import type { Arguments, CommandBuilder } from "yargs"; import * as anchor from "@project-serum/anchor"; import fs from "fs"; import { Keypair, PublicKey, Transaction } from "@solana/web3.js"; import { Rain } from "@rainfi/rain"; import { handleErrorTx } from "../utils/utils"; export const command = "liquidate_loan"; export const desc = "Liquidate a loan"; type Options = { loanAddress: string keypair:string simulate: string network: string } export const builder: CommandBuilder = (yargs) => { return yargs .options({ 'loan_address': { alias: 'loanAddress', describe: 'Loan address to liquidate. Use the command "get_loans_from_lender" and select a loan you want to liquidate.', demandOption: true }, 'k': { alias: 'keypair', describe: 'Keypair used to send/sign the transaction', demandOption: true, default: `${process.env.HOME}/.config/solana/id.json` }, 'simulate': { describe: 'Simulate the transaction instead of submit to network', default: "false", demandOption: false }, 'n': { alias: 'network', describe: 'Network to use', default: 'https://api.mainnet-beta.solana.com', demandOption: false } }) }; export const handler = async (argv: Arguments): Promise => { const { loanAddress, keypair, simulate, network } = argv; const isSimulate = simulate === 'true' const connection = new anchor.web3.Connection(network); const mainWalletParsed: number[] = JSON.parse( fs.readFileSync(keypair, "utf8") ); const wallet = Keypair.fromSecretKey(new Uint8Array(mainWalletParsed)); const rain = new Rain() console.log("[i] - Using RPC:", network); console.log("[i] - Using keypair:", wallet.publicKey.toBase58()); console.log("[i] - Using program:", rain.PUBKEY.toBase58()); console.log("[i] - Liquidate loan"); const walletWrapper = new anchor.Wallet(wallet); const provider = new anchor.AnchorProvider(connection, walletWrapper, { preflightCommitment: "recent", }); const loanToLiquidate = await connection.getAccountInfo(new PublicKey(loanAddress)) if(!loanToLiquidate) { console.log("This loan doesn't exist"); return; } const instruction = await rain.instructions.liquidateLoan(connection, wallet.publicKey, new PublicKey(loanAddress)) const tx = new Transaction().add(instruction) tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash tx.feePayer = wallet.publicKey //console.log(tx.serializeMessage().toString("base64")); if (isSimulate) { const simulation = await provider.simulate(tx, [wallet], "processed") console.log("Encoded Transaction Message:", tx.serializeMessage().toString("base64")); console.log("[i] - Simulation:", simulation); } else { try { const signature = await provider.sendAndConfirm(tx, [wallet]) console.log("[i] - Signature:", signature); } catch(e: any) { const errorMessage = handleErrorTx(e) throw new Error(errorMessage || e) } } };