Skip to main content

Overview

StateClient handles vault state management including creating new vaults, updating configurations, extending account size, and closing vaults.

Access

const client = new GlamClient();
client.state.initialize(...);

Methods

initialize

async initialize(
  params: InitStateParams,
  txOptions?: TxOptions
): Promise<TransactionSignature>
Creates a new GLAM vault state account.
params
InitStateParams
required
txOptions
TxOptions
Transaction options
Returns the transaction signature. The vault’s statePda is automatically set on the client after initialization.
import { StateAccountType } from "@glam/sdk";
import { stringToChars } from "@glam/sdk/utils";

const USDC = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
const SOL = new PublicKey("So11111111111111111111111111111111111111112");

// Create a tokenized vault
await client.state.initialize({
  accountType: StateAccountType.TOKENIZED_VAULT,
  name: stringToChars("My Investment Fund"),
  baseAssetMint: USDC,
  portfolioManagerName: stringToChars("Acme Capital"),
  assets: [USDC, SOL],
  timelockDuration: 86400, // 1 day
});

// The statePda is now set on the client
console.log("Vault created:", client.statePda.toBase58());
The state PDA is deterministically derived from:
  • Hash of the vault name
  • Owner public key
  • Protocol program ID
This allows you to recompute the state PDA later using the same name and owner.

update

async update(
  params: UpdateStateParams,
  txOptions?: TxOptions
): Promise<TransactionSignature>
Updates vault state configuration. Only the fields provided in params will be updated; omitted fields remain unchanged.
params
UpdateStateParams
required
txOptions
TxOptions
Transaction options
// Enable reduce-only mode
await client.state.update({
  reduceOnly: true,
});

// Add new assets to allowlist
await client.state.update({
  assets: [USDC, SOL, BONK, WIF],
});

// Transfer ownership
await client.state.update({
  owner: newOwnerPubkey,
});
If timelock is enabled on the vault:
  • Updates are staged and not applied immediately
  • Updates can be applied after the timelock period expires
  • Use TimelockClient to manage pending updates
If no timelock is configured, updates are applied immediately.

extend

async extend(
  newBytes: number,
  txOptions?: TxOptions
): Promise<TransactionSignature>
Extends the state account size to accommodate more data.
newBytes
number
required
Number of additional bytes to allocate
txOptions
TxOptions
Transaction options
// Extend state account by 1000 bytes
await client.state.extend(1000);
This is needed when adding many assets, delegates, or integration ACLs that exceed the current account size. The payer will be charged rent for the additional space.

close

async close(txOptions?: TxOptions): Promise<TransactionSignature>
Closes the vault state account and recovers rent.
txOptions
TxOptions
Transaction options
// Close the vault
await client.state.close();
Only the vault owner can close the state account. The vault must be empty (no assets, no shares outstanding) before it can be closed.

Transaction builder

For advanced use cases, access the transaction builder directly:
client.state.txBuilder: TxBuilder
The builder provides methods that return instructions or transactions without sending:

initializeIx

async initializeIx(
  params: InitStateParams,
  glamSigner: PublicKey
): Promise<[TransactionInstruction, PublicKey]>
Returns the initialization instruction and computed state PDA.
const [ix, statePda] = await client.state.txBuilder.initializeIx(
  {
    accountType: StateAccountType.TOKENIZED_VAULT,
    name: stringToChars("My Fund"),
    baseAssetMint: USDC,
  },
  client.signer
);

console.log("State PDA will be:", statePda.toBase58());

initializeTx

async initializeTx(
  params: InitStateParams,
  txOptions: TxOptions
): Promise<[VersionedTransaction, PublicKey]>
Returns the initialization transaction and computed state PDA.

updateIx

async updateIx(
  params: UpdateStateParams,
  glamSigner: PublicKey
): Promise<TransactionInstruction>
Returns the update instruction.

updateTx

async updateTx(
  params: UpdateStateParams,
  txOptions: TxOptions
): Promise<VersionedTransaction>
Returns the update transaction.

extendIx

async extendIx(
  newBytes: number,
  glamSigner: PublicKey
): Promise<TransactionInstruction>
Returns the extend instruction.

extendTx

async extendTx(
  newBytes: number,
  txOptions: TxOptions
): Promise<VersionedTransaction>
Returns the extend transaction.

closeIx

async closeIx(glamSigner: PublicKey): Promise<TransactionInstruction>
Returns the close instruction.

closeTx

async closeTx(txOptions: TxOptions): Promise<VersionedTransaction>
Returns the close transaction.

Types

StateAccountType

class StateAccountType {
  static readonly VAULT = { vault: {} };
  static readonly TOKENIZED_VAULT = { tokenizedVault: {} };
  static readonly MINT = { mint: {} };
  static readonly SINGLE_ASSET_VAULT = { singleAssetVault: {} };
}

Example usage

import { GlamClient, StateAccountType } from "@glam/sdk";
import { stringToChars } from "@glam/sdk/utils";
import { PublicKey } from "@solana/web3.js";

const client = new GlamClient();

// Create a new vault
await client.state.initialize({
  accountType: StateAccountType.TOKENIZED_VAULT,
  name: stringToChars("DeFi Strategy Fund"),
  baseAssetMint: new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"),
  portfolioManagerName: stringToChars("Solana Capital"),
  assets: [
    new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"), // USDC
    new PublicKey("So11111111111111111111111111111111111111112"),  // SOL
  ],
  timelockDuration: 86400, // 1 day timelock for updates
});

console.log("Vault created:", client.statePda.toBase58());

// Fetch vault state
const state = await client.fetchStateModel();
console.log("Vault name:", state.nameStr);
console.log("Owner:", state.owner.toBase58());
console.log("Assets:", state.assets);

// Update configuration
await client.state.update({
  reduceOnly: false,
});

Build docs developers (and LLMs) love