Meteora
  • Meteora: The most dynamic and sustainable liquidity layer on Solana
  • PRODUCT OVERVIEW
    • Meteora Liquidity Pools
      • DLMM Overview
        • What is DLMM?
        • DLMM Program
        • Dynamic Fees
        • Strategies & Use Cases
        • DLMM Farming Rewards
      • DLMM Launch Pool Overview
      • Dynamic AMM Overview
        • What is a Dynamic AMM Pool?
        • Dynamic AMM LP Fee and APY Calculation
        • Creating a Dynamic AMM Pool via the UI
        • Claiming Fees from Permanently Locked Liquidity
        • Dynamic AMM Stable Pools
        • Dynamic LST Pools
        • Additional yield from Dynamic Vaults
        • Dynamic AMM Farm Overview
      • DAMM v2 Overview
      • Memecoin Pool Overview
        • Memecoin Pool v2
          • What is Memecoin Pool v2?
        • Memecoin Pool v1
          • What is Memecoin Pool v1?
          • Permanently Locking Liquidity
      • Stake2Earn Pool Overview
        • What is a Stake2Earn Pool?
        • Stake2Earn for Launchpads
      • Multi-Token Stable Pool Overview
    • Alpha Vault Overview
    • Dynamic Vault Overview
      • What is a Dynamic Vault?
      • Dynamic Vault Program
      • Hermes - Meteora's Keeper
        • Algorithm to find optimal yield allocations
        • Rebalance crank
        • Operation fee calculation
      • Design Goals
      • Security
      • Dynamic Vaults Whitepaper
      • Dynamic Vaults Community Explainers
      • Affiliate Program for Dynamic Vault
        • Become an Affiliate Partner (Dynamic Vaults)
    • Dynamic Bonding Curve (DBC) Overview
      • What is the Dynamic Bonding Curve?
      • Customizable Pool Configuration
      • Bonding Curve Formula
      • DBC Migrator Keeper
    • Meteora’s Anti-Sniper Suite
  • INTEGRATION
    • DLMM Integration
      • DLMM SDK
        • DLMM TypeScript SDK
        • CPI Examples
      • DLMM API
      • Fetching information on locked liquidity in a DLMM
    • Dynamic AMM Pool Integration
      • Dynamic AMM SDK
        • Dynamic AMM TypeScript SDK
        • CPI Examples
      • Dynamic AMM API
        • Pool Info
        • Pool State
      • Setting Pool and Fee Config for Dynamic AMM Pools
      • Create Dynamic Pool with Timestamp/Slot Activation
      • Dynamic AMM - Farm Integration
    • DAMM v2 Integration
      • DAMM v2 SDK
        • DAMM v2 TypeScript SDK
        • DAMM v2 Rust SDK
      • Setting Pool and Fee Config for DAMM v2
      • Technical FAQ
    • Memecoin Pool Integration
      • Memecoin Pool v2 Integration
        • Setting Pool and Fee Config for Memecoin Pool v2
      • Memecoin Pool v1 Integration
        • TypeScript Code Examples
        • CPI Examples
        • Setting Pool and Fee Config for Memecoin Pool v1
        • Track permanently-locked liquidity in Memecoin Pool v1
        • Track Protocol Fee from swaps in Memecoin Pool v1
    • Stake2Earn Pool Integration
    • Dynamic Vault Integration
      • Using TypeScript-Client
      • Using Rust-Client
      • Using CPI
      • Vault API
        • Vault Info
        • Vault State
      • Vault Developer Resources
    • Alpha Vault Integration
      • Alpha Vault TypeScript SDK
      • Alpha Vault without Whitelist Setup
      • Alpha Vault with Whitelist Setup
    • Dynamic Bonding Curve (DBC) Integration
      • DBC SDK
        • DBC TypeScript SDK
        • DBC Rust SDK
      • DBC Fee Scheduler Formula
      • Program Repo
      • Technical FAQ
  • TOKEN LAUNCH POOLS
    • Steps to Create a Pool for a Token Launch
      • Create: DLMM Launch Pool
      • Create: Dynamic AMM Pool
      • Create: Memecoin Pool v1
      • Create: Stake2Earn Pool
      • Create: Pools with Alpha Vault
        • Create: DLMM Launch Pool with Alpha Vault
        • Create: Dynamic AMM Pool with Alpha Vault
        • Create: Memecoin Pool with Alpha Vault
        • Create: Stake2Earn Pool with Alpha Vault
    • Anti-Sniper Fee Suite for a Token Launch
  • Resources
    • Audits
    • Meteora Program IDs
    • Meteora APIs
    • Devnet Testing
    • Community Data Dashboards & Tools
    • Meteora Brand Assets
    • THE MASSIVE METEORA STIMULUS PACKAGE
      • Overview
      • 1. Dynamic Liquidity Market Maker (DLMM)
      • 2. Formation Of An LP Army DAO
      • 3. The 10% Stimulus Proposal
  • USER FAQ
    • Getting Started LPing
      • Supported Wallets
      • Prepare SOL
      • SOL required for Rent
      • What is Wrapped SOL?
      • What is an AMM?
      • What does it mean to provide liquidity?
      • How to swap to the tokens required for adding liquidity to a pool
      • How to quickly check if a token has any risks
      • Viewing your transaction history
      • My wallet has been compromised. What should I do?
    • Differences between DLMM and Dynamic Pools
    • DLMM FAQ
    • Dynamic AMM FAQ
      • How is the pool price of the token calculated in a Dynamic AMM?
      • What is a Meteora LP token?
      • How do I see fees earned on a Dynamic AMM Pool?
      • How to track your earnings for a Dynamic Pool?
      • What is Virtual Price in a Dynamic Pool?
      • How do LP tokens, fees, and virtual price work for Dynamic Pools?
      • Why must I add liquidity in non-stable Dynamic Pools using a 50:50 value ratio?
      • What is AMP in a Dynamic Pool with stable coins?
      • Why is the USDT-USDC pool not 1:1 in ratio of assets?
      • Can I create an LST, FX, or Multi-token pool using the Dynamic Pool creation tool?
    • Alpha Vault FAQ
    • Why is the token sometimes not picked up and tradable on Jupiter?
    • How do I create a new farm?
    • Video Tutorials to Get Started
      • LP Army Boot Camp
      • DLMM Strategy Sessions / Jam Sessions
  • Security and Risks
    • Risk of Impermanent Loss (IL)
    • Risk of depositing into an imbalanced pool / pool with price out of sync
    • Smart contract risk
    • Risk of a stablecoin depeg
    • Operational risk for dynamic vaults and pools
    • Lending risk for dynamic vaults and pools
  • legal
    • Terms of Service
    • Stake2Earn Terms of Service
