npm package: @perena/bankineco-sdk
Description: SDK for interacting with Bankineco program on Solana.
Author: Perena
Latest version: 1.0.153

# @perena/bankineco-sdk

SDK for interacting with the Bankineco program on Solana.

## Installation

```bash
npm install @perena/bankineco-sdk
```

## Example Usage

### Initialize the Client

```typescript
import { UsdStarClient, USDC_MINT, USDC_DECIMALS, USD_STAR_DECIMALS, fromUiAmount, BankinecoAction } from "@perena/bankineco-sdk";
import { Wallet } from "@coral-xyz/anchor";
import { PublicKey } from "@solana/web3.js";

const rpcUrl: string = ...; // TODO
const anchorWallet: Wallet = ...; // TODO

const client = UsdStarClient.new({
  env: "prod",
  rpcUrl,
  wallet: anchorWallet,
});
```

### Minting USD\*

```typescript
// Mint USD* with 1 USDC
const { transaction, lookupTables } = await client.mintFromYieldingTx({
  yieldingAmount: fromUiAmount(1, USDC_DECIMALS),
  fromYieldingMint: USDC_MINT,
  user: anchorWallet.publicKey,
});

// OR, If performing a CPI, pull accounts quicker:
const cpiAccounts = await client.getMintAndBurnCpiAccounts(USDC_MINT, BankinecoAction.Mint, anchorWallet.publicKey);
```

### Burning USD\*

```typescript
// Burn 1 USD* for USDC
const { transaction, lookupTables } = await client.burnForYieldingTx({
  banKMintAmount: fromUiAmount(1, USD_STAR_DECIMALS),
  toYieldingMint: USDC_MINT,
  user: anchorWallet.publicKey,
});

// OR, If performing a CPI, pull accounts quicker:
const cpiAccounts = await client.getMintAndBurnCpiAccounts(USDC_MINT, BankinecoAction.Burn, anchorWallet.publicKey);
```

### Get USD\* Price

```typescript
const usdStarPrice = await client.latestBankMintUiPrice();
```

### Get Junior Mint Price

```typescript
const juniorMintPrice = await client.latestJuniorMintUiPrice();
```

### Get USD\* Price

```typescript
import { getLatestUsdStarUiPrice } from "@perena/bankineco-sdk";

const usdStarPrice = await getLatestUsdStarUiPrice(rpcUrl, "prod");
```

### Get Quote

```typescript
const vault = client.getVault(USDC_MINT);

// Calculate the amount of USD* you will get from the USDC provided
const { amount: usdStarOutput, details: mintDetails } =
  await client.yieldingToBankMintQuote(fromUiAmount(1, USDC_DECIMALS), vault);

// Calculate the amount of USDC you will receive from the USD* amount provided
const { amount: usdcOutput, details: burnDetails } =
  await client.bankMintToYieldingQuote(
    fromUiAmount(1, USD_STAR_DECIMALS),
    vault,
  );
```

**Junior unstake fee quote (`fetchUnstakeFee`):** pass the number of **junior shares** as `amount` (same raw units as `requestUnstakeJuniorTx` / `instantUnstakeJuniorTx`). Use `early: true` when the user will pay the early fee (instant unstake, or fulfilling a queue before lockup expires); use `early: false` for a standard queued unstake after lockup.

- **Junior → USD\* (bank mint / senior):** do not set `targetMint`. `feeAmount`, `amountAfterFee`, and `burningFeeAmount` are denominated in **USD\*** (bank mint) raw units; `burningFeeBps` stays zero because there is no vault burn on that path.

- **Junior → yielding mint (e.g. USDC):** set `targetMint` to the yielding mint for an **idle vault the client supports** (the same mint you would pass to `requestUnstakeJuniorTx`). The SDK values the redemption in that mint and includes the vault **burn** fee, so `feeAmount` and `amountAfterFee` are in **that mint’s** raw units. Check `burningFeeBps` / `burningFeeAmount` for the burn portion.

```typescript
// Junior → USD* — standard vs early unstake fee only (amounts in USD* raw units)
const juniorToUsdStar = await client.fetchUnstakeFee({
  amount: fromUiAmount(5, USD_STAR_DECIMALS),
  early: false,
});

const juniorToUsdStarEarly = await client.fetchUnstakeFee({
  amount: fromUiAmount(5, USD_STAR_DECIMALS),
  early: true,
});

// Junior → USDC — unstake fee + burn fee (amounts in USDC raw units)
const juniorToUsdc = await client.fetchUnstakeFee({
  amount: fromUiAmount(5, USD_STAR_DECIMALS),
  early: false,
  targetMint: USDC_MINT,
});

const juniorToUsdcEarly = await client.fetchUnstakeFee({
  amount: fromUiAmount(5, USD_STAR_DECIMALS),
  early: true,
  targetMint: USDC_MINT,
});
```

### Staking (Junior Tranche)

Stake USD\* into the junior tranche to earn leveraged yield. Staked tokens are represented by junior share tokens.

```typescript
// Stake 10 USD* into the junior tranche
const { transaction, lookupTables, juniorMint } = await client.stakeJuniorTx({
  amount: fromUiAmount(10, USD_STAR_DECIMALS),
  user: anchorWallet.publicKey,
});

// If performing a CPI, pull tranche accounts:
const stakeCpiAccounts = await client.getStakeCpiAccounts(anchorWallet.publicKey);
```

