import type { Arguments, CommandBuilder } from "yargs"; import * as anchor from "@project-serum/anchor"; import fs from "fs"; import { ComputeBudgetProgram, Keypair, Transaction } from "@solana/web3.js"; import { Rain } from "@rainfi/rain"; import { handleErrorTx } from "../utils/utils"; export const command = "borrow"; export const desc = "Borrow"; type Options = { nftAddress: string poolOwner: string duration: number keypair: string simulate: string network: string } export const builder: CommandBuilder = (yargs) => { return yargs .options({ 'nft': { alias: 'nftAddress', describe: 'NFT Mint address to collateralize', demandOption: true }, 'owner': { alias: 'poolOwner', describe: 'Owner of the pool', demandOption: true }, 'duration': { describe: 'Duration of the loan', 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 { nftAddress, poolOwner, duration, 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] - Borrow"); const walletWrapper = new anchor.Wallet(wallet); const provider = new anchor.AnchorProvider(connection, walletWrapper, { preflightCommitment: "recent", }); const args = { nft_address: nftAddress, pool_owner: poolOwner, duration: duration, } const instruction = await rain.instructions.borrow(connection, wallet.publicKey, args) const additionalComputeBudgetInstruction = ComputeBudgetProgram.requestUnits({ units: 300000, additionalFee: 0, }); const tx = new Transaction().add(instruction.instruction).add(additionalComputeBudgetInstruction) 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, instruction.signers], "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) } } };