Powered by GitBook
On this page
  • Example Timeline (Alpha Vault: Pro rata mode)
  • Code Examples
  • 1. Main Steps
  • 2. Create Permissioned Alpha Vault with Whitelist and Individual Deposit Cap
  • 3. Create Merkle Root Config
  • 4. Deposit SOL or USDC with Proof
  • 5. Configure Alpha Vault Timings
  • 6. Important Reminders
  1. INTEGRATION
  2. Alpha Vault Integration

Alpha Vault with Whitelist Setup

PreviousAlpha Vault without Whitelist SetupNextDynamic Bonding Curve (DBC) Integration

Last updated 3 days ago

Below we provide the steps to use the Alpha Vault Typescript SDK to create an Alpha Vault with Whitelist.

Permissioned Alpha Vault has whitelist and individual deposit cap, so only whitelisted addresses can deposit into the vault, up to the deposit cap defined for the wallet.

To use the following Alpha Vault SDK examples, please complete the steps listed in the first.

Example Timeline (Alpha Vault: Pro rata mode)

Code Examples

1. Main Steps

This example demonstrates how to use the permissioned Alpha Vault to achieve authorization of user deposit with whitelisted wallet and deposit cap.

  1. Update address and deposit cap. Check whitelist_wallet.csv.

  2. Create a pool with permissioned vault. Check createDynamicPoolWithPermissionedVault.ts for more details.

  3. Generate merkle tree, and create merkle root config. Check createMerkleRootConfig.ts for more details.

  4. Deposit with merkle proof. Check depositWithProof.ts for more details.

