npm package: @pyron-finance/pyron-client
Description: This is the Typescript SDK for interacting with the Pyron Lending program.
Latest version: 2.10.0

# Pyron Client

This is the Typescript SDK for interacting with the Pyron Lending program.

## Installation

```bash
# npm
npm install @pyron-finance/client

# pnpm
pnpm install @pyron-finance/client

# yarn
yarn add @pyron-finance/client
```

## Getting Started

### Initialize the lendr client

> This example uses @solana/web3.js version 1.93.2

In order to interact with the Pyron SDK, we must first configure the lendr client object using the `LendrClient` instance:

```javascript
import { Connection } from "@solana/web3.js";
import { LendrClient, getConfig } from 'lendr-client';
import { NodeWallet } from "./src/common";

const connection = new Connection(CLUSTER_CONNECTION, "confirmed");
const keypair = Keypair.fromSecretKey(bs58.decode(KEYPAIR));
const wallet = new NodeWallet(keypair);
const config = getConfig();
const client = await LendrClient.fetch({ config, wallet, connection });
```

- `connection` establishes a connection to a Solana cluster
- `keypair` creates a keypair from a base58 encoded string
- `wallet` creates an Anchor-compliant Node.js wallet from your [local Solana keypair](https://docs.solanalabs.com/cli/wallets/)
- `config` returns a configuration object specific to the environment
- `client` is a high-level SDK for interacting with the Lending protocol

### Create an Account

Accounts on Pyron are the entry point for interacting with the protocol, allowing users to deposit assets, take out loans, and manage their positions. Using this SDK, you can create an account with one line of code. With this ability, you can enable seamless user onboarding by creating dedicated accounts for each new user. 

```javascript
const lendrAccount = await client.createLendrAccount();
```

- `lendrAccount` creates a new Lendr Account. Note that you can also create an account with Fogo Session (using `client.createLendrAccountWithSession`)

You can also fetch an existing account:
```javascript
const lendrAccount = await LendrAccountWrapper.fetch(ACCOUNT_ADDRESS, client);
```

### Listing all accounts under an authority

To see all accounts for an authority you can use the following code:
```javascript
const accounts = await client.getLendrAccountsForAuthority(WALLET_PUBLIC_KEY);
```

- `accounts` will contain an array of all lendr accounts owned by that authority. the address can be an instance of `PublicKey` or a base58 encoded string.

### Fetch a Bank

To interact with asset pools, or “banks,” on Pyron, you must first fetch the specific bank you want to borrow from or lend to:

```javascript
const bankSymbol = "FOGO";
const bank = client.getBankByTokenSymbol(bankSymbol);
if (!bank) throw Error(`${bankSymbol} bank not found`);
```

- `bankSymbol` holds the symbol for the bank that you will fetch. Note that you can also query banks by the token mint address (using `getBankByMint`) or by the bank address (using `getBankByPk`).
- `bank` fetches the specified bank using `getBankByTokenSymbol`, using the bank’s token symbol (`FOGO`) as the query parameter.

### Perform lending action

Once you’ve fetched the bank you want to interact with, you can make a deposit:

```javascript
await lendrAccount.deposit(1, bank.address);
```

The `deposit` method on the lendr account object allows you to deposit the specified amount of the denominated asset (first parameter) into the specified bank (second parameter). You can also perform lending actions with Fogo Sessions (using
`lendrAccount.depositWithSession(1, bank.address, SESSION)`).

### Borrow From a Bank

> Note: You can't borrow from the same bank where you already have a lending position, and vice versa.

After lending liquidity on Pyron, your account is now eligible to act as a borrower. You can borrow liquidity from Pyron banks using one line of code:

```javascript
await lendrAccount.borrow(1, bank.address);
```

The structure of the `borrow` method is identical to the `deposit` method, This structure is kept in all actions. You specify the amount you want to borrow using the first parameter, and you specify which bank you want to interact with using the second parameter. Note that you can also borrow with Fogo Sessions (using
`lendrAccount.borrowWithSession(1, bank.address, SESSION)`).

### Perform repay action

After you borrowed from a bank you can repay your loan with one line of code:
```javascript
await lendrAccount.repay(1, bank.address);
```

As you can see the structure of the `repay` also follows other actions. You specify the amount you want to repay using the first parameter, and you specify, which bank you borrowed from in the second parameter. Note you can also repay with Fogo Sessions (using
`lendrAccount.repayWithSession(1, bank.address, SESSION)`).

The `repay` function also takes a optional third parameter (`repayAll`) for when you want to repay the entire loan:
```javascript
await lendrAccount.repay(1, bank.address, true);
```

### Withdrawing from a Bank

To withdraw your balance from a bank you can use the following code:

```javascript
await lendrAccount.withdraw(1, bank.address);
```

The structure of the `withdraw` as same as `repay`. Specify the amount you want to withdraw using the first parameter, and specify Bank which you have an active lending position in using the second parameter. To withdraw your entire balance, provide `true` for the third optional parameter. You can also withdraw with Fogo Sessions (using
`lendrAccount.withdrawWithSession(1, bank.address, SESSION)`).

### Listing active positions

To see active positions for an account, their loans and balances, you can use the following example:

```javascript
// Refresh account data
await lendrAccount.reload();

for (const position of lendrAccount.activeBalances) {
	console.log(`Bank: ${position.bankPk.toBase58()}`)
	console.log(`Deposits: ${position.assetShares}`)
	console.log(`Borrows: ${position.liabilityShares}`)
}
```

You can also get a formatted string describing the account:

```javascript
console.log(lendrAccount.describe())
```

`describe` returns a string containing account's info such as authority, health, and active positions.

## Overriding Config

You can override LendrClient's config either by passing an optional overrides object to `getConfig()`:

```ts
import {PublicKey} from "@solana/web3.js";

const config = getConfig({
	overrides: {
		groupPk: new PublicKey("..."),
	},
});
const client = await LendrClient.fetch({ config, wallet: {} as Wallet, connection });
```

Or using these environment variables:
- LENDR_GROUP_PK
- LENDR_PROGRAM_ID
- LENDR_CLUSTER_OVERRIDE

## Configs

### Testnet

- Program Address: `89ZQeCPwkzSPJyTpktCKWNY6hBWMKuYt47R85Jo36yyh`
- Group Address: `4vDRNkXaeAcwJULZCQFFdNBM295sD8hSKQt3RaMwsRFc`

## Troubleshooting

### Cannot find module '@pyron-finance/pyron-client/common'

Update your `tsconfig.json` to use a newer module resolution strategy:
```json5
{
  "compilerOptions": {
    "moduleResolution": "node16" // `nodenext` or `bundler` also work
  }
}
```

Older module resolution modes (`node` or `node10`) doesn't support exports maps defined in modern package.json files. Switching to a newer module resolution tells TypeScript to follow Node.js’s newer ESM resolution rules, allowing it to find the entrypoint correctly.