```
   _  __         __               ___           _          _   __          ____
  / |/ /_ ______/ /__ __ _____   / _ )___  ____(_)__  ___ | | / /__ ___ __/ / /_
 /    / // / __/ / -_) // (_-<  / _  / _ \/ __/ / _ \/ _ `/ |/ / _ `/ // / / __/
/_/|_/\_,_/\__/_/\__/\_,_/___/ /____/\___/_/ /_/_//_/\_, /|___/\_,_/\_,_/_/\__/
   ____              __              __  _______  __/___/
  / __/______  ___  / /____ ___  ___/ / / __/ _ \/ //_/
 / _// __/ _ \/ _ \/ __/ -_) _ \/ _  / _\ \/ // / ,<
/_/ /_/  \___/_//_/\__/\__/_//_/\_,_/ /___/____/_/|_|
```

A TypeScript SDK for interacting with Nucleus BoringVault Smart Contracts, providing helper functions for depositing and withdrawing assets across multiple chains.

## Installation

**npm**

```bash
npm install @molecularlabs/nucleus-frontend
```

**yarn**

```bash
yarn add @molecularlabs/nucleus-frontend
```

**pnpm**

```bash
pnpm add @molecularlabs/nucleus-frontend
```

## Requirements

- Node.js >= 16

**Recommended**

- Viem >= 2.0.0
- Wagmi >= 2.0.0

## Features

- Deposit assets into vaults across multiple chains
- Bridge assets between supported networks
- Withdraw assets from vaults
- Calculate rates and fees
- TypeScript support with full type definitions

## Usage

### Vault Configuration

```ts
import { getContract } from '@molecular-labs/nucleus';

const contract = getContract({
  address: '0x1234567890123456789012345678901234567890',
  abi: abi,
});
```

### Transaction Preparation

#### prepareDepositData

```ts
import { prepareDepositData, getVaultByKey } from '@molecular-labs/nucleus';

const VAULT_KEY = 'bobaeth';

// Prepare deposit transaction data
const depositData = await prepareDepositData({
  vaultKey: 'bobaeth',
  userAddress: '0x1234...',
  depositAsset: '0xC02a...', // WETH address
  depositAmount: BigInt('1000000000000000000'), // 1 WETH
  slippage: 0.01, // 1% slippage (optional)
});

const {
  to, // Contract address to send the transaction to
  data, // Encoded transaction data
  value, // Amount of native token to send (in wei)
  gasLimit, // Estimated gas limit
  depositQuote, // Quote information including rates and fees
} = depositData;
```

#### prepareMintAndBridge

```ts
import { prepareMintAndBridge } from '@molecular-labs/nucleus';

const VAULT_KEY = 'bobaeth';

// Prepare mint and bridge transaction data
const mintAndBridgeData = await prepareMintAndBridge(
  VAULT_KEY,
  '0xC02a...', // Deposit asset address
  BigInt('1000000000000000000'), // 1 WETH
  '0x1234...', // User address
  0.01 // 1% slippage (optional)
);

const {
  abi, // Contract ABI (TellerAbi)
  address, // Contract address to send the transaction to
  functionName, // 'depositAndBridge'
  args, // [depositAsset, depositAmount, minimumMint, bridgeData]
  chainId, // Chain ID for the transaction
  value, // Amount of native token to send (in wei)
} = mintAndBridgeData;
```

**Interfaces**

```ts
interface MintAndBridgeData {
  abi: typeof TellerAbi;
  address: Address;
  functionName: 'depositAndBridge';
  args: [Address, bigint, bigint, BridgeData];
  chainId: number;
  value: bigint;
}
```

#### prepareWithdrawData

```ts
import { prepareWithdrawData, TokenKey } from '@molecular-labs/nucleus';

const VAULT_KEY = 'bobaeth';

// Prepare withdraw transaction data
const withdrawData = await prepareWithdrawData({
  vaultKey: VAULT_KEY,
  chainId: 1, // Ethereum mainnet
  userAddress: '0x1234...',
  wantAsset: TokenKey.WETH,
  redeemAmount: BigInt('1000000000000000000'), // 1 token
  deadline: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now (optional)
  slippage: 0.01, // 1% slippage (optional)
});

const {
  abi, // AtomicQueueAbi
  address, // Contract address for the atomic queue
  functionName, // 'updateAtomicRequest'
  args, // [redeemTokenAddress, wantAssetAddress, userRequest]
  chainId, // Chain ID for the transaction
} = withdrawData;
```

**Interfaces**

```ts
interface PrepareWithdrawParams {
  vaultKey: VaultKey;
  chainId: ChainId;
  userAddress: Address;
  wantAsset: TokenKey;
  redeemAmount: bigint;
  deadline?: number;
  slippage?: number;
}

interface PrepareWithdrawResult {
  abi: typeof AtomicQueueAbi;
  address: Address;
  functionName: 'updateAtomicRequest';
  args: [offer: Address, want: Address, userRequest: UserRequest];
  chainId: number;
}
```

#### prepareWithdrawAndBridge

```ts
import { prepareWithdrawAndBridge, TokenKey } from '@molecular-labs/nucleus';

const VAULT_KEY = 'bobaeth';

// Prepare withdraw and bridge transaction data
const withdrawAndBridgeData = await prepareWithdrawAndBridge({
  vaultKey: VAULT_KEY,
  sourceChainId: 288, // Boba network
  destinationChainId: 1, // Ethereum mainnet
  userAddress: '0x1234...',
  wantAsset: TokenKey.WETH,
  redeemAmount: BigInt('1000000000000000000'), // 1 token
  previewFee: BigInt('100000000000000'), // Bridge fee (get this from getPreviewFee)
  deadline: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now (optional)
  slippage: 0.01, // 1% slippage (optional)
});

const {
  bridgeData, // Bridge configuration data
  withdrawRequestData, // Withdraw request details
} = withdrawAndBridgeData;

// Further destructure the withdraw request data
const {
  abi, // AtomicQueueAbi
  address, // Contract address for the atomic queue
  functionName, // 'updateAtomicRequest'
  args, // [redeemTokenAddress, wantAssetAddress, userRequest]
  chainId, // Chain ID for the transaction
} = withdrawRequestData;
```

**Interfaces**

```ts
interface PrepareWithdrawAndBridgeParams {
  vaultKey: VaultKey;
  sourceChainId: ChainId;
  destinationChainId: ChainId;
  userAddress: Address;
  wantAsset: TokenKey;
  redeemAmount: bigint;
  previewFee: bigint;
  deadline?: number;
  slippage?: number;
}

interface PrepareWithdrawAndBridgeResult {
  bridgeData: BridgeData;
  withdrawRequestData: PrepareWithdrawResult;
}
```