2. Create Permissioned Alpha Vault with Whitelist and Individual Deposit Cap

This example shows how to create a Dynamic AMM Pool with permissioned Alpha Vault (that has a whitelist and deposit cap)

  • Please contact the Meteora team if the existing pool and Alpha Vault config don't meet your requirements.

  • Currently only Dynamic AMM Pool support permissioned Alpha Vault with whitelist and deposit cap.

  • Currently, only SOL or USDC is accepted as the quote token when initializing a Dynamic AMM or DLMM Pool with Alpha Vault in a permissionless setup. Since the Alpha Vault can't tell what the quote token would be, the quote token is limited to SOL or USDC.

import {
  clusterApiUrl,
  Connection,
  Keypair,
  PublicKey,
  sendAndConfirmTransaction,
  SYSVAR_CLOCK_PUBKEY,
} from "@solana/web3.js";
import AlphaVault, { DYNAMIC_AMM_PROGRAM_ID, PoolType, VaultMode } from "../..";
import DynamicAmm from "@mercurial-finance/dynamic-amm-sdk";
import {
  ActivationType,
  Clock,
  ClockLayout,
  createTokenAndMint,
  loadKeypairFromFile,
} from "../utils";
import dotenv from "dotenv";
import { BN } from "bn.js";
import { derivePoolAddressWithConfig } from "@mercurial-finance/dynamic-amm-sdk/dist/cjs/src/amm/utils";

dotenv.config();

async function createDummyMints(connection: Connection, payer: Keypair) {
  console.log("Creating mint A");
  const mintAInfo = await createTokenAndMint(
    connection,
    payer,
    6,
    100_000_000_000
  );

  console.log("Creating mint B");
  const mintBInfo = await createTokenAndMint(
    connection,
    payer,
    6,
    100_000_000_000
  );

  return {
    mintAInfo,
    mintBInfo,
  };
}

/**
 *
 * @param connection
 * @param creator
 * @param activationType Pool activation based on time or slot
 * @param maximumActivationDuration Maximum duration for pool to be activation after creation
 * @param minimumLockDuration Minimum duration for bought token be locked
 * @param maximumLockDuration Maximum duration for bought token to be locked
 * @param minimumVestingDuration Minimum duration for bought token to be vested
 * @param maximumVestingDuration Maximum duration for bought token be vested
 * @param vaultMode Vault mode: fcfs or prorata
 */
