> For the complete documentation index, see [llms.txt](https://docs.augustdigital.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.augustdigital.io/developers/typescript-sdk/code-examples/solana-actions.md).

# Solana Actions

Execute transactions on Solana vaults including deposits, withdrawals, and queries. All operations follow the same pattern as EVM vaults for consistency.

### Overview

Solana vault interactions use the same pattern as EVM:

1. Use `sdk.getVault()` to query vault data
2. Use `sdk.solana.vaultDeposit()` to deposit
3. Use `sdk.solana.vaultRedeem()` to withdraw

The SDK handles all Solana-specific complexities (PDAs, token accounts, etc.) automatically.

### Setup

#### Basic Initialization

Include Solana RPC endpoint when initializing the SDK:

```typescript
import AugustSDK from '@augustdigital/sdk';

const sdk = new AugustSDK({
  appName: 'your-app-name', // required
  providers: {
    -1: 'https://api.mainnet-beta.solana.com', // Solana Mainnet
  },
});

// Access Solana adapter
const solana = sdk.solana;
```

#### Custom RPC Endpoint

```typescript
const sdk = new AugustSDK({
  appName: 'your-app-name', // required
  providers: {
    -1: 'https://solana-mainnet.g.alchemy.com/v2/YOUR_KEY',
  },
});
```

#### For Write Operations

To execute transactions, you need to set a wallet provider:

```typescript
import { useWallet } from '@solana/wallet-adapter-react';

// In your React component
const { publicKey, signTransaction } = useWallet();

// Set wallet for signing transactions
if (publicKey && signTransaction) {
  sdk.solana.setWalletProvider(publicKey, signTransaction);
}
```

### Adapter API

#### Methods

**setWalletProvider()**

Set the wallet provider for write operations.

```typescript
sdk.solana.setWalletProvider(
  publicKey: PublicKey | string,
  signTransaction: (tx: Transaction) => Promise<Transaction>
): void
```

**Parameters:**

* `publicKey`: User's Solana public key
* `signTransaction`: Function to sign transactions (from wallet adapter)

**Example:**

```typescript
import { useWallet } from '@solana/wallet-adapter-react';

function MyComponent() {
  const { publicKey, signTransaction } = useWallet();

  useEffect(() => {
    if (publicKey && signTransaction) {
      sdk.solana.setWalletProvider(publicKey, signTransaction);
    }
  }, [publicKey, signTransaction]);
}
```

### Get Vault Data

Query Solana vault information using the same `sdk.getVault()` method as EVM vaults.

```typescript
sdk.getVault({
  vault: string;  // Solana program ID
  chainId?: number;  // -1 for mainnet
  options?: {
    solanaWallet?: string;  // For user position data
  };
}): Promise<IVault>
```

#### Parameters

| Parameter              | Type     | Required | Description                                |
| ---------------------- | -------- | -------- | ------------------------------------------ |
| `vault`                | `string` | Yes      | Solana vault program ID                    |
| `options.solanaWallet` | `string` | No       | User's Solana public key for position data |

#### Example

```typescript
// Get vault details
const vault = await sdk.getVault({
  vault: 'VaultProgramId...',
  chainId: -1, // Solana mainnet
});

console.log('Name:', vault.name);
console.log('Version:', vault.version); // "sol-0"
console.log('Total Assets:', vault.totalAssets.normalized);
console.log('APY:', vault.apy.apy);
console.log('Deposit Token:', vault.depositAssets[0].symbol);

// Get vault with user position
const vaultWithPosition = await sdk.getVault({
  vault: 'VaultProgramId...',
  chainId: -1,
  options: {
    solanaWallet: 'UserPublicKey...',
  },
});

if (vaultWithPosition.position) {
  console.log(
    'Your balance:',
    vaultWithPosition.position.walletBalance.normalized,
  );
}
```

#### Get All Solana Vaults

```typescript
const solanaVaults = await sdk.getVaults({
  chainIds: [-1], // Filter to Solana mainnet only
  solanaWallet: 'UserPublicKey...', // Optional: include positions
});

solanaVaults.forEach((vault) => {
  console.log(`${vault.name}: ${vault.totalAssets.normalized} TVL`);
});
```

#### Get User Positions

```typescript
const positions = await sdk.getVaultPositions({
  solanaWallet: 'UserPublicKey...',
  chainId: -1,
});

positions.forEach((position) => {
  console.log(`Vault: ${position.vault}`);
  console.log(`Balance: ${position.walletBalance.normalized}`);
});
```

### Vault Deposit

Deposit tokens into a Solana vault. The SDK derives the vault PDAs, creates the depositor's share token account when it is missing, and sends the program's `deposit_checked` instruction through the wallet registered with `setWalletProvider`.

```typescript
sdk.solana.vaultDeposit(
  vaultProgramId: PublicKey | string,
  idl: object,
  publicKey: PublicKey | string,
  depositAmount: number | bigint,
  sendTransaction?: undefined,
  vaultAddress?: PublicKey | string,
  options?: ISolanaDepositOptions,
): Promise<string>
```

#### Parameters

| Parameter         | Type                    | Required | Description                                                                                                                    |
| ----------------- | ----------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `vaultProgramId`  | `PublicKey \| string`   | Yes      | Vault program ID — `Solana.constants.programIds['mainnet-beta'].vault` on mainnet                                              |
| `idl`             | `object`                | Yes      | Program IDL — pass `Solana.constants.vaultIdl`                                                                                 |
| `publicKey`       | `PublicKey \| string`   | Yes      | Depositor's wallet public key                                                                                                  |
| `depositAmount`   | `number \| bigint`      | Yes      | `bigint` is raw on-chain units; `number` is a UI amount converted with the deposit mint's decimals                             |
| `sendTransaction` | `undefined`             | No       | Ignored and scheduled for removal. Pass `undefined` rather than dropping the argument, or `vaultAddress` shifts into this slot |
| `vaultAddress`    | `PublicKey \| string`   | No       | Vault state account. Omit only for legacy single-vault programs, which derive it from the program ID                           |
| `options`         | `ISolanaDepositOptions` | No       | Slippage protection, see below                                                                                                 |

#### Slippage protection

Deposits send the program's `deposit_checked` instruction. The SDK quotes the shares the deposit should mint from the vault's current state and passes that quote, lowered by a tolerance, as `min_shares_out`; the program reverts with `SlippageExceeded` if the share price moves past it before execution. Control it with the trailing `options` argument:

```typescript
// Default: 50 bps (0.5%) below the quote.
await sdk.solana.vaultDeposit(programId, idl, wallet, amount, undefined, vaultAddress);

// Tighter or looser tolerance, in basis points.
await sdk.solana.vaultDeposit(programId, idl, wallet, amount, undefined, vaultAddress, {
  slippageBps: 10,
});

// Your own floor in raw share units (skips the quote and its snapshot read).
// `0n` restores the unguarded behaviour of the plain `deposit` instruction.
await sdk.solana.vaultDeposit(programId, idl, wallet, amount, undefined, vaultAddress, {
  minSharesOut: 995_000n,
});
```

#### Returns

Transaction signature as `string`.

#### Example

```typescript
import { Solana } from '@augustdigital/sdk';
import { useWallet } from '@solana/wallet-adapter-react';

const { publicKey, signTransaction } = useWallet();

if (publicKey && signTransaction) {
  sdk.solana.setWalletProvider(publicKey, signTransaction);
}

const signature = await sdk.solana.vaultDeposit(
  Solana.constants.programIds['mainnet-beta'].vault,
  Solana.constants.vaultIdl,
  publicKey,
  100, // 100 tokens, UI amount
  undefined,
  'VaultAddress...',
);

console.log('Deposit successful:', signature);
```

#### Behavior

The SDK automatically:

1. Fetches the vault state and derives the PDAs
2. Creates the share token account when the depositor has none, in the same transaction
3. Converts a `number` amount to raw units with the deposit mint's decimals
4. Quotes the expected shares and applies the slippage floor
5. Signs through the registered wallet and confirms at the adapter's commitment level (`finalized` by default)

### Vault Withdraw

Redeem shares from a Solana vault. The program's `redeem_checked` instruction burns the shares and transfers the payout in the same transaction.

```typescript
sdk.solana.vaultRedeem(
  vaultProgramId: PublicKey | string,
  idl: object,
  publicKey: PublicKey | string,
  redeemShares: number | bigint,
  sendTransaction?: undefined,
  vaultAddress?: PublicKey | string,
  options?: ISolanaRedeemOptions,
): Promise<string>
```

#### Parameters

| Parameter         | Type                   | Required | Description                                                                                                                    |
| ----------------- | ---------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `vaultProgramId`  | `PublicKey \| string`  | Yes      | Vault program ID — `Solana.constants.programIds['mainnet-beta'].vault` on mainnet                                              |
| `idl`             | `object`               | Yes      | Program IDL — pass `Solana.constants.vaultIdl`                                                                                 |
| `publicKey`       | `PublicKey \| string`  | Yes      | Share holder's wallet public key                                                                                               |
| `redeemShares`    | `number \| bigint`     | Yes      | `bigint` is raw share units; `number` is a UI amount                                                                           |
| `sendTransaction` | `undefined`            | No       | Ignored and scheduled for removal. Pass `undefined` rather than dropping the argument, or `vaultAddress` shifts into this slot |
| `vaultAddress`    | `PublicKey \| string`  | No       | Vault state account. Omit only for legacy single-vault programs                                                                |
| `options`         | `ISolanaRedeemOptions` | No       | Slippage protection, see below                                                                                                 |

#### Slippage protection

Redemptions send `redeem_checked`. The floor is on what the wallet **receives, net of the withdrawal fee**, quoted from the vault state the SDK already reads; the default tolerance is 50 bps. Pass `slippageBps` or an explicit `minAssetsOut` (raw deposit-mint units) in the trailing `options` argument, exactly as for deposits. A `SlippageExceeded` revert is reported with a message saying the price moved past your tolerance and to retry or raise it.

#### Returns

Transaction signature as `string`.

#### Example

```typescript
const positions = await sdk.getVaultPositions({
  solanaWallet: publicKey.toString(),
  chainId: -1,
});

if (positions[0].walletBalance.raw === '0') {
  throw new Error('No balance to redeem');
}

const signature = await sdk.solana.vaultRedeem(
  Solana.constants.programIds['mainnet-beta'].vault,
  Solana.constants.vaultIdl,
  publicKey,
  50, // redeem 50 shares, UI amount
  undefined,
  'VaultAddress...',
);

console.log('Redemption complete:', signature);
```

### Examples

#### Complete Deposit Flow

```typescript
import AugustSDK, { Solana } from '@augustdigital/sdk';
import { useWallet } from '@solana/wallet-adapter-react';

function SolanaVaultDeposit() {
  const { publicKey, signTransaction } = useWallet();
  const [loading, setLoading] = useState(false);

  const sdk = new AugustSDK({
    appName: 'your-app-name', // required
    providers: {
      -1: 'https://api.mainnet-beta.solana.com',
    },
  });

  const deposit = async (vaultAddress: string, amount: number) => {
    if (!publicKey || !signTransaction) {
      throw new Error('Wallet not connected');
    }

    setLoading(true);
    try {
      // 1. Set wallet provider
      sdk.solana.setWalletProvider(publicKey, signTransaction);

      // 2. Get vault details
      const vault = await sdk.getVault({
        vault: vaultAddress,
        chainId: -1,
      });

      console.log(`Depositing to ${vault.name}`);

      // 3. Execute deposit (SDK handles everything)
      const signature = await sdk.solana.vaultDeposit(
        Solana.constants.programIds['mainnet-beta'].vault,
        Solana.constants.vaultIdl,
        publicKey,
        amount,
        undefined,
        vaultAddress,
      );

      console.log('Deposit successful:', signature);
      return signature;
    } catch (error) {
      console.error('Deposit failed:', error);
      throw error;
    } finally {
      setLoading(false);
    }
  };

  return (
    <button
      onClick={() => deposit('VaultAddress...', 100)}
      disabled={loading || !publicKey}
    >
      {loading ? 'Depositing...' : 'Deposit 100 Tokens'}
    </button>
  );
}
```

#### Complete Withdrawal Flow

```typescript
function SolanaVaultWithdraw() {
  const { publicKey, signTransaction } = useWallet();

  const sdk = new AugustSDK({
    appName: 'your-app-name', // required
    providers: {
      -1: 'https://api.mainnet-beta.solana.com',
    },
  });

  const withdraw = async (vaultAddress: string) => {
    if (!publicKey || !signTransaction) {
      throw new Error('Wallet not connected');
    }

    try {
      // 1. Set wallet provider
      sdk.solana.setWalletProvider(publicKey, signTransaction);

      // 2. Check user's position
      const position = await sdk.getVaultPositions({
        solanaWallet: publicKey.toString(),
        chainId: -1,
      });

      if (!position[0] || position[0].walletBalance.raw === '0') {
        throw new Error('No balance to withdraw');
      }

      const shares = BigInt(position[0].walletBalance.raw);
      console.log(`Redeeming ${position[0].walletBalance.normalized} shares`);

      // 3. Execute redemption (all shares, in raw units)
      const signature = await sdk.solana.vaultRedeem(
        Solana.constants.programIds['mainnet-beta'].vault,
        Solana.constants.vaultIdl,
        publicKey,
        shares,
        undefined,
        vaultAddress,
      );

      console.log('Withdrawal successful:', signature);
      return signature;
    } catch (error) {
      console.error('Withdrawal failed:', error);
      throw error;
    }
  };

  return (
    <button onClick={() => withdraw('VaultAddress...')}>
      Withdraw All
    </button>
  );
}
```

#### Query Vault Before Depositing

```typescript
// 1. Get vault info
const vault = await sdk.getVault({
  vault: 'VaultAddress...',
  chainId: -1,
});

// 2. Check if deposits are enabled
if (vault.isDepositPaused) {
  throw new Error('Vault deposits are paused');
}

// 3. Show user the vault details
console.log(`Vault: ${vault.name}`);
console.log(`APY: ${vault.apy.apy}%`);
console.log(`TVL: ${vault.totalAssets.normalized}`);
console.log(`Deposit token: ${vault.depositAssets[0].symbol}`);

// 4. Deposit
await sdk.solana.vaultDeposit(
  Solana.constants.programIds['mainnet-beta'].vault,
  Solana.constants.vaultIdl,
  publicKey,
  100,
  undefined,
  vault.address,
);
```

### Advanced Operations

For advanced use cases, the Solana adapter exposes low-level methods and utilities.

#### Direct Program Access

Access Solana connection and provider for custom operations:

```typescript
// Get connection
const connection = sdk.solana.connection;
const balance = await connection.getBalance(publicKey);

// Get Anchor provider
const provider = sdk.solana.provider;

// Get program instance
const program = sdk.solana.getProgram(Solana.constants.vaultIdl);

// Query vault account directly
const vaultState = await program.account.vault.fetch(vaultPda);
```

#### Utility Functions

```typescript
import { Solana } from '@augustdigital/sdk';
```

**deriveShareMintPda()**

Derive the share mint PDA for a vault.

```typescript
const shareMintPda = Solana.utils.deriveShareMintPda('VaultProgramId...');

console.log('Share Mint PDA:', shareMintPda.toString());
```

**getToken()**

Get token metadata from mint address.

```typescript
const token = await Solana.utils.getToken({
  mintAddress: 'MintPublicKey...',
  endpoint: 'https://api.mainnet-beta.solana.com',
  connection: sdk.solana.connection,
});

console.log('Symbol:', token.symbol);
console.log('Decimals:', token.decimals);
console.log('Supply:', token.supply);
```

#### getVaultStateReadOnly()

Get vault state without a wallet provider.

```typescript
const vaultState = await Solana.utils.getVaultStateReadOnly({
  vaultProgramId: 'VaultProgramId...',
  idl: vaultIdl,
  endpoint: 'https://api.mainnet-beta.solana.com',
  connection: sdk.solana.connection,
});
```

#### getProvider()

Create an Anchor provider with wallet.

```typescript
import { PublicKey } from '@solana/web3.js';

const provider = Solana.utils.getProvider({
  network: 'mainnet-beta',
  connection: sdk.solana.connection,
  publicKey: new PublicKey('UserPublicKey...'),
  signTransaction: signTransactionFunction,
});
```

#### getReadOnlyProvider()

Create a read-only Anchor provider.

```typescript
const provider = Solana.utils.getReadOnlyProvider({
  network: 'mainnet-beta',
  connection: sdk.solana.connection,
});
```

#### getProgram()

Create an Anchor program instance.

```typescript
const program = Solana.utils.getProgram({
  network: 'mainnet-beta',
  provider: anchorProvider,
  idl: programIdl,
});
```

### Constants

```typescript
import { Solana } from '@augustdigital/sdk';
```

#### Vault IDL

```typescript
const vaultIdl = Solana.constants.vaultIdl;
```

#### Program IDs

```typescript
const programId = Solana.constants.programIds['mainnet-beta'].vault;

// Per network; `undefined` where the program is not deployed.
const devnet = Solana.constants.getDeployedProgramIds('devnet');
```

#### Fallback Values

```typescript
const fallbackDecimals = Solana.constants.fallbackDecimals; // 8
const fallbackNetwork = Solana.constants.fallbackNetwork; // 'mainnet-beta'
```

### Error Handling

#### Connection Errors

```typescript
try {
  const vaultState = await sdk.solana.getVaultState('VaultId...', vaultIdl);
} catch (error) {
  if (error.message.includes('404')) {
    console.error('Vault program not found');
  } else if (error.message.includes('Network request failed')) {
    console.error('RPC connection failed');
  } else {
    console.error('Unknown error:', error);
  }
}
```

#### Transaction Errors

```typescript
try {
  await sdk.solana.vaultDeposit(
    Solana.constants.programIds['mainnet-beta'].vault,
    Solana.constants.vaultIdl,
    publicKey,
    1_000_000_000n,
    undefined,
    'VaultAddress...',
  );
} catch (error) {
  if (error.message.includes('User rejected')) {
    console.error('Transaction cancelled by user');
  } else if (error.message.includes('insufficient funds')) {
    console.error('Not enough SOL for transaction');
  } else {
    console.error('Transaction failed:', error);
  }
}
```
