npm package: @rainfi/sdk
Description: This package is used to interact with Rain.fi protocol on Solana
Author: solwhitey
Latest version: 1.3.44


<div align="center">

  <img src="https://i.ibb.co/fCpnvzQ/rain-simple-logo.png" />

  <h1>Rain.fi</h1>

  <p>
    <strong>Leveraging the liquidity of NFTs like never before.</strong>
  </p>

  <p>
    <a target="_blank" href="https://docs.rain.fi"><img alt="Tutorials" src="https://img.shields.io/badge/docs-tutorials-yellow" /></a>
    <a target="_blank" href="https://discord.com/invite/usrMBX5adn"><img alt="Discord" src="https://img.shields.io/badge/chat-discord-blueviolet" /></a>
    <a target="_blank" href="https://twitter.com/rainfi_"><img alt="Twitter" src="https://img.shields.io/badge/follow-twitter-blue" /></a>
  </p>
</div>

- This code is given as is and is unaudited. Use at your own risk.
- The examples might not be always up to date since the package is in active development.

# Table of contents:

- [Installation](#installation)
  - [Usage](#usage)
- [Examples](#examples)
  - [Pool Class](#pool-class) 
  - [Rain Class](#rain-class) 
- [License](#license)
- [TODO](#todo)

## Installation

Yarn:
```bash
yarn add @rainfi/sdk
```

NPM:
```bash
npm i @rainfi/sdk
```

### Usage

```ts
import { Pool, Rain } from "@rainfi/sdk";
import { Connection, LAMPORTS_PER_SOL, Keypair, PublicKey } from "@solana/web3.js";

const connection = new Connection("https://api.mainnet-beta.solana.com", "confirmed");
const publicKey = new Keypair().publicKey // Your pubkey
const poolOwner = new PublicKey("OWNER_OF_POOL_PUBKEY")

// Let you interact with a specific pool only
const pool = new Pool(connection, poolOwner, publicKey)

// Let you interact with the whole protocol
const rain = new Rain(connection, publicKey)


```

# Examples

## Pool Class

Let you interact with a specific pool only. Useful when you want to intergarte it on your website.

```ts
import { Pool } from "@rainfi/sdk";
import { Connection, LAMPORTS_PER_SOL, Keypair, PublicKey } from "@solana/web3.js";

const connection = new Connection("https://api.mainnet-beta.solana.com", "confirmed");
const publicKey = new Keypair().publicKey // Your pubkey
const poolOwner = new PublicKey(OWNER_OF_POOL)

const pool = new Pool(connection, poolOwner, publicKey)

// To fetch/refresh data of the pool
const poolData = await pool.fetch()

// To fetch all loans/mortgages from the pool, including ongoing, liquidated and repaid ones
const allLoans = await pool.loans('all')
const mortgagesOpen = await pool.mortgages('all')

// To get all ongoing loans from pool
const loansOpen = await pool.loans('ongoing')
const mortgagesOpen = await pool.mortgages('ongoing')

// To get all loan history from pool
const loansHistory = await pool.loans('history')

// You can also pass the borrower pubkey to get the loans related to your pool from a specific address
const allLoans = await pool.loans('all', publicKey)
const loansOpen = await pool.mortgages('all', publicKey)

// To get whitelisted collections from the pool
const poolCollections = await pool.collections()

// Here, we just take the first collections in the pool as example
const collection = poolCollections[0]

//Create the borrow instruction
const borrowIxs = await pool.borrow(
  new PublicKey("Eb89RFb5MZh4QWaae7m3pMQf5S1eNwUvoaYcpiDGdBfE"),   // NFT mint address string that you want to collateralize
  3,                                                               // The duration of the loan in DAYS
  20 * LAMPORTS_PER_SOL,                                           // Amount you want to borrow, must be lower than collection.maxAmountToBorrow
  collection.floorPrice                                            // FloorPrice of the collection, used to avoid front run
)

//Create the repay instruction

const loanAddress = loansOpen[0].accountAddress // address of the account holding data for the loan

const repayIx = await pool.repay(loanAddress)

// Create buy instruction, current supported marketplace: Solanart, Hadeswap, and auction house

const buyIxs = await pool.buy({
  nftMint: PublicKey,                                       // NFT mint pubkey
  seller?: nftSellerPubkey,                                 // NFT seller pubkey
  auctionHousePubkey?: auctionHousePubkey,                  // AH address
  escrowAddress?: escrowAddress,                            // escrow address holding the NFT
  marketplace: 'solanart' | 'auction_house' | 'hadeswap',   // marketplace where NFT is listed
  floorPrice: collection.floorPrice,                        // collection floor price in LAMPORTS
  price: 120 * LAMPORTS_PER_SOL,                            // NFT price in LAMPORTS
  amount: (120 * LAMPORTS_PER_SOL) * 0.50,                  // amount paid by the borrower, should 50% of the price of the NFT in LAMPORTS
  duration: number                                          // The duration of the mortgage in DAYS
})

const repayMortgageIxs = await pool.repayMortgage(
  mortgageAddress,                                       // mortgage account address
  amount,                                                // Amount to repay in LAMPORTS
)

// send your instructions
```

## Rain Class

Let you interact with the whole protocol and its features/functions with any pool.

### Create a pool

```ts

import { Rain } from "@rainfi/sdk";
import { Connection, LAMPORTS_PER_SOL } from "@solana/web3.js";

const connection = new Connection("https://api.mainnet-beta.solana.com", "confirmed");
const publicKey = new Keypair().publicKey // Your pubkey
const rain = new Rain(connection, publicKey)

const instruction = await rain.createPool(
  {
    loanToValue: 50,                                              // 50% of the floor price of the NFT
    maxAmount: 100,                                               // Max amount that can be used per loan in SOL, should default to size of the pool
    interestType: 1,                                              // Enable dynamic interest or not
    interestRate: (!dynamicInterest && loanInterest * 100) || 0,  // If dynamicInterest is used, we set the interest rate, else we set to 0 since program will overwrite
    interestCurve: 25,                                            // Interest curve depending on your parameter see docs
    interestGap: 19,                                              // Interest curve depending on your parameter see docs
    maxDuration: 14,                                              // In days
    compound: true,                                               // Compound interest or not, put the profit back in the pool or not
    amount: 100,                                                  // pool size = 100 SOL
    collections: [
      {
        collection: 301,    // This is the rain ID of the collection
        collectionLtv: 5000 // This is the loan to value of your collection, 5000 means 50%
      },
      {
        collection: 793,    // This is the rain ID of the collection
        collectionLtv: 7000 // This is the loan to value of your collection, 7000 means 70%
      },
      {
        collection: 292,    // This is the rain ID of the collection
        collectionLtv: 6000 // This is the loan to value of your collection, 6000 means 60%
      }
    ]// Ids of the collections that you want to authorize lending on. They can be obtained using getAvailableCollections()
  }
)

// wrap and send your instructions
```

### Borrow

```ts
import { Rain } from "@rainfi/sdk";
import { Connection, LAMPORTS_PER_SOL, Keypair, PublicKey } from "@solana/web3.js";

const connection = new Connection("https://api.mainnet-beta.solana.com", "confirmed");
const publicKey = new Keypair().publicKey // Your pubkey
const rain = new Rain(connection, publicKey)

// Get all pools available
const poolAvailable = await rain.utils.getAllPoolAvailable(connection)

// Select the pool
const pool = poolAvailable[0]

// To get all collections and their data, use that function.
const allCollections = await rain.utils.getAvailableCollections(connection)

// Here, we just want the data of Degenerate Ape Academy collection
const collection = await rain.utils.getCollection(connection, 292) // 292 is the ID of the DAA collection on rain

const duration = 3 // The duration of the loan in DAYS

//Create a borrow instruction
const borrowIxs = await rain.borrow({
  nftMint: new PublicKey("Eb89RFb5MZh4QWaae7m3pMQf5S1eNwUvoaYcpiDGdBfE"),   // NFT mint address string that you want to collateralize
  poolOwner: pool.owner,                                                    // The owner of the pool
  duration: duration,                                                       // The duration of the loan in DAYS
  amount: 20 * LAMPORTS_PER_SOL,                                            // Amount you want to borrow, must be lower than loanToValue
  floorPrice: collection.floorPrice                                         // FloorPrice of the collection, used to avoid front run
})

// wrap and send your instructions
```


## License

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion by you shall be licensed at the discretion of the repository maintainers without any additional terms or conditions.

## TODO

- Add examples and docs for mortgages, functions are already in the package itself though
- Add more examples about use cases
- actually do the TODO