๐Ÿง™โ€โ™€๏ธSolana

An in-depth guide on how to integrate the Solana Service Alpha release into your existing August SDK service.

Overview

The SolanaService is a comprehensive service for interacting with Solana vaults in the August Digital ecosystem. It provides functionality for fetching vault state, depositing tokens, and withdrawing tokens from Solana-based vaults.

Table of Contents


Before you get started

  1. Update your existing AugustSDK initialization method. First time using the SDK? See how to use it here.

    const AugustSDK = new AugustDigitalSDK({
      augustKey: <AUGUST_API_KEY>
      providers: {
        <CHAIN_ID>: <JSON_RPC_URL>,
        // Mainnet Example:
        // 1: `https://mainnet.infura.io/v3/${INFURA_API_KEY}`,
      },
      solana: {
        rpcUrl: <SOLANA_RPC_URL>,
        network: 'mainnet-beta' | 'devnet'
      }
    })

Initialization

Basic Initialization

import { SolanaService } from '@augustdigital/services';
import { PublicKey } from '@solana/web3.js';

// Initialize with RPC endpoint and network
const solanaService = new SolanaService(
  'https://api.devnet.solana.com', // RPC endpoint
  'devnet' // Network: 'devnet' | 'mainnet-beta' | 'testnet' | 'localnet'
);

With Wallet Connection

import { SolanaService } from '@augustdigital/services';
import { PublicKey } from '@solana/web3.js';

const solanaService = new SolanaService(
  'https://api.devnet.solana.com',
  'devnet'
);

// Connect wallet for authenticated operations
const publicKey = new PublicKey('YOUR_WALLET_PUBLIC_KEY');
const signTransaction = async (transaction) => {
  // Your wallet's sign transaction function
  return signedTransaction;
};

solanaService.setWalletProvider(publicKey, signTransaction);

AugustSDK Integration

Updating AugustSDK Initializer

To integrate SolanaService with your existing AugustSDK setup, update your configuration to include Solana settings:

import AugustDigitalSDK from '@augustdigital/sdk';

const augustSdk = new AugustDigitalSDK({
  augustKey: process.env.NEXT_PUBLIC_AUGUST_DIGITAL_API_KEY,
  subgraphKey: process.env.NEXT_PUBLIC_SUBGRAPH_API_KEY,
  providers: {
    1: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY',
    56: 'https://bsc-dataseed.binance.org/',
    // ... other EVM chains
  },
  env: 'PROD',
  slackWebookUrl: process.env.NEXT_PUBLIC_SLACK_WEBHOOK_URL,
  // Add Solana configuration
  solana: {
    rpcUrl: 'https://api.devnet.solana.com',
    network: 'devnet'
  }
});

// Access SolanaService through the SDK
const solanaService = augustSdk.solanaService; // This is automatically initialized

Accessing SolanaService

The SolanaService is automatically initialized when you provide Solana configuration to AugustSDK:

// The SolanaService is available as a private property
// You can access it through the vaults methods or create a public getter

Fetching Vault State

Basic Vault State Fetching

import { SolanaVaultIdl } from '@augustdigital/services';
import { PublicKey } from '@solana/web3.js';

// Get vault program ID
const vaultProgramId = solanaService.getProgramId('vault');
// or use a specific program ID
const vaultProgramId = new PublicKey('dELbEtKGo19R4H9qmvuji7AXfqvqC1DDr5BUFVHons4');

// Fetch vault state (requires wallet connection)
const vaultState = await solanaService.getVaultState(
  vaultProgramId,
  SolanaVaultIdl
);

console.log('Vault State:', vaultState);
// Returns: { vaultState, depositMintDecimals, vaultToken }

Read-Only Vault State (No Wallet Required)

// Fetch vault state without wallet connection
const vaultState = await solanaService.getVaultStateReadOnly(
  vaultProgramId,
  SolanaVaultIdl
);

console.log('Vault State:', vaultState);

Vault State Response Structure

interface VaultStateResponse {
  vaultState: {
    operator: PublicKey | null;
    admin: PublicKey | null;
    shareMint: PublicKey | null;
    depositMint: PublicKey | null;
    feeRecipient: PublicKey | null;
    withdrawalFee: number | null;
    deployedAum: number | null;
    pdaBump: number[] | null;
    paused: boolean | null;
  } | null;
  depositMintDecimals: number | null;
  vaultToken: {
    balance: number;
    decimals: number;
    rawAmount: string;
    symbol: string;
    name: string;
  };
}

Depositing into Solana Vault

Prerequisites

Before depositing, ensure you have:

  1. A connected wallet with the required tokens

  2. The vault state fetched

  3. A valid deposit amount

Deposit Implementation

import { SolanaVaultIdl } from '@augustdigital/services';
import { PublicKey } from '@solana/web3.js';

async function depositToVault(
  solanaService: SolanaService,
  vaultProgramId: PublicKey,
  depositAmount: number,
  publicKey: PublicKey,
  sendTransaction: (tx: Transaction, connection: Connection) => Promise<string>
) {
  try {
    // 1. First, fetch the vault state
    const vaultStateData = await solanaService.getVaultState(
      vaultProgramId,
      SolanaVaultIdl
    );

    if (!vaultStateData.vaultState) {
      throw new Error('Failed to fetch vault state');
    }

    // 2. Perform the deposit
    const depositResult = await solanaService.handleDeposit(
      vaultProgramId,
      SolanaVaultIdl,
      publicKey,
      depositAmount,
      vaultStateData.vaultState,
      sendTransaction
    );

    if (depositResult) {
      console.log('Deposit successful! Transaction signature:', depositResult);
      return depositResult;
    } else {
      throw new Error('Deposit failed');
    }
  } catch (error) {
    console.error('Deposit error:', error);
    throw error;
  }
}

