Skip to main content

Quick Start

There are two paths depending on where you are in your integration:

  • Path A — Sandbox UI (no code): validate the full flow in your browser before writing a line.
  • Path B — Code integration: implement the flow in your own protocol once you know it works.

Path A: Try it in the sandbox

No scripts, no config files, no private keys. Just a wallet on Ethereum Sepolia.

1. Get testnet DS Tokens

Open the Faucet, connect your wallet on Ethereum Sepolia, and request tokens. You'll receive DS Tokens within seconds.

2. Register as an operator

Go to Register as Operator, enter your protocol contract address, and click Register as Operator. On testnet this is permissionless — no admin approval needed.

If you don't have a protocol contract yet, you can enter your wallet address to explore the flow. Just note that in production the operator must be the contract that calls registerVault().

3. Try the full investor flow

Go to Mock Protocol Example. This page simulates what an investor sees when interacting with a DeFi protocol that has integrated DS Token. Walk through:

  1. Sign — Sign the EIP-712 standing permission authorizing the operator to register a vault on your behalf.
  2. Approve — Approve the DS Token contract to allow the operator to transfer tokens.
  3. Deposit — The protocol calls registerVault() using your signature and pulls tokens into the vault.

This is the exact flow your users will experience.

4. Test your own protocol contract

Once you've deployed your own protocol contract, use the Protocol Tester to call it directly from the browser:

  1. Upload your contract's ABI.
  2. Select a method from the dropdown.
  3. Fill in parameters — amount fields are automatically converted to the correct decimal representation.
  4. Optionally sign the EIP-712 RegisterVault typed data and auto-fill the signature parameter.
  5. Approve the DS Token spend if needed, then execute.

This lets you validate your contract's integration with VaultRegistrar without writing any off-chain scripts.


Path B: Integrate it in code

Once you've validated the flow in the sandbox, use this path to integrate into your protocol's off-chain code.

1. Get testnet DS Tokens

Same as above — use the Faucet or call requestTokens() programmatically.

2. Register as an operator (on-chain)

# from bc-vault-registrar — only needed if you control the admin key
npx hardhat add-operator \
--registrar 0xVaultRegistrar \
--operator 0xYourProtocolContract \
--network sepolia

Or use the sandbox UI at Register as Operator — it calls addOperator() directly from your wallet.

3. Sign and register a vault

import { createWalletClient, http, createPublicClient } from "viem";
import { sepolia } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY");

const walletClient = createWalletClient({
account,
chain: sepolia,
transport: http(),
});

const publicClient = createPublicClient({
chain: sepolia,
transport: http(),
});

const VAULT_REGISTRAR = "0xYOUR_VAULT_REGISTRAR_ADDRESS";
const OPERATOR = "0xYOUR_OPERATOR_ADDRESS";
const TOKEN = "0xDS_TOKEN_ADDRESS";

// 1. Get current nonce
const nonce = await publicClient.readContract({
address: VAULT_REGISTRAR,
abi: [
"function operatorNonce(address, address) view returns (uint256)",
],
functionName: "operatorNonce",
args: [account.address, OPERATOR],
});

// 2. Sign EIP-712 typed data
const deadline = BigInt(Math.floor(Date.now() / 1000) + 600);

const signature = await walletClient.signTypedData({
domain: {
name: "VaultRegistrar",
version: "1",
chainId: sepolia.id,
verifyingContract: VAULT_REGISTRAR,
},
types: {
RegisterVault: [
{ name: "investor", type: "address" },
{ name: "operator", type: "address" },
{ name: "token", type: "address" },
{ name: "nonce", type: "uint256" },
{ name: "deadline", type: "uint256" },
],
},
primaryType: "RegisterVault",
message: {
investor: account.address,
operator: OPERATOR,
token: TOKEN,
nonce,
deadline,
},
});

// 3. Register the vault (called by the operator)
const hash = await walletClient.writeContract({
address: VAULT_REGISTRAR,
abi: [
"function registerVault(address, address, uint256, bytes)",
],
functionName: "registerVault",
args: ["0xYOUR_VAULT_ADDRESS", account.address, deadline, signature],
});

console.log("Vault registered:", hash);

Next steps