async function getPoolConfigByRequirement(
  connection: Connection,
  creator: PublicKey,
  activationType: ActivationType,
  maximumActivationDuration: number,
  minimumLockDuration: number,
  maximumLockDuration: number,
  minimumVestingDuration: number,
  maximumVestingDuration: number,
  vaultMode: VaultMode
) {
  // 1. Pool configs that can be used by anyone to create pool
  const publicPoolConfigs =
    await DynamicAmm.getPoolConfigsWithPoolCreatorAuthority(
      connection,
      PublicKey.default
    );

  // 2. Pool configs that can only be used by specific pubkey to create pool
  const creatorPoolConfigs =
    await DynamicAmm.getPoolConfigsWithPoolCreatorAuthority(
      connection,
      creator
    );

  // 3. Look for pool configs that have vault support
  const poolConfigsWithVaultSupport = [
    ...publicPoolConfigs,
    ...creatorPoolConfigs,
  ].filter((config) => config.account.vaultConfigKey != PublicKey.default);

  console.log(
    `Gotten ${poolConfigsWithVaultSupport.length} usable pool configs with vault support`
  );

  const configFuture =
    vaultMode === VaultMode.FCFS
      ? AlphaVault.getFcfsConfigs(connection)
      : AlphaVault.getProrataConfigs(connection);

  const configs = await configFuture;

  for (const programAccount of poolConfigsWithVaultSupport) {
    const { account } = programAccount;
    // 3.1 Pool activation type and duration matches
    if (
      account.activationType == activationType &&
      account.activationDuration.toNumber() >= maximumActivationDuration
    ) {
      const vaultConfig = configs.find((c) =>
        c.publicKey.equals(account.vaultConfigKey)
      );

      if (!vaultConfig) {
        continue;
      }

      const startVestingDuration =
        vaultConfig.account.startVestingDuration.toNumber();
      const endVestingDuration =
        vaultConfig.account.endVestingDuration.toNumber();

      const vestingDuration = endVestingDuration - startVestingDuration;

      // 3.2 Vault activation type, lock and vesting duration matches
      if (
        startVestingDuration >= minimumLockDuration &&
        startVestingDuration <= maximumLockDuration &&
        vestingDuration >= minimumVestingDuration &&
        vestingDuration <= maximumVestingDuration &&
        vaultConfig.account.activationType == activationType
      ) {
        return programAccount;
      }
    }
  }

  return null;
}

async function createDynamicPoolWithPermissionedVault(
  connection: Connection,
  payer: Keypair
) {
  const { mintAInfo, mintBInfo } = await createDummyMints(connection, payer);

  // Pool and vault requirement
  const maximumActivationDuration = 86400; // 1 day
  const minimumLockDuration = 60 * 30; // 30 minutes
  const maximumLockDuration = 86400; // 1 day
  const minimumVestingDuration = 60 * 60; // 1 hour
  const maximumVestingDuration = 60 * 60 * 24 * 7; // 1 week
  const vaultMode = VaultMode.PRORATA;

  // 1.Find pool config where it allow user to create pool with customizable start trading time which start from NOW -> NOW + 24H
  // With lock duration fall between 30 minutes -> 1 days (non customizable)
  // And vesting duration fall between 1 hour -> 1 week (non customizable)
  // And prorata vault
  const poolConfig = await getPoolConfigByRequirement(
    connection,
    payer.publicKey,
    ActivationType.Timestamp,
    maximumActivationDuration,
    minimumLockDuration,
    maximumLockDuration,
    minimumVestingDuration,
    maximumVestingDuration,
    vaultMode
  );

  console.log("Got pool config");
  console.log(poolConfig);

  const clockAccount = await connection.getAccountInfo(SYSVAR_CLOCK_PUBKEY);
  const clock: Clock = ClockLayout.decode(clockAccount.data);

  // Pool start trade after created for 5 hour
  const activationPoint = clock.unixTimestamp.add(new BN(3600 * 5));

  // 2. Create the pool
  const transactions =
    await DynamicAmm.createPermissionlessConstantProductPoolWithConfig2(
      connection,
      payer.publicKey,
      mintAInfo.mint,
      mintBInfo.mint,
      new BN(100_000_000),
      new BN(100_000_000),
      poolConfig.publicKey,
      {
        activationPoint,
      }
    );

  console.log("Creating pool");
  for (const tx of transactions) {
    const txHash = await sendAndConfirmTransaction(connection, tx, [payer]);
    console.log(txHash);
  }

  const poolPubkey = derivePoolAddressWithConfig(
    mintAInfo.mint,
    mintBInfo.mint,
    poolConfig.publicKey,
    DYNAMIC_AMM_PROGRAM_ID
  );

  console.log("Pool created", poolPubkey.toBase58());

  // 3. Create the alpha vault
  const initPermissionlessVaultTx = await AlphaVault.createPermissionedVault(
    connection,
    {
      baseMint: mintAInfo.mint,
      quoteMint: mintBInfo.mint,
      poolType: PoolType.DYNAMIC,
      vaultMode: VaultMode.PRORATA,
      poolAddress: poolPubkey,
      config: poolConfig.account.vaultConfigKey,
    },
    payer.publicKey
  );

  console.log("Creating vault");
  const txHash = await sendAndConfirmTransaction(
    connection,
    initPermissionlessVaultTx,
    [payer]
  );
  console.log(txHash);
}

