Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

TypeScript SDK (vifdk)

The vifdk is the official TypeScript SDK for the Vif protocol. It provides a high-level, type-safe interface for interacting with Vif smart contracts using viem.

Installation

npm
npm install vifdk viem

Quick Start

1. Set Up Viem Client

import { createPublicClient, createWalletClient, http } from "viem";
import { mainnet } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
 
const publicClient = createPublicClient({
  chain: mainnet,
  transport: http(),
});
 
const walletClient = createWalletClient({
  chain: mainnet,
  transport: http(),
  account: privateKeyToAccount(privateKey),
});

2. Define Tokens

import { Token } from "vifdk";
 
const USDC = Token.from(
  "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // address
  6, // decimals
  "USDC", // symbol
  1n, // initial unit
);
 
const WETH = Token.from(
  "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
  18,
  "WETH",
  1n,
);

3. Create a Market

import { Market } from "vifdk";
 
const market = Market.create({
  base: WETH,
  quote: USDC,
  tickSpacing: 1n,
});

4. Initialize VifRouter

import { VifRouter, execute } from "vifdk";
 
const router = new VifRouter(
  VIF_ROUTER_ADDRESS, // Router contract address
  VIF_CORE_ADDRESS, // Core contract address
  1, // Chain ID
);

5. Execute a Market Order (Swap)

 
// Create actions builder
const actions = router
  .createTypedActions()
  .orderSingle({
    market: market.asks,
    fillVolume: USDC.amount("1000"), // Spend 1000 USDC
    maxTick: market.asks.price(4000), // Max price limit
  })
  .build({
    addRecommendedActions: true, // Automatically adds settleAll(USDC) and takeAll(WETH)
    receiver: walletClient.account.address,
  });
 
// Get transaction data
const { commands, args } = actions.txData();
 
// Execute transaction
const receipt = await walletClient.writeContractSync({
  address: VIF_ROUTER_ADDRESS,
  ...execute(commands, args),
});

6. Place a Limit Order

const limitActions = router
  .createTypedActions()
  .limitSingle({
    market: market.asks,
    gives: WETH.amount("1"), // Sell 1 WETH
    tick: market.asks.price(3500), // At 3500 USDC/WETH
    expiry: new Date(Date.now() + 86400000), // Expires in 24 hours
    provision: Token.PROVISION_TOKEN.amount("0.001"), // 0.001 ETH provision
  })
  .build({
    addRecommendedActions: true, // Automatically adds settleAll(NATIVE_TOKEN) and settleAll(WETH)
    receiver: walletClient.account.address,
  });
 
const { commands: limitCommands, args: limitArgs } = limitActions.txData();
 
const limitReceipt = await walletClient.writeContractSync({
  address: VIF_ROUTER_ADDRESS,
  ...execute(limitCommands, limitArgs),
  value: limitActions.expectedValue({
    globalProvision: Token.PROVISION_TOKEN.amount("0.001"),
  }).amount, // Include provision
});

Core Concepts

Type Safety

vifdk is fully typed and provides excellent TypeScript support:

// Actions are type-checked at compile time
const typedActions = router
  .createTypedActions()
  .orderSingle({
    /* params are type-checked */
    market: market.asks,
    fillVolume: USDC.amount("100"),
  })
  .build({
    addRecommendedActions: true,
    receiver: walletClient.account.address,
  });
 
// Results are properly typed
const { commands: cmd, args: arg } = typedActions.txData();
const { result } = await publicClient.simulateContract({
  address: VIF_ROUTER_ADDRESS,
  ...execute(cmd, arg),
});
const parsedResult = typedActions.parseSimulationResult(result);
// parsedResult[0].data is typed based on action type

Builder Pattern

All operations use a fluent builder pattern:

const builderActions = router
  .createTypedActions()
  .orderSingle({
    market: market.asks,
    fillVolume: USDC.amount("100"),
  })
  .limitSingle({
    market: market.asks,
    gives: WETH.amount("1"),
    tick: market.asks.price(3500),
  })
  .build({
    addRecommendedActions: true,
    receiver: walletClient.account.address,
  });

Actions are automatically ordered and optimized when calling .build().

Token Amounts

Token amounts are represented with proper precision:

const amount = USDC.amount("1000.5"); // String for precision
// amount.amount is bigint: 1000500000n
 
const amount2 = USDC.amount(1000500000n); // Or use bigint directly
// amount2.amountString is '1000.5'

Market Directions

Markets have two directions (asks and bids):

market.asks; // Makers sell base (WETH), buyers get WETH
market.bids; // Makers buy base (WETH), sellers give WETH

Key Features

  • Type-safe - Full TypeScript support with strict typing
  • Builder pattern - Fluent API for building complex transactions
  • Viem integration - Works seamlessly with viem clients
  • Automatic optimization - Actions are automatically ordered for efficiency
  • Result parsing - Parse simulation results and transaction logs
  • Market helpers - Price conversions, fee calculations, and more

Next Steps

Explore the SDK in detail:

Common Use Cases

Check out guides for common patterns:

Support