> For the complete documentation index, see [llms.txt](https://docs.chamberfi.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.chamberfi.com/build/integration-examples.md).

# Integration examples

Minimal, runnable examples for the flows integrators hit most often. All SDK examples assume `@dhedge/v2-sdk` and `ethers` v5. Error handling is kept terse. Add production niceties (retries, user prompts, logging) in real code.

## Read a vault's current composition

```ts
import { Dhedge, Network, ethers } from "@dhedge/v2-sdk";

const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
const chamber = new Dhedge(new ethers.Wallet(PK, provider), Network.POLYGON);

const vault = await chamber.loadPool(VAULT_ADDRESS);
const composition = await vault.getComposition();
console.log(composition);
```

For read-only analytics across many vaults, use the [subgraph](/build/subgraph.md) instead. It's faster and doesn't require an RPC per query.

## Deposit into a vault

```ts
const vault = await chamber.loadPool(VAULT_ADDRESS);

// ERC20 approve → deposit
await vault.approveDeposit(USDC_ADDRESS, "1000000000"); // 1000 USDC (6 decimals)
const tx = await vault.deposit(USDC_ADDRESS, "1000000000");
await tx.wait();
```

The deposit asset must be enabled on the vault (manager-controlled). If it isn't, the call reverts with [`dh8`](https://github.com/dhedge/V2-Public/blob/master/readmes/errorCodes/dHEDGEV2ErrorCodes.json). All revert codes (`dh3`, `dh8`, etc.) are catalogued in the [V2-Public error codes JSON](https://github.com/dhedge/V2-Public/blob/master/readmes/errorCodes/dHEDGEV2ErrorCodes.json). That file is the source of truth and may change. See [deposit](/deposit/deposit.md) for the depositor-facing story, and [fees](/deposit/fees.md) for how entry fees are settled (in shares, not the deposit asset).

## Withdraw

Simple withdrawal (assets fit the basic ERC20 path):

```ts
const tx = await vault.withdraw(SHARE_AMOUNT);
await tx.wait();
```

If the vault holds complex assets (LPs, perps, lending positions), the SDK's `withdraw()` may not cleanly unwind them. For those vaults, call the contract's `withdrawSafe(shareAmount, complexAssets[])` directly via an ethers `Contract` instance. Each entry tells the asset guard how to unwind. The SDK doesn't currently wrap this.

Note that the depositor's lockup cooldown must have elapsed, or the call reverts with [`dh3`](https://github.com/dhedge/V2-Public/blob/master/readmes/errorCodes/dHEDGEV2ErrorCodes.json). See [lockup & withdrawals](/deposit/lockup-withdrawals.md).

## Create a vault

```ts
const vault = await chamber.createPool(
  "Mat Finance",          // manager name (display name on vault page)
  "Conservative USD",     // vault name
  "CUSD",                 // vault share token symbol
  [
    [USDC_ADDRESS, true], // USDC as deposit asset
    [WETH_ADDRESS, false],// WETH tradeable but not depositable
    [WBTC_ADDRESS, false],
  ],
  10,                     // performance fee (numerator, e.g. 10 = 10%)
  0,                      // management fee
  0,                      // entry fee
  0,                      // exit fee
);
console.log("new vault:", vault.address);
```

For a walkthrough of the product decisions behind each parameter (denomination asset, fee structure, lockup), see [create a vault](/manage/create-a-vault.md).

## Execute a trade

```ts
import { Dapp } from "@dhedge/v2-sdk";

const tx = await vault.trade(
  Dapp.ODOS,        // aggregator
  USDC_ADDRESS,     // from
  WETH_ADDRESS,     // to
  "1000000000",     // 1000 USDC
  0.5,              // 0.5% max slippage
);
await tx.wait();
```

Only the manager or delegated trader can execute trades. The aggregator routes must compose into a guard-compliant call. If the destination contract isn't guarded, the transaction reverts with `dh23`.

## Prepare calldata without sending

Useful for multisig flows, or handing the tx to a user's wallet to sign:

```ts
const txData = await vault.trade(
  Dapp.ODOS,
  USDC_ADDRESS,
  WETH_ADDRESS,
  "1000000000",
  0.5,
  null,                         // no extra options
  { onlyGetTxData: true },      // return prepared tx, don't send
);
// txData = { txData, to, minAmountOut } — pass to your signer of choice
```

## Check if a protocol is supported

Before building a call, verify the guard exists:

```ts
import { Contract } from "ethers";

const factory = new Contract(FACTORY_ADDRESS, FACTORY_ABI, provider);
const guard = await factory.getContractGuard(TARGET_PROTOCOL);
if (guard === ethers.constants.AddressZero) {
  throw new Error("protocol not supported on this chain");
}
```

See [guard system](/build/guard-system.md) for the full enumeration surface.

## Query the subgraph

```ts
const res = await fetch(SUBGRAPH_URL, {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    query: `{
      pools(first: 20, orderBy: totalSupply, orderDirection: desc) {
        id
        fundAddress
        name
        manager
        managerName
        totalSupply
        tokenPrice
      }
    }`,
  }),
});
const { data } = await res.json();
```

See [subgraph](/build/subgraph.md) for schema and per-chain endpoints.

## Set a trader

A manager delegates day-to-day trading to a second EOA (hot wallet, bot, or agent):

```ts
const vault = await chamber.loadPool(VAULT_ADDRESS);
const tx = await vault.setTrader(TRADER_ADDRESS);
await tx.wait();
```

The trader can execute trades and change vault assets (default ON) but cannot change fees or the trader address itself. See [trader delegation](/manage/trader-delegation.md) for the full permission split.

## See also

* [SDK](/build/sdk.md): full method surface
* [Guard system](/build/guard-system.md): what makes a call succeed or fail
* [MCP server](/build/mcp-server.md): read vault state from an AI client
