@molecularlabs/nucleus-frontend
Version: 
Nucleus BoringVault Frontend SDK
506 lines (402 loc) • 12.1 kB
Markdown
```
   _  __         __               ___           _          _   __          ____
  / |/ /_ ______/ /__ __ _____   / _ )___  ____(_)__  ___ | | / /__ ___ __/ / /_
 /    / // / __/ / -_) // (_-<  / _  / _ \/ __/ / _ \/ _ `/ |/ / _ `/ // / / __/
/_/|_/\_,_/\__/_/\__/\_,_/___/ /____/\___/_/ /_/_//_/\_, /|___/\_,_/\_,_/_/\__/
   ____              __              __  _______  __/___/
  / __/______  ___  / /____ ___  ___/ / / __/ _ \/ //_/
 / _// __/ _ \/ _ \/ __/ -_) _ \/ _  / _\ \/ // / ,<
/_/ /_/  \___/_//_/\__/\__/_//_/\_,_/ /___/____/_/|_|
```
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 Dependencies**
- 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
### Setup with Wagmi 2.x
```tsx
import { createConfig, http } from 'wagmi'
import { mainnet, boba } from 'wagmi/chains'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { WagmiProvider } from 'wagmi'
const config = createConfig({
  chains: [mainnet, boba],
  transports: {
    [mainnet.id]: http(),
    [boba.id]: http(),
  },
})
const queryClient = new QueryClient()
function App() {
  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <YourApp />
      </QueryClientProvider>
    </WagmiProvider>
  )
}
```
### Basic Usage Example
```tsx
import { useAccount, useWriteContract, useWaitForTransactionReceipt } from 'wagmi'
import { 
  prepareDepositTransactionData, 
  prepareApproveDepositToken,
  VaultKeys 
} from '@molecularlabs/nucleus-frontend'
function DepositComponent() {
  const { address } = useAccount()
  const { writeContract, data: hash } = useWriteContract()
  const { isLoading, isSuccess } = useWaitForTransactionReceipt({ hash })
  const handleDeposit = async () => {
    if (!address) return
    try {
      // 1. First, prepare approval transaction
      const approvalData = await prepareApproveDepositToken({
        vaultKey: 'bobaeth',
        depositTokenSymbol: 'WETH',
        depositAmount: '1.0',
        chainId: 1, // Ethereum mainnet
      })
      // 2. Execute approval
      await writeContract(approvalData)
      // 3. Prepare deposit transaction
      const depositData = await prepareDepositTransactionData({
        vaultKey: 'bobaeth',
        userAddress: address,
        depositTokenSymbol: 'WETH',
        depositAmount: '1.0',
        chainId: 1,
        slippage: 0.01, // 1% slippage
      })
      // 4. Execute deposit
      await writeContract(depositData)
    } catch (error) {
      console.error('Deposit failed:', error)
    }
  }
  return (
    <div>
      <button onClick={handleDeposit} disabled={isLoading}>
        {isLoading ? 'Processing...' : 'Deposit 1 WETH'}
      </button>
      {isSuccess && <p>Transaction successful!</p>}
    </div>
  )
}
```
## API Reference
### Transaction Preparation Functions
#### prepareDepositTransactionData
Prepares transaction data for depositing assets into a vault.
```ts
import { prepareDepositTransactionData } from '@molecularlabs/nucleus-frontend'
const depositData = await prepareDepositTransactionData({
  vaultKey: 'bobaeth',
  userAddress: '0x1234...',
  depositTokenSymbol: 'WETH',
  depositAmount: '1.0', // Amount as string
  chainId: 1, // Ethereum mainnet
  slippage: 0.01, // 1% slippage (optional)
})
// Use with Wagmi
const { writeContract } = useWriteContract()
await writeContract(depositData)
```
#### prepareDepositAndBridgeTransactionData
Prepares transaction data for depositing and bridging assets across chains.
```ts
import { prepareDepositAndBridgeTransactionData } from '@molecularlabs/nucleus-frontend'
const bridgeData = await prepareDepositAndBridgeTransactionData({
  vaultKey: 'bobaeth',
  depositTokenSymbol: 'WETH',
  depositAmount: '1.0',
  sourceChainId: 1, // Ethereum mainnet
  destinationChainId: 288, // Boba network
  userAddress: '0x1234...',
  slippage: 0.01,
})
// Use with Wagmi
const { writeContract } = useWriteContract()
await writeContract(bridgeData)
```
#### prepareWithdrawTransactionData
Prepares transaction data for withdrawing assets from a vault.
```ts
import { prepareWithdrawTransactionData } from '@molecularlabs/nucleus-frontend'
const withdrawData = await prepareWithdrawTransactionData({
  vaultKey: 'bobaeth',
  chainId: 1,
  userAddress: '0x1234...',
  wantTokenSymbol: 'WETH',
  offerAmount: '1.0', // Amount of vault shares to redeem
  deadline: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
  slippage: 0.01,
})
// Use with Wagmi
const { writeContract } = useWriteContract()
await writeContract(withdrawData)
```
#### prepareBridgeAndWithdrawTransactionData
Prepares transaction data for bridging and withdrawing assets across chains.
```ts
import { prepareBridgeAndWithdrawTransactionData } from '@molecularlabs/nucleus-frontend'
const bridgeAndWithdrawData = await prepareBridgeAndWithdrawTransactionData({
  vaultKey: 'bobaeth',
  sourceChainId: 288, // Boba network
  destinationChainId: 1, // Ethereum mainnet
  userAddress: '0x1234...',
  wantTokenSymbol: 'WETH',
  offerAmount: '1.0',
  deadline: Math.floor(Date.now() / 1000) + 3600,
  slippage: 0.01,
})
// Execute bridge transaction first
const { writeContract } = useWriteContract()
await writeContract(bridgeAndWithdrawData.bridgeTransactionData)
// Then execute withdraw transaction on destination chain
await writeContract(bridgeAndWithdrawData.withdrawTransactionData)
```
### Approval Functions
#### prepareApproveDepositToken
Prepares approval transaction for deposit tokens.
```ts
import { prepareApproveDepositToken } from '@molecularlabs/nucleus-frontend'
const approvalData = await prepareApproveDepositToken({
  vaultKey: 'bobaeth',
  depositTokenSymbol: 'WETH',
  depositAmount: '1.0', // Optional: specific amount to approve
  chainId: 1,
})
// Use with Wagmi
const { writeContract } = useWriteContract()
await writeContract(approvalData)
```
#### prepareApproveWithdrawToken
Prepares approval transaction for vault shares.
```ts
import { prepareApproveWithdrawToken } from '@molecularlabs/nucleus-frontend'
const approvalData = await prepareApproveWithdrawToken({
  vaultKey: 'bobaeth',
  withdrawAmount: '1.0', // Optional: specific amount to approve
  chainId: 1,
})
// Use with Wagmi
const { writeContract } = useWriteContract()
await writeContract(approvalData)
```
### Utility Functions
#### getVaultByKey
Retrieves vault configuration by key.
```ts
import { getVaultByKey, VaultKeys } from '@molecularlabs/nucleus-frontend'
const vault = await getVaultByKey('bobaeth')
console.log('Available vaults:', VaultKeys)
```
#### Exchange Rate Functions
```ts
import { 
  getDepositExchangeRate, 
  getWithdrawExchangeRate 
} from '@molecularlabs/nucleus-frontend'
// Get deposit exchange rate
const depositRate = await getDepositExchangeRate({
  vaultKey: 'bobaeth',
  depositTokenSymbol: 'WETH',
  depositAmount: '1.0',
  chainId: 1,
})
// Get withdraw exchange rate
const withdrawRate = await getWithdrawExchangeRate({
  vaultKey: 'bobaeth',
  wantTokenSymbol: 'WETH',
  offerAmount: '1.0',
  chainId: 1,
})
```
#### Bridge Fee Functions
```ts
import { getBridgeFee } from '@molecularlabs/nucleus-frontend'
const bridgeFee = await getBridgeFee({
  vaultKey: 'bobaeth',
  sourceChainId: 1,
  destinationChainId: 288,
  bridgeAmount: '1.0',
})
```
#### Approval Check Functions
```ts
import { 
  isDepositSpendApproved, 
  isWithdrawalSpendApproved 
} from '@molecularlabs/nucleus-frontend'
// Check if deposit token is approved
const isDepositApproved = await isDepositSpendApproved({
  vaultKey: 'bobaeth',
  userAddress: '0x1234...',
  depositTokenSymbol: 'WETH',
  depositAmount: '1.0',
  chainId: 1,
})
// Check if vault shares are approved
const isWithdrawApproved = await isWithdrawalSpendApproved({
  vaultKey: 'bobaeth',
  userAddress: '0x1234...',
  withdrawAmount: '1.0',
  chainId: 1,
})
```
## Complete Example with React Hook
```tsx
import { useState } from 'react'
import { useAccount, useWriteContract, useWaitForTransactionReceipt } from 'wagmi'
import { 
  prepareDepositTransactionData,
  prepareApproveDepositToken,
  isDepositSpendApproved,
  VaultKeys 
} from '@molecularlabs/nucleus-frontend'
function useNucleusDeposit() {
  const { address } = useAccount()
  const { writeContract, data: hash } = useWriteContract()
  const { isLoading, isSuccess } = useWaitForTransactionReceipt({ hash })
  const [error, setError] = useState<string | null>(null)
  const deposit = async (
    vaultKey: string,
    tokenSymbol: string,
    amount: string,
    chainId: number,
    slippage = 0.01
  ) => {
    if (!address) {
      setError('No wallet connected')
      return
    }
    try {
      setError(null)
      // Check if approval is needed
      const isApproved = await isDepositSpendApproved({
        vaultKey,
        userAddress: address,
        depositTokenSymbol: tokenSymbol,
        depositAmount: amount,
        chainId,
      })
      if (!isApproved) {
        // Prepare and execute approval
        const approvalData = await prepareApproveDepositToken({
          vaultKey,
          depositTokenSymbol: tokenSymbol,
          depositAmount: amount,
          chainId,
        })
        await writeContract(approvalData)
      }
      // Prepare and execute deposit
      const depositData = await prepareDepositTransactionData({
        vaultKey,
        userAddress: address,
        depositTokenSymbol: tokenSymbol,
        depositAmount: amount,
        chainId,
        slippage,
      })
      await writeContract(depositData)
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Transaction failed')
    }
  }
  return {
    deposit,
    isLoading,
    isSuccess,
    error,
  }
}
// Usage in component
function DepositForm() {
  const { deposit, isLoading, isSuccess, error } = useNucleusDeposit()
  const [amount, setAmount] = useState('1.0')
  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    deposit('bobaeth', 'WETH', amount, 1, 0.01)
  }
  return (
    <form onSubmit={handleSubmit}>
      <input
        type="number"
        value={amount}
        onChange={(e) => setAmount(e.target.value)}
        placeholder="Amount"
        step="0.1"
        min="0"
      />
      <button type="submit" disabled={isLoading}>
        {isLoading ? 'Processing...' : 'Deposit WETH'}
      </button>
      {error && <p style={{ color: 'red' }}>{error}</p>}
      {isSuccess && <p style={{ color: 'green' }}>Deposit successful!</p>}
    </form>
  )
}
```
## TypeScript Support
The SDK provides full TypeScript support with comprehensive type definitions:
```ts
import type { 
  VaultKey, 
  ChainId, 
  DepositTransactionData,
  WithdrawTransactionData 
} from '@molecularlabs/nucleus-frontend'
// All functions are fully typed
const depositData: DepositTransactionData = await prepareDepositTransactionData({
  // TypeScript will provide autocomplete and type checking
})
```
## Error Handling
The SDK includes comprehensive error handling:
```ts
try {
  const depositData = await prepareDepositTransactionData({
    vaultKey: 'bobaeth',
    userAddress: '0x1234...',
    depositTokenSymbol: 'WETH',
    depositAmount: '1.0',
    chainId: 1,
  })
} catch (error) {
  if (error instanceof Error) {
    console.error('Deposit preparation failed:', error.message)
  }
}
```
## Supported Networks
- Ethereum Mainnet (Chain ID: 1)
- Boba Network (Chain ID: 288)
- Sei Network (Chain ID: 713715)
- Plume Mainnet (Chain ID: 98866)
## License
MIT