UNPKG

edwin-sdk

Version:

SDK for integrating AI agents with DeFi protocols

139 lines (117 loc) 4.97 kB
import { VersionedTransaction } from '@solana/web3.js'; import { SupportedChain } from '../../core/types'; import { SupplyParameters, WithdrawParameters } from './parameters'; import { SolanaWalletClient, canSign } from '../../core/wallets/solana_wallet'; import edwinLogger from '../../utils/logger'; interface LuloDepositResponse { data: { transactionMeta: Array<{ transaction: string; }>; }; } interface LuloWithdrawResponse { signature: string; } export class LuloProtocol { public supportedChains: SupportedChain[] = ['solana']; private wallet: SolanaWalletClient; constructor(wallet: SolanaWalletClient) { this.wallet = wallet; } async getPortfolio(): Promise<string> { return ''; } async supply(params: SupplyParameters): Promise<string> { try { // Check if wallet has signing capability if (!canSign(this.wallet)) { throw new Error('Supply operation requires a wallet with signing capabilities'); } if (!process.env.FLEXLEND_API_KEY) { throw new Error('FLEXLEND_API_KEY is not set (For lulo.fi)'); } if (!params.amount) { throw new Error('Amount is required'); } const response = await fetch(`https://api.flexlend.fi/generate/account/deposit?priorityFee=50000`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-wallet-pubkey': this.wallet.publicKey.toBase58(), 'x-api-key': process.env.FLEXLEND_API_KEY!, }, body: JSON.stringify({ owner: this.wallet.publicKey.toBase58(), mintAddress: params.asset, // This should be the mint address of the asset depositAmount: params.amount.toString(), }), }); edwinLogger.info(response); const responseData = (await response.json()) as LuloDepositResponse; const transactionMeta = responseData.data.transactionMeta; // Deserialize the transaction const luloTxn = VersionedTransaction.deserialize(Buffer.from(transactionMeta[0].transaction, 'base64')); // Get a recent blockhash and set it const connection = this.wallet.getConnection(); const { blockhash } = await connection.getLatestBlockhash(); luloTxn.message.recentBlockhash = blockhash; // Sign and send transaction this.wallet.signTransaction(luloTxn); const signature = await connection.sendTransaction(luloTxn, { preflightCommitment: 'confirmed', maxRetries: 3, }); // Wait for confirmation using the latest strategy const latestBlockhash = await connection.getLatestBlockhash(); await connection.confirmTransaction({ signature, blockhash: latestBlockhash.blockhash, lastValidBlockHeight: latestBlockhash.lastValidBlockHeight, }); return ( 'Successfully supplied ' + params.amount + ' ' + params.asset + ' to Lulo.fi, transaction signature: ' + signature ); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; throw new Error(`Lulo supply failed: ${errorMessage}`); } } async withdraw(params: WithdrawParameters): Promise<string> { try { // Check if wallet has signing capability if (!canSign(this.wallet)) { throw new Error('Withdraw operation requires a wallet with signing capabilities'); } const response = await fetch( `https://blink.lulo.fi/actions/withdraw?amount=${params.amount}&symbol=${params.asset}`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ account: this.wallet.publicKey.toBase58(), }), } ); const data = (await response.json()) as LuloWithdrawResponse; return ( 'Successfully withdrew ' + params.amount + ' ' + params.asset + ' from Lulo.fi, transaction signature: ' + data.signature ); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; throw new Error(`Lulo withdraw failed: ${errorMessage}`); } } }