> ## Documentation Index
> Fetch the complete documentation index at: https://docs.decibel.trade/llms.txt
> Use this file to discover all available pages before exploring further.

# Vault Integration Guide

> Create and manage onchain vaults that pool capital under a single manager with interval-based performance fees and fungible share tokens.

Vaults are onchain smart contracts that let you run a trading strategy with pooled capital. Contributors deposit USDC and receive fungible share tokens representing their claim on vault assets. You trade with the pooled funds and earn performance fees on profitable intervals.

<Note>
  For how vaults work from a contributor's perspective, see [Vaults](/for-traders/vaults). For the protocol-owned liquidity vault, see [DLP Vault](/for-traders/dlp-vault).
</Note>

This guide walks you through creating a vault on testnet, funding it with USDC, and activating it for contributions. It then covers how vaults work under the hood (lifecycle, fees, shares) and advanced operations like contributing to existing vaults, redeeming shares, and delegating trading permissions.

<Info>
  **TypeScript** examples use the [Decibel TypeScript SDK](/typescript-sdk/write-sdk) (`DecibelWriteDex` / `DecibelReadDex`). **Python** examples still use `aptos-sdk` with on-chain entry functions and will be updated in a follow-up.
</Info>

<Info>
  **Testnet funding (Aptos testnet)** — To run the full Part 1 flow (create, contribute, redeem), keep about **210 USDC** in your primary Trading Account (subaccount), in chain units (6 decimals):

  | Item                                          | Chain units   | USDC        |
  | --------------------------------------------- | ------------- | ----------- |
  | Vault creation fee (deducted from subaccount) | `100_000_000` | \$100       |
  | `initialFunding` (min activation)             | `100_000_000` | \$100       |
  | Optional `depositToVault` (min contribution)  | `10_000_000`  | \$10        |
  | **Suggested subaccount total**                | `210_000_000` | **\~\$210** |

  The creation fee and `initialFunding` are **separate** debits from subaccount collateral.

  Reference implementation: [`typescript/packages/e2e/src/vault-e2e.ts`](https://github.com/aptos-labs/etna/blob/main/typescript/packages/e2e/src/vault-e2e.ts). Run `cd typescript/packages/e2e && pnpm start:vault-e2e` (see `.env.example` for `PRIVATE_KEY` and `API_KEY`; `NEXT_PUBLIC_GAS_STATION_API_KEY` is only required for that smoke script, not for a typical integration).
</Info>

<CardGroup cols={1} className="max-w-3xl mx-auto my-6">
  <Card title="Part 1: Launch Your First Vault" icon="zap" href="#part-1">
    Fund your account, create a vault on testnet, and activate it.
  </Card>

  <Card title="Part 2: How Vaults Work" icon="brain" href="#part-2">
    Lifecycle, fees, shares, and parameters.
  </Card>

  <Card title="Part 3: Advanced Operations" icon="gear" href="#part-3">
    Contributing, redeeming, querying, and delegation.
  </Card>
</CardGroup>

<a id="part-1" />

## Part 1: Launch Your First Vault

<Info>
  You can also create and manage vaults through the [Decibel UI](https://app.decibel.trade/accounts) without writing any code. Navigate to Accounts, then click the Vaults tab and "Create Vault." This guide covers the programmatic approach.
</Info>

### 1. Prerequisites

* [Node.js](https://nodejs.org/) 18+ (TypeScript), or Python 3.8+ (Python examples)
* An API Wallet with its private key (create one at [app.decibel.trade/api](https://app.decibel.trade/api))
* An API Key (Bearer Token) from [Geomi](https://geomi.dev) (see [Get API Keys](/quickstart/node-api-key))
* Testnet APT for gas fees: paste your API Wallet address into the [Aptos Testnet Faucet](https://aptos.dev/network/faucet). This is your wallet address, not your Trading Account (subaccount) address.

<Note>
  **Gas (choose one)** — **Default:** pay gas with testnet APT from the faucet above. **Optional:** set `gasStationApiKey` on `DecibelConfig` to sponsor gas via [Geomi Gas Station](/quickstart/gas-station) (see [SDK configuration](/typescript-sdk/configuration)). Vault integrations do **not** require Gas Station; the repo's `vault-e2e` script uses it only for convenience on testnet.
</Note>

### 2. Install Dependencies

<CodeGroup>
  ```bash TypeScript theme={null}
  npm install @decibeltrade/sdk @aptos-labs/ts-sdk
  ```

  ```bash Python theme={null}
  pip install aptos-sdk
  ```
</CodeGroup>

`@aptos-labs/ts-sdk` is a peer dependency for `Ed25519Account` signing (same as the [Write SDK](/typescript-sdk/write-sdk) setup).

### 3. Set Up Your Script

TypeScript examples use `DecibelWriteDex` / `DecibelReadDex`. Python examples use `aptos-sdk` with the testnet package address below.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { AccountAddress, Ed25519Account, Ed25519PrivateKey } from "@aptos-labs/ts-sdk";
  import {
    DecibelReadDex,
    DecibelWriteDex,
    extractVaultAddressFromCreateTx,
    getPrimarySubaccountAddr,
    TESTNET_CONFIG,
    TimeInForce,
  } from "@decibeltrade/sdk";

  const account = new Ed25519Account({
    privateKey: new Ed25519PrivateKey(process.env.PRIVATE_KEY!),
  });

  const read = new DecibelReadDex(TESTNET_CONFIG, {
    nodeApiKey: process.env.APTOS_NODE_API_KEY!,
  });

  const write = new DecibelWriteDex(TESTNET_CONFIG, account, {
    nodeApiKey: process.env.APTOS_NODE_API_KEY!,
  });
  ```

  ```python Python theme={null}
  from aptos_sdk.account import Account
  from aptos_sdk.account_address import AccountAddress
  from aptos_sdk.async_client import RestClient
  from aptos_sdk.bcs import Serializer
  from aptos_sdk.transactions import (
      EntryFunction,
      TransactionArgument,
      TransactionPayload,
  )
  import asyncio
  import json

  PACKAGE = "0xe7da2794b1d8af76532ed95f38bfdf1136abfd8ea3a240189971988a83101b7f"
  NODE_URL = "https://api.testnet.aptoslabs.com/v1"

  client = RestClient(NODE_URL)
  account = Account.load_key("0xYOUR_PRIVATE_KEY")
  ```
</CodeGroup>

### 4. Get Your Trading Account Address

Your Trading Account (subaccount) holds USDC collateral used to fund a vault.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const primarySubaccount = write.getPrimarySubaccountAddress(account.accountAddress);
  console.log("Primary subaccount:", primarySubaccount);
  ```

  ```python Python theme={null}
  result = await client.view(
      f"{PACKAGE}::dex_accounts::primary_subaccount",
      [],
      [str(account.address())],
  )
  primary_subaccount = json.loads(result)[0]
  print("Primary subaccount:", primary_subaccount)
  ```
</CodeGroup>

<Note>
  The primary subaccount is auto-created on your first deposit. You don't need to create it manually.
</Note>

### 5. Mint Testnet USDC

On testnet, mint USDC with `restricted_mint` (rate-limited per account). For the full Part 1 walkthrough, plan for **\~210 USDC** in your subaccount (see the funding table above). If mint allowance is exhausted, fund via the [Decibel UI](https://app.decibel.trade) or `write.deposit` from your wallet.

<Tabs>
  <Tab title="Pay own gas (default)">
    Use this when `gasStationApiKey` is **not** set on your SDK config (same as testnet APT from step 1).

    ```typescript theme={null}
    const mintTx = await write.aptos.transaction.build.simple({
      sender: account.accountAddress,
      data: {
        function: `${write.config.deployment.package}::usdc::restricted_mint`,
        typeArguments: [],
        functionArguments: [500_000_000], // 500 USDC (6 decimals)
      },
    });
    const mintResult = await write.aptos.signAndSubmitTransaction({
      signer: account,
      transaction: mintTx,
    });
    await write.aptos.waitForTransaction({ transactionHash: mintResult.hash });
    console.log("Minted USDC:", mintResult.hash);
    ```
  </Tab>

  <Tab title="With Gas Station (optional)">
    Use this only when `gasStationApiKey` is set (matches `vault-e2e.ts` on testnet).

    ```typescript theme={null}
    const tx = await write.buildTx(
      {
        function: `${write.config.deployment.package}::usdc::restricted_mint`,
        typeArguments: [],
        functionArguments: [500_000_000],
      },
      account.accountAddress,
    );
    const auth = write.aptos.sign({ signer: account, transaction: tx });
    const pending = await write.submitTx(tx, auth);
    await write.aptos.waitForTransaction({ transactionHash: pending.hash });
    console.log("Minted USDC:", pending.hash);
    ```
  </Tab>
</Tabs>

<Warning>
  If `gasStationApiKey` is set, do **not** use `aptos.transaction.build.simple` for custom Move calls like `restricted_mint` — submission will fail with *Transaction must have a fee payer*. Use the Gas Station tab above, or omit `gasStationApiKey` and pay gas with APT.
</Warning>

<CodeGroup>
  ```python Python theme={null}
  payload = EntryFunction.natural(
      f"{PACKAGE}::usdc",
      "restricted_mint",
      [],
      [TransactionArgument(500_000_000, Serializer.u64)],
  )
  signed_txn = await client.create_bcs_signed_transaction(
      account, TransactionPayload(payload)
  )
  txn = await client.submit_and_wait_for_bcs_transaction(signed_txn)
  print("Minted USDC:", txn["hash"])
  ```
</CodeGroup>

<Note>
  Alternatively, fund your wallet with testnet USDC through the [Decibel UI](https://app.decibel.trade) and skip minting. On Python, creation fees and minimums depend on your target network's on-chain config.
</Note>

### 6. Deposit USDC to Your Trading Account

Move USDC from your wallet into your Trading Account so it can be used as vault capital. Use at least **`210_000_000`** chain units (\~210 USDC) to cover the testnet creation fee, minimum `initialFunding`, and a follow-on contribution:

<CodeGroup>
  ```typescript TypeScript theme={null}
  await write.deposit(210_000_000, primarySubaccount); // ~210 USDC (6 decimals)
  console.log("Deposited USDC to subaccount");
  ```

  ```python Python theme={null}
  usdc_metadata = AccountAddress.from_str(
      # Derive USDC metadata: createObjectAddress(PACKAGE, "USDC")
      "0xbdabb88aa9a875f3a2ebe0974e24f3ae5e57cfd17c6abdfef8a8111f43681b7e"
  )

  payload = EntryFunction.natural(
      f"{PACKAGE}::dex_accounts_entry",
      "deposit_to_subaccount_at",
      [],
      [
          TransactionArgument(AccountAddress.from_str(primary_subaccount), Serializer.struct),
          TransactionArgument(usdc_metadata, Serializer.struct),
          TransactionArgument(210_000_000, Serializer.u64),
      ],
  )
  signed_txn = await client.create_bcs_signed_transaction(
      account, TransactionPayload(payload)
  )
  txn = await client.submit_and_wait_for_bcs_transaction(signed_txn)
  print("Deposited USDC:", txn["hash"])
  ```
</CodeGroup>

This USDC stays in your **primary subaccount** until create debits the creation fee and `initialFunding`.

### 7. Create and Fund Your Vault

Create a vault and deposit initial capital from your Trading Account. On Aptos testnet, a **\$100 creation fee** (`100_000_000` chain units) is debited from subaccount collateral in addition to `initialFunding`. With `initialFunding` of at least `100_000_000` (100 USDC, 6 decimals), the vault activates automatically. The example below uses `200_000_000` for headroom above the minimum.

<CodeGroup>
  ```typescript TypeScript theme={null}
  const createTx = await write.createVault({
    subaccountAddr: primarySubaccount,
    contributionAssetType: write.config.deployment.usdc,
    vaultName: "My Trading Vault",
    vaultDescription: "Algorithmic strategy",
    vaultSocialLinks: ["https://x.com/myvault", ""],
    vaultShareSymbol: "MTV",
    feeBps: 500, // 5% performance fee
    feeIntervalS: 2_592_000, // 30 days
    contributionLockupDurationS: 0,
    initialFunding: 200_000_000, // 200 USDC
    acceptsContributions: true,
    delegateToCreator: true, // grants your wallet trading permissions on the vault
  });

  const vaultAddress = extractVaultAddressFromCreateTx(createTx);
  console.log("Vault created:", vaultAddress);
  ```

  ```python Python theme={null}
  payload = EntryFunction.natural(
      f"{PACKAGE}::vault_api",
      "create_and_fund_vault",
      [],
      [
          TransactionArgument(AccountAddress.from_str(primary_subaccount), Serializer.struct),
          TransactionArgument(usdc_metadata, Serializer.struct),
          TransactionArgument("My Trading Vault", Serializer.str),
          TransactionArgument("Algorithmic strategy", Serializer.str),
          TransactionArgument(["https://x.com/myvault", ""],
                              lambda s, v: s.sequence(v, Serializer.str)),
          TransactionArgument("MTV", Serializer.str),
          TransactionArgument("", Serializer.str),
          TransactionArgument("", Serializer.str),
          TransactionArgument(500, Serializer.u64),
          TransactionArgument(2592000, Serializer.u64),
          TransactionArgument(0, Serializer.u64),
          TransactionArgument(200_000_000, Serializer.u64),
          TransactionArgument(True, Serializer.bool),
          TransactionArgument(True, Serializer.bool),
      ],
  )
  signed_txn = await client.create_bcs_signed_transaction(
      account, TransactionPayload(payload)
  )
  txn = await client.submit_and_wait_for_bcs_transaction(signed_txn)
  print("Vault created:", txn["hash"])
  ```
</CodeGroup>

<Note>
  `delegateToCreator: true` grants your account permission to trade on the vault. If you set it to `false`, delegate separately in step 9 (equivalent to the repo's `vault-e2e.ts`, which uses `delegateToCreator: false` then delegates in step 9).
</Note>

For full parameter details, see [Create and Fund Vault](/developer-hub/on-chain/vault/create-and-fund).

### 8. Activate the Vault (if needed)

If `initialFunding` was at least 100 USDC (6 decimals), skip this step. Otherwise activate after funding to the minimum:

<Tabs>
  <Tab title="Pay own gas (default)">
    ```typescript theme={null}
    const activateTx = await write.buildActivateVaultTx({
      vaultAddress,
      signerAddress: account.accountAddress,
    });
    const activateResult = await write.aptos.signAndSubmitTransaction({
      signer: account,
      transaction: activateTx,
    });
    await write.aptos.waitForTransaction({ transactionHash: activateResult.hash });
    console.log("Vault activated:", activateResult.hash);
    ```
  </Tab>

  <Tab title="With Gas Station (optional)">
    ```typescript theme={null}
    const activateTx = await write.buildActivateVaultTx({
      vaultAddress,
      signerAddress: account.accountAddress,
    });
    const auth = write.aptos.sign({ signer: account, transaction: activateTx });
    const pending = await write.submitTx(activateTx, auth);
    await write.aptos.waitForTransaction({ transactionHash: pending.hash });
    console.log("Vault activated:", pending.hash);
    ```
  </Tab>
</Tabs>

<CodeGroup>
  ```python Python theme={null}
  payload = EntryFunction.natural(
      f"{PACKAGE}::vault_api",
      "activate_vault",
      [],
      [TransactionArgument(AccountAddress.from_str(vault_address), Serializer.struct)],
  )
  signed_txn = await client.create_bcs_signed_transaction(
      account, TransactionPayload(payload)
  )
  txn = await client.submit_and_wait_for_bcs_transaction(signed_txn)
  print("Vault activated:", txn["hash"])
  ```
</CodeGroup>

For full parameter details, see [Activate Vault](/developer-hub/on-chain/vault/activate).

### 9. Delegate Trading (optional)

Skip this step if you set `delegateToCreator: true` in step 7. To grant trading permissions to another address (e.g. a bot wallet):

<Tabs>
  <Tab title="Pay own gas (default)">
    ```typescript theme={null}
    const delegateTx = await write.buildDelegateDexActionsToTx({
      vaultAddress,
      accountToDelegateTo: botWalletAddress,
      signerAddress: account.accountAddress,
    });
    const delegateResult = await write.aptos.signAndSubmitTransaction({
      signer: account,
      transaction: delegateTx,
    });
    await write.aptos.waitForTransaction({ transactionHash: delegateResult.hash });
    console.log("Delegated trading:", delegateResult.hash);
    ```
  </Tab>

  <Tab title="With Gas Station (optional)">
    ```typescript theme={null}
    const delegateBuilt = await write.buildDelegateDexActionsToTx({
      vaultAddress,
      accountToDelegateTo: botWalletAddress,
      signerAddress: account.accountAddress,
    });
    const delegateAuth = write.aptos.sign({ signer: account, transaction: delegateBuilt });
    const delegatePending = await write.submitTx(delegateBuilt, delegateAuth);
    await write.aptos.waitForTransaction({ transactionHash: delegatePending.hash });
    console.log("Delegated trading:", delegatePending.hash);
    ```
  </Tab>
</Tabs>

<CodeGroup>
  ```python Python theme={null}
  def serialize_option_u64(ser, val):
      """Serialize an optional u64: None = empty option, int = some(value)"""
      if val is None:
          ser.u8(0)  # None variant
      else:
          ser.u8(1)  # Some variant
          ser.u64(val)

  payload = EntryFunction.natural(
      f"{PACKAGE}::vault_admin_api",
      "delegate_dex_actions_to",
      [],
      [
          TransactionArgument(AccountAddress.from_str(vault_address), Serializer.struct),
          TransactionArgument(AccountAddress.from_str(bot_wallet_address), Serializer.struct),
          TransactionArgument(None, serialize_option_u64),  # No expiration
      ],
  )
  signed_txn = await client.create_bcs_signed_transaction(
      account, TransactionPayload(payload)
  )
  txn = await client.submit_and_wait_for_bcs_transaction(signed_txn)
  print("Delegated trading:", txn["hash"])
  ```
</CodeGroup>

For full parameter details, see [Delegate DEX Actions](/developer-hub/on-chain/vault/delegate-dex-actions).

### 10. Place an Order as the Vault

Vault trading uses the same `placeOrder` API as a normal Trading Account. The difference is the `subaccountAddr`: pass the vault's portfolio subaccount (derived from the vault object address), not your wallet's primary subaccount. You must have delegated trading first (`delegateToCreator: true` in step 7, or step 9). Use a market that exists on your network (this example uses `APT/USD`).

<CodeGroup>
  ```typescript TypeScript theme={null}
  const vaultSubaccount = getPrimarySubaccountAddr(
    AccountAddress.fromString(vaultAddress),
    write.config.compatVersion,
    write.config.deployment.package,
  );

  const markets = await read.markets.getAll();
  const marketPrices = await read.marketPrices.getAll();
  const market = markets.find((m) => m.market_name === "APT/USD"); // use a live market on your network
  if (!market) throw new Error("Market not found");

  const midPx = marketPrices.find((p) => p.market === market.market_addr)?.mid_px;
  if (midPx == null) throw new Error("No mid price for market");

  // Convert human-readable amounts to chain units — see formatting guide
  function amountToChainUnits(amount: number, decimals: number) {
    return Math.floor(amount * 10 ** decimals);
  }

  const orderResult = await write.placeOrder({
    marketName: market.market_name,
    price: amountToChainUnits(midPx, market.px_decimals),
    size: market.min_size,
    isBuy: true,
    timeInForce: TimeInForce.ImmediateOrCancel,
    isReduceOnly: false,
    subaccountAddr: vaultSubaccount,
    tickSize: market.tick_size,
  });

  if (orderResult.success) {
    console.log("Vault order placed:", orderResult.transactionHash);
  } else {
    console.error("Order failed:", orderResult.error);
  }
  ```

  ```python Python theme={null}
  # Use the on-chain place_order_to_subaccount flow with the vault portfolio subaccount.
  # See /developer-hub/on-chain/order-management/place-order
  ```
</CodeGroup>

See [Write SDK — Trading on behalf of a vault](/typescript-sdk/write-sdk#trading-on-behalf-of-a-vault) for TWAP, TP/SL, and cancellation on the vault subaccount (TypeScript).

<Check>
  Verify your vault is live. Browse to [app.decibel.trade/vaults](https://app.decibel.trade/vaults) and search for your vault name. You can also query it via the REST API to confirm it's active and accepting contributions.
</Check>

<a id="part-2" />

## Part 2: How Vaults Work

A vault pools capital under a single manager. The manager trades with the pooled funds, and profits (after fees) are distributed to all shareholders proportionally. Contributors receive fungible share tokens representing their claim on the vault's net assets. See [Vaults for Traders](/for-traders/vaults) for the full contributor perspective.

### Vault Lifecycle

| Phase          | What happens                                                                                                                    |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| Creation       | Manager creates the vault, sets fee parameters, and deposits initial capital                                                    |
| Pre-activation | Vault exists but doesn't accept contributions. Manager must fund it to the minimum (\$100)                                      |
| Activation     | Manager activates the vault (or it auto-activates if funded with >= \$100 at creation). It can now accept outside contributions |
| Active trading | Manager (or delegate) trades with pooled capital. Contributors can join or redeem                                               |
| Ongoing        | Fees are crystallized at each interval. Shares are minted/burned as contributors join/leave                                     |

### Interval-Based Performance Fees

Vaults use an interval-based fee model. There is no high watermark or cumulative tracking.

1. When a vault is created, the manager sets a fee rate (0-10%) and a fee interval (30-365 days).
2. At the end of each interval, the protocol compares the vault's current NAV to its NAV at the start of that interval.
3. If the vault profited during that interval, the manager receives their fee percentage as newly minted shares.
4. If the vault lost money or broke even, the manager receives nothing for that interval.
5. The next interval starts fresh. There is no carry-forward of losses from previous intervals.

<Warning>
  Each interval is independent. If a vault loses 20% in one interval and gains 25% in the next, the manager earns fees on the full 25% gain in the second interval, even though the vault hasn't fully recovered. This is different from a high watermark model.
</Warning>

### Key Parameters

These are the protocol-enforced limits. Vault managers choose values within these ranges at creation time.

| Parameter               | Range / Value                                         |
| ----------------------- | ----------------------------------------------------- |
| Performance fee         | 0-10% (0-1000 bps)                                    |
| Fee interval            | 30-365 days                                           |
| Min manager capital     | Lesser of 5% of vault NAV or \$100,000                |
| Min activation funding  | \$100                                                 |
| Min contribution        | \$10                                                  |
| Min redemption          | \$5                                                   |
| Max contribution lockup | 0-7 days                                              |
| Vault creation fee      | Configurable per network (**\$100 on Aptos testnet**) |

### Shares as Fungible Tokens

When you contribute to a vault, you receive fungible share tokens on Aptos. These shares are transferable, can be used as collateral in other DeFi protocols, and can be traded on secondary markets. See [Fungible Token Ownership](/for-traders/vaults#fungible-token-ownership) for details.

### Protocol Vault (DLP) vs User Vaults

Decibel runs one special vault, the [Decibel Liquidity Provider (DLP)](/for-traders/dlp-vault), alongside user-created vaults. Both use the same onchain infrastructure.

|                     | DLP Vault            | User Vaults                   |
| ------------------- | -------------------- | ----------------------------- |
| Manager             | Protocol (automated) | Any user                      |
| Strategy            | Market making        | Manager's discretion          |
| Contribution lockup | 72 hours             | 0-7 days (manager-configured) |
| Fee structure       | 0%                   | Manager-defined (0-10%)       |

<a id="part-3" />

## Part 3: Advanced Operations

### Contributing to an Existing Vault

Anyone can contribute to an active vault that accepts contributions. The minimum contribution is \$10 USDC (`10_000_000` chain units). Contributions go through your Trading Account (subaccount). After creating a vault in Part 1, an additional `depositToVault` matches the e2e smoke test's follow-on contribution step.

<CodeGroup>
  ```typescript TypeScript theme={null}
  await write.depositToVault({
    vaultAddress,
    amount: 50_000_000, // 50 USDC (6 decimals)
    subaccountAddr: primarySubaccount,
  });
  console.log("Contributed to vault");
  ```

  ```python Python theme={null}
  payload = EntryFunction.natural(
      f"{PACKAGE}::dex_accounts_entry",
      "contribute_to_vault",
      [],
      [
          TransactionArgument(AccountAddress.from_str(primary_subaccount), Serializer.struct),
          TransactionArgument(AccountAddress.from_str(vault_address), Serializer.struct),
          TransactionArgument(usdc_metadata, Serializer.struct),
          TransactionArgument(50_000_000, Serializer.u64),
      ],
  )
  signed_txn = await client.create_bcs_signed_transaction(
      account, TransactionPayload(payload)
  )
  txn = await client.submit_and_wait_for_bcs_transaction(signed_txn)
  print("Contributed to vault:", txn["hash"])
  ```
</CodeGroup>

<Warning>
  If the vault has a contribution lockup configured, you cannot redeem your shares until the lockup period expires.
</Warning>

For full parameter details, see [Contribute to Vault](/developer-hub/on-chain/vault/contribute).

### Redeeming Shares

To withdraw from a vault, redeem your share tokens for the underlying USDC. The minimum redemption is \$5 (`5_000_000` share units at 6 decimals). The protocol may close up to 10% of positions per redemption at up to 2% slippage to free capital.

Query your share balance on the **contributor subaccount** (not the wallet address), then redeem at least the minimum:

<CodeGroup>
  ```typescript TypeScript theme={null}
  const performances = await read.vaults.getUserPerformancesOnVaults({
    ownerAddr: primarySubaccount,
  });
  const shares =
    performances.find((p) => p.vault.address === vaultAddress)?.current_num_shares ?? 0;

  await write.withdrawFromVault({
    vaultAddress,
    shares: Math.max(5_000_000, Math.floor(shares * 0.1)), // partial redeem, min $5
    subaccountAddr: primarySubaccount,
  });
  console.log("Redeemed from vault");
  ```

  ```python Python theme={null}
  payload = EntryFunction.natural(
      f"{PACKAGE}::dex_accounts_entry",
      "redeem_from_vault",
      [],
      [
          TransactionArgument(AccountAddress.from_str(primary_subaccount), Serializer.struct),
          TransactionArgument(AccountAddress.from_str(vault_address), Serializer.struct),
          TransactionArgument(10_000_000, Serializer.u64),
      ],
  )
  signed_txn = await client.create_bcs_signed_transaction(
      account, TransactionPayload(payload)
  )
  txn = await client.submit_and_wait_for_bcs_transaction(signed_txn)
  print("Redeemed from vault:", txn["hash"])
  ```
</CodeGroup>

For full parameter details, see [Redeem from Vault](/developer-hub/on-chain/vault/redeem).

### Querying Vault Data

<CodeGroup>
  ```typescript TypeScript theme={null}
  const vaults = await read.vaults.getVaults({ vaultType: "user", limit: 20 });
  const owned = await read.vaults.getUserOwnedVaults({
    ownerAddr: account.accountAddress.toString(), // wallet — vaults you created
  });
  const performances = await read.vaults.getUserPerformancesOnVaults({
    ownerAddr: primarySubaccount, // subaccount — shares you hold as a contributor
  });
  const sharePrice = await read.vaults.getVaultSharePrice({ vaultAddress });
  const maxInstantRedeem = await read.vaults.getMaxSynchronousRedemption({ vaultAddress });
  ```

  ```python Python theme={null}
  # Query vault listings and performance via the REST API (see link below).
  ```
</CodeGroup>

Vault listings and performance are also available through the REST API. See [vault endpoints](/api-reference/vaults/get-account-owned-vaults).

### Trading on Behalf of a Vault

The vault manager (or any delegated account) places orders with `write.placeOrder` and `subaccountAddr` set to the vault portfolio subaccount (see [Part 1, step 10](#10-place-an-order-as-the-vault) and [Write SDK — Trading on behalf of a vault](/typescript-sdk/write-sdk#trading-on-behalf-of-a-vault)).

1. At creation: `delegateToCreator: true` grants the creator trading permissions.
2. After creation: use `buildDelegateDexActionsToTx` to delegate to a bot wallet.
3. Delegations can optionally include an expiration timestamp.
4. The vault owner can revoke delegations on-chain at any time.

The same order types as regular [Trading Accounts](/for-traders/vaults) (limit, market, TWAP, TP/SL) work when `subaccountAddr` is the vault subaccount.

## What's Next

<Steps>
  <Step title="Read the onchain reference">
    Full parameter docs for [Create and Fund](/developer-hub/on-chain/vault/create-and-fund), [Activate](/developer-hub/on-chain/vault/activate), [Contribute](/developer-hub/on-chain/vault/contribute), [Redeem](/developer-hub/on-chain/vault/redeem), and [Delegate](/developer-hub/on-chain/vault/delegate-dex-actions).
  </Step>

  <Step title="Understand vault fees and mechanics">
    See [Vaults for Traders](/for-traders/vaults) for the contributor perspective and [Fees](/for-traders/fees) for the full fee breakdown.
  </Step>

  <Step title="Explore the DLP Vault">
    Learn about the protocol-owned liquidity vault and its backstop role on the [DLP Vault](/for-traders/dlp-vault) page.
  </Step>

  <Step title="Build with the SDK">
    See [Write SDK — Vault transactions](/typescript-sdk/write-sdk#vault-transactions) and [Trading on behalf of a vault](/typescript-sdk/write-sdk#trading-on-behalf-of-a-vault). Optional end-to-end smoke: `cd typescript/packages/e2e && pnpm start:vault-e2e`.
  </Step>
</Steps>