const connection = new Connection(clusterApiUrl("devnet"));
const payer = loadKeypairFromFile(process.env.KEYPAIR_PATH);

/**
 * This example shows how to create dynamic pool with permissioned vault
 * Please contact meteora team if the existing pool and vault config doesn't meet the requirement
 * Currently only dynamic pool support permissioned vault
 */
createDynamicPoolWithPermissionedVault(connection, payer)
  .then(() => {
    console.log("Done");
  })
  .catch(console.error);

Whitelisted wallet csv file Example

Whitelist modes

  • Without Whitelist

    • Permissionless: No whitelist, anyone can deposit into the Alpha Vault

  • With Whitelist

    • PermissionWithAuthority : In this mode, only the Alpha Vault creator can create escrow account with max_cap. This allows the creator to easily use a permissioned (with whitelist) setup without having to use the merkle tree. Creator needs to pay SOL rent for each escrow account for the whitelisted wallets, so this Alpha Vault whitelist mode is suitable for scenarios where there are very few whitelisted addresses (e.g. =<100). If they need to support a lot more whitelisted addresses, they should still use the merkle tree (PermissionWithMerkleProof whitelist mode).

3. Create Merkle Root Config

This example shows how to create a merkle root config after generating a merkle tree, which is required to verify the whitelisted wallet address data, and enable deposits by whitelisted wallets.

import {
  clusterApiUrl,
  Connection,
  Keypair,
  PublicKey,
  sendAndConfirmTransaction,
} from "@solana/web3.js";
import { loadKeypairFromFile } from "../utils";
import { AlphaVault } from "../../alpha-vault";
import dotenv from "dotenv";
import { createMerkleTree, loadWhitelistWalletCsv } from "./utils";
import { BN } from "bn.js";

dotenv.config();

async function createMerkleRootConfig(
  vault: PublicKey,
  csvPath: string,
  payer: Keypair
) {
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
  const alphaVault = await AlphaVault.create(connection, vault);

  // 1. Load whitelist wallet from csv file
  const whitelistWallets = await loadWhitelistWalletCsv(csvPath);
  console.log("Loaded whitelist wallets");
  console.log(whitelistWallets);

  // 2. Create merkle tree
  const tree = await createMerkleTree(connection, alphaVault, whitelistWallets);

  // 3. Create merkle root config
  // If the tree grew too large, one can partition it into multiple tree by setting different version
  const version = new BN(0);
  const createMerkleRootConfigTx = await alphaVault.createMerkleRootConfig(
    tree.getRoot(),
    version,
    payer.publicKey
  );

  // 4. Send transaction
  console.log("Sending transaction");
  const txHash = await sendAndConfirmTransaction(
    connection,
    createMerkleRootConfigTx,
    [payer]
  );
  console.log(txHash);
}

// Permissioned alpha vault
const vault = new PublicKey("ARGqVVUPPqtqH9UeBHvYsv7AtZv623YdEaEziZ1pdDUs");
const payer = loadKeypairFromFile(process.env.KEYPAIR_PATH);
const whitelistWalletCsvFilepath =
  "src/examples/permissioned/whitelist_wallet.csv";

/**
 * This example shows how to close an escrow account and get rental back. Close escrow can only happen after vesting is complete, and escrow have claimed all the bought token.
 */
createMerkleRootConfig(vault, whitelistWalletCsvFilepath, payer)
  .then(() => {
    console.log("Done");
  })
  .catch(console.error);

4. Deposit SOL or USDC with Proof