// Usage example
const vaultProgramId = new PublicKey('dELbEtKGo19R4H9qmvuji7AXfqvqC1DDr5BUFVHons4');
const depositAmount = 100; // Amount in token units (not wei)

const result = await depositToVault(
  solanaService,
  vaultProgramId,
  depositAmount,
  publicKey,
  sendTransaction
);

Deposit Process

  1. Token Account Creation: If you don't have a share token account, it will be created automatically

  2. Amount Validation: The service validates the deposit amount and converts it to the correct decimal precision

  3. Transaction Building: Creates and signs the deposit transaction

  4. Execution: Sends the transaction to the Solana network


Withdrawing from Solana Vault

Prerequisites

Before withdrawing, ensure you have:

  1. A connected wallet with vault shares

  2. The vault state fetched

  3. A valid withdrawal amount (in shares)

Withdrawal Implementation

import { SolanaVaultIdl } from '@augustdigital/services';
import { PublicKey } from '@solana/web3.js';

async function withdrawFromVault(
  solanaService: SolanaService,
  vaultProgramId: PublicKey,
  redeemShares: number,
  publicKey: PublicKey,
  sendTransaction: (tx: Transaction, connection: Connection) => Promise<string>
) {
  try {
    // 1. First, fetch the vault state
    const vaultStateData = await solanaService.getVaultState(
      vaultProgramId,
      SolanaVaultIdl
    );

    if (!vaultStateData.vaultState) {
      throw new Error('Failed to fetch vault state');
    }

    // 2. Check user's share balance
    const shareBalance = await solanaService.fetchUserShareBalance(
      publicKey,
      vaultStateData.vaultState
    );

    if (shareBalance < redeemShares) {
      throw new Error('Insufficient share balance');
    }

    // 3. Perform the withdrawal
    const withdrawResult = await solanaService.handleRedeem(
      vaultProgramId,
      SolanaVaultIdl,
      publicKey,
      redeemShares,
      vaultStateData.vaultState,
      sendTransaction
    );

    if (withdrawResult) {
      console.log('Withdrawal successful! Transaction signature:', withdrawResult);
      return withdrawResult;
    } else {
      throw new Error('Withdrawal failed');
    }
  } catch (error) {
    console.error('Withdrawal error:', error);
    throw error;
  }
}

// Usage example
const vaultProgramId = new PublicKey('dELbEtKGo19R4H9qmvuji7AXfqvqC1DDr5BUFVHons4');
const redeemShares = 50; // Amount of shares to redeem

const result = await withdrawFromVault(
  solanaService,
  vaultProgramId,
  redeemShares,
  publicKey,
  sendTransaction
);

Withdrawal Process

  1. Share Balance Check: Verifies you have sufficient shares to redeem

  2. Fee Recipient Setup: Creates fee recipient token account if needed

  3. Amount Validation: Validates the withdrawal amount and converts to correct decimal precision

  4. Transaction Building: Creates and signs the redeem transaction

  5. Execution: Sends the transaction to the Solana network


Additional Utility Methods

Fetching User Balances

// Get user's token balance for the deposit mint
const tokenBalance = await solanaService.fetchUserTokenBalance(
  publicKey,
  vaultState
);

// Get user's share balance
const shareBalance = await solanaService.fetchUserShareBalance(
  publicKey,
  vaultState
);

Token Information

// Get token metadata
const tokenInfo = await solanaService.getToken(mintAddress);

// Get just the token symbol
const symbol = await solanaService.getTokenSymbol(mintAddress);

Program Access

// Get the vault program instance
const program = solanaService.getProgram(SolanaVaultIdl);

// Get program ID for vault
const vaultProgramId = solanaService.getProgramId('vault');

Error Handling

The SolanaService includes comprehensive error handling for common scenarios:

  • Wallet not connected: Throws error if wallet is required but not connected

  • Insufficient balance: Validates token and share balances before transactions

  • Invalid amounts: Ensures amounts are positive numbers

  • Missing vault state: Validates vault state before operations

  • Transaction failures: Handles and reports transaction errors


Network Support

The SolanaService supports the following networks:

  • devnet: Development network (default)

  • mainnet-beta: Main Solana network

  • testnet: Test network

  • localnet: Local development network


Type Definitions

Key types used throughout the service:

type ISolanaNetwork = 'devnet' | 'mainnet-beta' | 'testnet' | 'localnet';
type ISolanaRpcEndpoint = `https://${string}`;

interface ISolanaConfig {
  rpcUrl: string;
  network: ISolanaNetwork;
}

interface ISolanaVaultState {
  operator: PublicKey | null;
  admin: PublicKey | null;
  shareMint: PublicKey | null;
  depositMint: PublicKey | null;
  feeRecipient: PublicKey | null;
  withdrawalFee: number | null;
  deployedAum: number | null;
  pdaBump: number[] | null;
  paused: boolean | null;
}

This documentation provides a comprehensive guide for using the SolanaService with August Digital's Solana vaults. For additional support or questions, please refer to the August Digital documentation or contact support.

Last updated