# Zebec Plutus Contract SDK

SDK for interacting with zebec bnb contracts

## Installation

```bash
yarn add @zebec-protocol/plutus-sdk

// or

npm install @zebec-protocol/plutus-sdk
```

## Files and Folders

| Files and folders | Descriptions                                                      |
| ----------------- | ----------------------------------------------------------------- |
| Borrower          | Contains Borrower client and definitions                          |
| CreditDesk        | Contains CreditDesk client and definitions                        |
| PlutusConfig      | Contains PlutusConfig client and definitions                      |
| Pool              | Contains Pool client and definitions                              |
| Contracts         | Contains typechain generated files and are used to create clients |
| ZebecConsensus    | Contains ZebecConsensus Client and definitions                    |
| Utils             | Contains utility functions for logging, approving tokens, etc     |
| Contansts         | Contains constants such as contract address                       |

## Development

To run the project

```bash
yarn start
```

To build the project

```bash
yarn build
```

To remove dist folder

```bash
yarn clean
```

To run test scripts:

```bash
yarn test:single <path to test script>

# example for windows: yarn test:single tests\pool.spec.ts
# example for linux: yarn test:single tests/pool.spec.ts
```

To compile generate typechain files from abis

```bash
yarn build:typechain
```

## Usage

### Create Pool Client

Pool client can be created in following way.

```ts
const lender = <signer>;
const client = new PoolClient(lender);
```

### Deposit usdc to pool

To deposit usdc in pool, do as given below.

```ts
const depositReceipt = await client.deposit(amount);
```

After depositing usdc corresponding amount of PLP token is received by lender. You can see your PLP balance.

```ts
const owner = <signer>;
const plpToken = Token__factory.connect(PLP_ADDRESS, owner);
const lenderPlp = await plpToken.balanceOf(lender.address);
```

### Withdraw USDC from pool

Withdraw USDC from pool burns the PLP tokens that the lender have.

```ts
const amount = "100";
const withdrawTxn = await client.withdraw(amount, USDC_ADDRESS);
```

### Create CreditDesk Client

```ts
const signer = <signer>;
const creditDeskClient = new CreditDeskClient(signer);
```

### Create zebec consensus client

```ts
const admin = <signer>;
const zebecConsensusClient = new ZebecConsesusClient(admin, ZEBEC_CONSENSUS_ADDRESS)
```

### Tokenize assets

After tokenization, certain amount of asset token is minted to borrower as specified in loan limit.

```ts
const name = "Test Token";
const symbol = "TKN";
const borrower = "<address>";
const loanLimit = BigInt("10000");
const interestApr = 15; // percent
const paymentPeriodInDays = "30";
const termInDays = "90";
const lateFeeApr = "10"; // percent

const receipt = zebecConsensusClient.tokenization(
	name,
	symbol,
	borrower,
	loanLimit,
	interestApr,
	paymentPeriodInDays,
	termInDays,
	lateFeeApr,
);
```

### Detokenize assets

```ts
const assetTokenAddress = "<address>";
const creditLineAddress = "<address>";
const receipt = zebecConsensusClient.deTokenization(assetTokenAddress, creditLineAddress);
```

### Get creditline of underwriter

Here the underwriter is ZebecConsensus Contract.

```ts
const creditLines = creditDeskClient.getUnderwriterCreditLines(ZEBEC_CONSENSUS_ADDRESS);
```

### Get creditline of borrower

```ts
const borrowerAddress = "<address>";
const creditline = creditDeskClient.getBorrowerCreditLines(borrowerAddress);
```

### Get overall APR

```ts
const apr = creditDeskClient.getOverallApr(ZEBEC_CONSENSUS_ADDRESS);
```

### Get supply balance and interest

```ts
const lenderAddress = "<address>";
const { supplyAmountLended, claimableInterest } =
	creditDeskClient.getSupplyBalanceAndInterest(lenderAddress);
```

### Get pool usage

```ts
const usage = creditDeskClient.getPoolUsage(ZEBEC_CONSENSUS_ADDRESS);
```

### Create Borrower Client

```ts
const owner = <signer>;
const borrowerClient = new BorrowerClient(owner, BORROWER_ADDRESS, CREDIT_DESK_ADDRESS);
```

### Get loan

For getting loan, creditline must be approved and created by admin.

```ts
const creditLineAddress = "<address>";
const assetTokenAddress = "<address>";
const amount = "10000";
const receipt = borrowerClient.getLoan(creditLineAddress, amount, assetTokenAddress);
```

### Get next payment amount

```ts
const creditLineAddress = "<address>";
const paymentAmount = borrowerClient.getNextPaymentAmount(creditLineAddress);
```

### Repay loan

```ts
const amount = "100";
const creditLineAddress = "<address>";
const receipt = borrowerClient.repayLoan(creditLineAddress, amount);
```

### Repay loan in full

```ts
const creditLineAddress = "<address>";
const receipt = borrowerClient.repayLoanInFull(creditLineAddress);
```
