# 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) — AI-agent integration


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.chamberfi.com/build/integration-examples.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