This example shows how to deposit into a permissioned alpha vault using a whitelisted wallet. Deposit can only happen before the end of the deposit period.

import {
  clusterApiUrl,
  Connection,
  Keypair,
  PublicKey,
  sendAndConfirmTransaction,
} from "@solana/web3.js";
import { loadKeypairFromFile } from "../utils";
import { AlphaVault } from "../../alpha-vault";
import BN from "bn.js";
import dotenv from "dotenv";
import Decimal from "decimal.js";
import { deriveMerkleRootConfig } from "../../alpha-vault/helper";
import { createMerkleTree, loadWhitelistWalletCsv } from "./utils";
import { PROGRAM_ID } from "../../alpha-vault/constant";

dotenv.config();

async function depositToPermissionedAlphaVault(
  vault: PublicKey,
  depositAmount: BN,
  csvPath: string,
  payer: Keypair
) {
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
  const alphaVault = await AlphaVault.create(connection, vault);

  // 1. Load whitelisted wallet
  const whitelistedWallets = await loadWhitelistWalletCsv(csvPath);

  // 2. Create merkle tree
  const tree = await createMerkleTree(
    connection,
    alphaVault,
    whitelistedWallets
  );

  // 3. Get wallet proof info
  const depositorWhitelistInfo = whitelistedWallets.find((w) =>
    w.wallet.equals(payer.publicKey)
  );
  const quoteMint = await connection.getTokenSupply(alphaVault.vault.quoteMint);
  const toNativeAmountMultiplier = new Decimal(10 ** quoteMint.value.decimals);

  const nativeDepositCap = new BN(
    depositorWhitelistInfo.depositCap.mul(toNativeAmountMultiplier).toString()
  );

  const depositorProof = tree
    .getProof(payer.publicKey, nativeDepositCap)
    .map((buffer) => {
      return Array.from(new Uint8Array(buffer));
    });

  const [merkleRootConfig] = deriveMerkleRootConfig(
    alphaVault.pubkey,
    new BN(0),
    new PublicKey(PROGRAM_ID["mainnet-beta"])
  );

  // 4. Deposit
  const depositTx = await alphaVault.deposit(depositAmount, payer.publicKey, {
    merkleRootConfig,
    maxCap: nativeDepositCap,
    proof: depositorProof,
  });

  console.log(`Depositing ${depositAmount.toString()}`);
  const txHash = await sendAndConfirmTransaction(connection, depositTx, [
    payer,
  ]);
  console.log(txHash);

  const escrow = await alphaVault.getEscrow(payer.publicKey);
  console.log("Escrow info");
  console.log(escrow);
}

// Alpha vault to be deposited to
const vault = new PublicKey("ARGqVVUPPqtqH9UeBHvYsv7AtZv623YdEaEziZ1pdDUs");
const depositAmount = new BN(100_000);
const payer = loadKeypairFromFile(process.env.KEYPAIR_PATH);
const whitelistWalletCsvFilepath =
  "src/examples/permissioned/whitelist_wallet.csv";

/**
 * This example shows how to deposit to permissioned alpha vault. Deposit can only happen before the deposit close.
 */
depositToPermissionedAlphaVault(
  vault,
  depositAmount,
  whitelistWalletCsvFilepath,
  payer
)
  .then(() => {
    console.log("Done");
  })
  .catch(console.error);

5. Configure Alpha Vault Timings

If you are integrating the Alpha Vault program and need to view and select the predefined timings for the various phases, such as:

  • Deposit open time (only for FCFS mode currently)

  • Deposit close time

  • Vault crank/buy start time

  • Vault crank/buy end time

  • Withdraw unused USDC or SOL after crank is successful

  • Pool Activation time

  • Token claim start time

  • Vesting start time

  • Vesting end time

Note: There is a minimum ~1 hour 5 minutes period between the deposit close time and the pool activation time.

You can use this config endpoint that has predefined timings created by Meteora.