### Unstaking (Junior Tranche)

Unstaking is a two-step process: first **request** the unstake (which locks your shares in a withdrawal queue), then **fulfill** it once the lockup period expires. An admin crank automatically fulfills expired queues, so in most cases you only need to submit the request and wait.

Fulfilling immediately is possible but incurs a higher early unstake fee. Waiting for the lockup to expire means a lower standard fee is applied instead.

```typescript
// Request unstake — locks shares in a withdrawal queue
const { transaction, lookupTables, withdrawalQueue } = await client.requestUnstakeJuniorTx({
  shares: fromUiAmount(5, USD_STAR_DECIMALS),
  queueId: 0, // unique per-user queue identifier
  user: anchorWallet.publicKey,
});
```

To receive a yielding token (e.g. USDC) directly instead of USD\*, pass `targetMint`:

```typescript
const { transaction, lookupTables } = await client.requestUnstakeJuniorTx({
  shares: fromUiAmount(5, USD_STAR_DECIMALS),
  queueId: 0,
  targetMint: USDC_MINT,
});
```

If performing a CPI, pull tranche accounts for unstaking. Pass a yielding mint to include yielding redemption accounts, or omit it to unstake to USD\* only:

```typescript
// Unstake to USD*
const unstakeCpiAccounts = await client.getUnstakeCpiAccounts(anchorWallet.publicKey);

// Unstake to USDC (includes yielding redemption accounts)
const unstakeToUsdcCpiAccounts = await client.getUnstakeCpiAccounts(anchorWallet.publicKey, USDC_MINT);
```

If you need to fulfill immediately (paying the early unstake fee), you can compose both steps into a single transaction:

```typescript
import { Transaction } from "@solana/web3.js";

const { transaction: requestTx, lookupTables } = await client.requestUnstakeJuniorTx({
  shares: fromUiAmount(5, USD_STAR_DECIMALS),
  queueId: 0,
  user: anchorWallet.publicKey,
});

const { transaction: fulfillTx } = await client.fulfillUnstakeJuniorTx({
  owner: anchorWallet.publicKey,
  queueId: 0,
});

const transaction = new Transaction().add(requestTx, fulfillTx);
```

### Instant unstake (Junior) — `instantUnstakeJuniorTx`

To exit the junior tranche in **one transaction** without using the withdrawal queue, use `instantUnstakeJuniorTx`. The program always applies the **early unstake fee** (same idea as fulfilling a queued request before lockup expires). Use `fetchUnstakeFee` with `early: true` if you want a fee quote first.

```typescript
const { transaction, lookupTables } = await client.instantUnstakeJuniorTx({
  shares: fromUiAmount(5, USD_STAR_DECIMALS),
  user: anchorWallet.publicKey,
});
```

To receive a yielding asset (e.g. USDC) instead of USD\*, set `targetMint`. For vaults that need extra accounts on redeem (for example marginfi), pass `remainingAccounts` as you would for `requestUnstakeJuniorTx`.

```typescript
const { transaction, lookupTables } = await client.instantUnstakeJuniorTx({
  shares: fromUiAmount(5, USD_STAR_DECIMALS),
  targetMint: USDC_MINT,
  user: anchorWallet.publicKey,
});
```

The returned `transaction` should be signed and sent like other client helpers; attach `lookupTables` when building/sending the versioned transaction if your stack requires it.

### Reading Withdrawal Queues

After requesting an unstake, you can fetch all withdrawal queue entries for a given owner to check amounts awaiting unstake and how much time remains until each lockup expires.

```typescript
const queues = await client.fetchAllWithdrawalQueues(anchorWallet.publicKey);

for (const queue of queues) {
  queue.queueId;          // the queue identifier
  queue.address;          // on-chain address of this queue entry
  queue.amount;           // junior shares locked in this queue entry
  queue.targetMint;       // the mint the user receives upon fulfillment (e.g. USD* or USDC)
  queue.requestTs;        // when the unstake was requested
  queue.expiryTs;         // when the lockup expires
  queue.secondsRemaining; // seconds until the admin crank can fulfill (0 if expired)
  queue.isExpired;        // true if the lockup period has passed
}
```

### Get Unstake Fee

Fetch the fee that would be applied for a given unstake amount. Set `early: true` for an immediate unstake (higher fee) or `early: false` for a standard unstake after the lockup expires.

```typescript
// Early unstake fee (fulfilling before lockup expires)
const { feeBps, feeAmount, amountAfterFee } = await client.fetchUnstakeFee({
  amount: fromUiAmount(5, USD_STAR_DECIMALS),
  early: true,
});

// Standard unstake fee (after lockup expires)
const standard = await client.fetchUnstakeFee({
  amount: fromUiAmount(5, USD_STAR_DECIMALS),
  early: false,
});
```

### Use Insured USD\*

```typescript
import { InsuredUsdStarClient } from "@perena/bankineco-sdk";

const client = InsuredUsdStarClient.new({
  env: "prod",
  rpcUrl,
  wallet: anchorWallet,
});
```