If your preferred configs are not available in the predefined config lists above, and you want more customization, please contact the Meteora team.

Config endpoint is based on Pool Activation Timing

The above config endpoint is tied to the pool activation timing, so all timings for the different Alpha Vault phases is derived from the pool activation timing.

In this example below, the claim process will start 3600 seconds (1 hour) after pool activation, and it will end 7200 seconds (2 hours) after pool activation. In other words, after the pool starts trading, tokens are locked first and released for claiming 3600 seconds (1 hour) later.

{
  maxBuyingCap: new BN(10000000),
  index,
  startVestingDuration: new BN(3600),
  endVestingDuration: new BN(7200),
  escrowFee: new BN(0),
  individualDepositingCap: new BN(50000),
  activationType: ActivationType.TIMESTAMP,
  depositingPoint: new BN(1028979080),
}

6. Important Reminders

A) Claim start time should NOT be earlier than Pool activation time

For a new token launch, the project should ensure that token claiming from the Alpha Vault is NOT possible before the launch pool trading activation or before the token starts trading anywhere, whether on a Dynamic AMM or DLMM Pool. If users are able to claim tokens before the launch pool/token starts trading, they may create a separate market with a price that deviates from the project's preferred launch price.

B) For Memecoins that want to permanently lock liquidity, lock it before Pool activation time

If the Alpha Vault is used for a Memecoin launch pool, and the project wants to permanently lock liquidity in the Memecoin pool, they should ideally lock the liquidity BEFORE the pool starts trading, so that swap fees from locked liquidity are captured the second trading starts.

In a scenario where:

  • The pool started trading - t0

  • Liquidity gets deposited to the pool by the project, but not locked - t1

  • Subsequently, that liquidity is permanently locked by the project - t2

The project will not be able to claim swap fees earned from t1 to t2, since fees from t1 to t2 are assigned to the LP token before the LP token gets permanently locked. When the LP token gets locked, the earlier fees are locked along with it.

The project will only be able to claim swap fees from locked liquidity starting from t2.

C) Quote token must be SOL or USDC

Only SOL or USDC is accepted as the quote token when initializing a Dynamic AMM or DLMM Pool with Alpha Vault.

D) If no vesting is required, what should the startVestingPoint and endVestingPoint be?

  • startVestingPoint: Absolute value, the slot or timestamp that start vesting depend on the pool activation type. If no vesting is required, you should put this as 1 sec after the pool's activationPoint

  • endVestingPoint: Absolute value, the slot or timestamp that end vesting depend on the pool activation type. If no vesting is required, this should be the same as startVestingPoint

E) How to crank the Alpha Vault so that it purchases the token from the pool?

  • Typically, we have a keeper that cranks the Alpha Vault to automatically purchase tokens from the pool.

PermissionWithMerkleProof : In this mode, only wallets that are whitelisted can deposit into the Alpha Vault. needs to be provided by the project to Meteora, for the Merkle proof to be hosted by Meteora. Alpha Vault deposits should not open until the Merkle proof is hosted by Meteora.

Pool config list:

Vault config list:

However, if the auto-crank fails, you can visit this fillVaultDlmm.ts repo and input your Publickey

Main Steps
Create Permissioned Alpha Vault with Whitelist and Individual Deposit Cap
Create Merkle Root Config
Deposit SOL or USDC with Proof
Configure Alpha Vault Timings
Important Reminders
https://github.com/MeteoraAg/alpha-vault-sdk/blob/main/ts-client/src/examples/permissioned/whitelist_wallet.csv?plain=1
Csv file containing the list of whitelisted wallets
https://amm-v2.meteora.ag/swagger-ui/#/pools/get_all_pool_configs
https://amm-v2.meteora.ag/swagger-ui/#/alpha_vault_config/get_all
https://github.com/MeteoraAg/alpha-vault-sdk/blob/main/ts-client/src/examples/fillVaultDlmm.ts
Alpha Vault SDK section