@cks-systems/manifest-sdk

中文文档
0.2.38发布于 2026/01/17MITTypeScriptESM + CJS近 30 天下载 6262

TypeScript SDK for Manifest

原始使用文档
文档目录36 节
  1. Installation
  2. Overview
  3. Quick Start
  4. For UI Applications (Read-Only)
  5. For Trading Bots (Full Access)
  6. UI Integration Examples
  7. Finding Markets
  8. Loading Market Data
  9. Reading the Orderbook
  10. Subscribing to Market Updates
  11. Reading Trader Balances
  12. Wallet Integration (No Private Key)
  13. Trading Bot Examples
  14. Complete Bot Setup Flow
  15. Depositing Funds
  16. Placing Orders
  17. Order Types
  18. Cancelling Orders
  19. Withdrawing Funds
  20. Place Order with Auto-Deposit
  21. Complete Trading Loop Example
  22. Global Account Operations
  23. Setup Global Account
  24. Deposit to Global Account
  25. Withdraw from Global Account
  26. Reading Global Account State
  27. Advanced Patterns
  28. Batch Order Updates
  29. Loading All Markets for a Trader
  30. Fill Feed (Monitoring Trades)
  31. Error Handling
  32. Token2022 Support
  33. API Reference
  34. ManifestClient
  35. Market
  36. Global

Manifest TypeScript Client

TypeScript SDK for interacting with the Manifest decentralized exchange on Solana.

Installation

yarn add @cks-systems/manifest-sdk

Overview

The SDK provides these main classes:

  • ManifestClient - Primary class for building transactions and reading market data
  • Market - Deserializes and queries market state (orderbook, balances, seats)
  • Wrapper - Caches a trader's open orders across markets
  • Global - Manages global account state for cross-market liquidity

Quick Start

For UI Applications (Read-Only)

import { Connection, PublicKey } from '@solana/web3.js';
import { ManifestClient, Market } from '@cks-systems/manifest-sdk';

const connection = new Connection('https://api.mainnet-beta.solana.com');
const marketAddress = new PublicKey('YOUR_MARKET_ADDRESS');

// Load market data (no wallet needed)
const market = await Market.loadFromAddress({
  connection,
  address: marketAddress,
});

// Read orderbook
const bids = market.bids();
const asks = market.asks();

console.log('Best bid:', market.bestBidPrice());
console.log('Best ask:', market.bestAskPrice());

For Trading Bots (Full Access)

import { Connection, Keypair, PublicKey } from '@solana/web3.js';
import { ManifestClient, OrderType } from '@cks-systems/manifest-sdk';

const connection = new Connection('https://api.mainnet-beta.solana.com');
const trader = Keypair.fromSecretKey(/* your keypair */);
const marketAddress = new PublicKey('YOUR_MARKET_ADDRESS');

// Creates wrapper + claims seat automatically if needed
const client = await ManifestClient.getClientForMarket(
  connection,
  marketAddress,
  trader,
);

// Now ready to trade
const placeOrderIx = client.placeOrderIx({
  numBaseTokens: 1.0,
  tokenPrice: 100.0,
  isBid: true,
  lastValidSlot: 0, // No expiration
  orderType: OrderType.Limit,
  clientOrderId: 1,
});

UI Integration Examples

Finding Markets

import { ManifestClient } from '@cks-systems/manifest-sdk';

// List all market addresses
const marketPubkeys = await ManifestClient.listMarketPublicKeys(connection);

// Find markets for specific token pair
const baseMint = new PublicKey('So11111111111111111111111111111111111111112'); // SOL
const quoteMint = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'); // USDC

const markets = await ManifestClient.listMarketsForMints(
  connection,
  baseMint,
  quoteMint,
);

Loading Market Data

import { Market } from '@cks-systems/manifest-sdk';

// Method 1: Load from address (fetches from chain)
const market = await Market.loadFromAddress({
  connection,
  address: marketAddress,
});

// Method 2: Load from existing buffer (for subscriptions)
const accountInfo = await connection.getAccountInfo(marketAddress);
const market = Market.loadFromBuffer({
  address: marketAddress,
  buffer: accountInfo.data,
});

// Access market info
console.log('Base mint:', market.baseMint().toBase58());
console.log('Quote mint:', market.quoteMint().toBase58());
console.log('Base decimals:', market.baseDecimals());
console.log('Quote decimals:', market.quoteDecimals());

Reading the Orderbook

// Get all orders
const bids = market.bids(); // Sorted by price descending
const asks = market.asks(); // Sorted by price ascending

// Get best prices
const bestBid = market.bestBidPrice();
const bestAsk = market.bestAskPrice();

// Each order contains:
// - price: number (in quote tokens per base token)
// - numBaseTokens: number
// - clientOrderId: number
// - trader: PublicKey
// - sequenceNumber: number
// - lastValidSlot: number

Subscribing to Market Updates

// Subscribe to real-time market changes
connection.onAccountChange(marketAddress, (accountInfo) => {
  const market = Market.loadFromBuffer({
    address: marketAddress,
    buffer: accountInfo.data,
  });

  // Update your UI
  updateOrderbook(market.bids(), market.asks());
  updateBestPrices(market.bestBidPrice(), market.bestAskPrice());
});

Reading Trader Balances

// Get a trader's balance on a specific market
const traderPubkey = new PublicKey('TRADER_ADDRESS');

// Withdrawable balance (deposited - locked in orders)
const baseBalance = market.getWithdrawableBalanceTokens(traderPubkey, true);
const quoteBalance = market.getWithdrawableBalanceTokens(traderPubkey, false);

// Check if trader has a seat
const hasSeat = market.hasSeat(traderPubkey);

Wallet Integration (No Private Key)

For browser wallets like Phantom, use getSetupIxs and getClientForMarketNoPrivateKey:

import { Transaction } from '@solana/web3.js';
import { ManifestClient } from '@cks-systems/manifest-sdk';

async function setupAndGetClient(
  connection: Connection,
  marketAddress: PublicKey,
  walletPubkey: PublicKey,
  sendTransaction: (tx: Transaction) => Promise<string>,
) {
  // Check if setup is needed (wrapper creation + seat claim)
  const { setupNeeded, instructions, wrapperKeypair } =
    await ManifestClient.getSetupIxs(connection, marketAddress, walletPubkey);

  if (setupNeeded) {
    const tx = new Transaction().add(...instructions);
    tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
    tx.feePayer = walletPubkey;

    // Sign with wrapper keypair if creating new wrapper
    if (wrapperKeypair) {
      tx.partialSign(wrapperKeypair);
    }

    // Send via wallet adapter
    await sendTransaction(tx);

    // Wait for confirmation
    await new Promise((resolve) => setTimeout(resolve, 5000));
  }

  // Create client (read-only, instructions must be signed by wallet)
  const client = await ManifestClient.getClientForMarketNoPrivateKey(
    connection,
    marketAddress,
    walletPubkey,
  );

  return client;
}

Trading Bot Examples

Complete Bot Setup Flow

import {
  Connection,
  Keypair,
  PublicKey,
  Transaction,
  sendAndConfirmTransaction,
  ComputeBudgetProgram,
} from '@solana/web3.js';
import { ManifestClient, OrderType } from '@cks-systems/manifest-sdk';

const connection = new Connection('https://api.mainnet-beta.solana.com');
const trader = Keypair.fromSecretKey(Uint8Array.from(/* your key */));
const marketAddress = new PublicKey('YOUR_MARKET_ADDRESS');

// Step 1: Initialize client (auto-creates wrapper + claims seat)
const client = await ManifestClient.getClientForMarket(
  connection,
  marketAddress,
  trader,
);

console.log('Market loaded:', client.market.address.toBase58());
console.log('Base mint:', client.market.baseMint().toBase58());
console.log('Quote mint:', client.market.quoteMint().toBase58());

Depositing Funds

// Deposit base tokens (e.g., SOL)
const depositBaseIx = client.depositIx(
  trader.publicKey,
  client.market.baseMint(),
  10.0, // Amount in tokens (not atoms)
);

// Deposit quote tokens (e.g., USDC)
const depositQuoteIx = client.depositIx(
  trader.publicKey,
  client.market.quoteMint(),
  1000.0, // Amount in tokens
);

// Send deposit transaction
const depositTx = new Transaction().add(depositBaseIx, depositQuoteIx);
const depositSig = await sendAndConfirmTransaction(connection, depositTx, [
  trader,
]);
console.log('Deposited:', depositSig);

Placing Orders

// Place a limit bid
const bidIx = client.placeOrderIx({
  numBaseTokens: 1.0,
  tokenPrice: 95.0, // Price in quote per base
  isBid: true,
  lastValidSlot: 0, // 0 = no expiration
  orderType: OrderType.Limit,
  clientOrderId: 1, // Your reference ID
});

// Place a limit ask
const askIx = client.placeOrderIx({
  numBaseTokens: 1.0,
  tokenPrice: 105.0,
  isBid: false,
  lastValidSlot: 0,
  orderType: OrderType.Limit,
  clientOrderId: 2,
});

// Send orders
const orderTx = new Transaction().add(bidIx, askIx);
const orderSig = await sendAndConfirmTransaction(connection, orderTx, [trader]);

Order Types

// Limit Order - standard order that can take or provide liquidity
const limitOrder = client.placeOrderIx({
  numBaseTokens: 1.0,
  tokenPrice: 100.0,
  isBid: true,
  lastValidSlot: 0,
  orderType: OrderType.Limit,
  clientOrderId: 1,
});

// Post-Only Order - rejected if it would immediately match
const postOnlyOrder = client.placeOrderIx({
  numBaseTokens: 1.0,
  tokenPrice: 100.0,
  isBid: true,
  lastValidSlot: 0,
  orderType: OrderType.PostOnly,
  clientOrderId: 2,
});

// Immediate-or-Cancel - fills what it can, cancels the rest
const iocOrder = client.placeOrderIx({
  numBaseTokens: 1.0,
  tokenPrice: 100.0,
  isBid: true,
  lastValidSlot: 0,
  orderType: OrderType.ImmediateOrCancel,
  clientOrderId: 3,
});

// Global Order - uses global account for cross-market liquidity
const globalOrder = client.placeOrderIx({
  numBaseTokens: 1.0,
  tokenPrice: 100.0,
  isBid: true,
  lastValidSlot: 0,
  orderType: OrderType.Global,
  clientOrderId: 4,
});

Cancelling Orders

// Cancel by client order ID
const cancelIx = client.cancelOrderIx(1); // clientOrderId

// Cancel all orders on this market
const cancelAllIx = client.cancelAllIx();

// Cancel all bids only
const cancelBidsIx = client.cancelBidsOnCoreIx();

// Cancel all asks only
const cancelAsksIx = client.cancelAsksOnCoreIx();

Withdrawing Funds

// Withdraw specific amount
const withdrawBaseIx = client.withdrawIx(
  trader.publicKey,
  client.market.baseMint(),
  5.0, // Amount in tokens
);

// Withdraw all funds from market
const withdrawAllIx = client.withdrawAllIx();

const withdrawTx = new Transaction().add(...withdrawAllIx);
await sendAndConfirmTransaction(connection, withdrawTx, [trader]);

Place Order with Auto-Deposit

Automatically deposits required funds if balance is insufficient:

const instructions = await client.placeOrderWithRequiredDepositIxs({
  numBaseTokens: 1.0,
  tokenPrice: 100.0,
  isBid: true,
  lastValidSlot: 0,
  orderType: OrderType.Limit,
  clientOrderId: 1,
});

// instructions array may include deposit ix before place order ix
const tx = new Transaction().add(...instructions);
await sendAndConfirmTransaction(connection, tx, [trader]);

Complete Trading Loop Example

async function tradingBot() {
  const client = await ManifestClient.getClientForMarket(
    connection,
    marketAddress,
    trader,
  );

  while (true) {
    // Reload market data
    await client.market.reload(connection);

    const bestBid = client.market.bestBidPrice();
    const bestAsk = client.market.bestAskPrice();
    const spread = bestAsk && bestBid ? (bestAsk - bestBid) / bestBid : null;

    console.log(
      `Best Bid: ${bestBid}, Best Ask: ${bestAsk}, Spread: ${spread}`,
    );

    // Check our balances
    const baseBalance = client.market.getWithdrawableBalanceTokens(
      trader.publicKey,
      true,
    );
    const quoteBalance = client.market.getWithdrawableBalanceTokens(
      trader.publicKey,
      false,
    );

    console.log(`Balances - Base: ${baseBalance}, Quote: ${quoteBalance}`);

    // Your trading logic here...

    await new Promise((resolve) => setTimeout(resolve, 1000));
  }
}

Global Account Operations

Global accounts allow traders to share liquidity across multiple markets.

Setup Global Account

import { Global, ManifestClient } from '@cks-systems/manifest-sdk';

const mint = new PublicKey('TOKEN_MINT_ADDRESS');

// Add trader to global account (one-time setup)
const addTraderIx = await ManifestClient.createGlobalAddTraderIx(
  connection,
  trader.publicKey,
  mint,
);

const tx = new Transaction().add(addTraderIx);
await sendAndConfirmTransaction(connection, tx, [trader]);

Deposit to Global Account

// Deposit to global account (available across all markets for this token)
const globalDepositIx = await ManifestClient.globalDepositIx(
  connection,
  trader.publicKey,
  mint,
  100.0, // Amount in tokens
);

const tx = new Transaction().add(globalDepositIx);
await sendAndConfirmTransaction(connection, tx, [trader]);

Withdraw from Global Account

const globalWithdrawIx = await ManifestClient.globalWithdrawIx(
  connection,
  trader.publicKey,
  mint,
  50.0, // Amount in tokens
);

const tx = new Transaction().add(globalWithdrawIx);
await sendAndConfirmTransaction(connection, tx, [trader]);

Reading Global Account State

import { Global } from '@cks-systems/manifest-sdk';

// Load global account
const globalAddress = Global.findGlobalAddress(mint);
const global = await Global.loadFromAddress({
  connection,
  address: globalAddress,
});

// Check balances
const balance = await global.getGlobalBalanceTokens(
  connection,
  trader.publicKey,
);
console.log('Global balance:', balance);

// Check if trader has global seat
const hasSeat = global.hasSeat(trader.publicKey);

Advanced Patterns

Batch Order Updates

// Cancel and replace multiple orders in one transaction
const batchIx = client.batchUpdateIx({
  cancels: [{ clientOrderId: 1 }, { clientOrderId: 2 }],
  orders: [
    {
      numBaseTokens: 1.0,
      tokenPrice: 96.0,
      isBid: true,
      lastValidSlot: 0,
      orderType: OrderType.Limit,
      clientOrderId: 3,
    },
    {
      numBaseTokens: 1.0,
      tokenPrice: 104.0,
      isBid: false,
      lastValidSlot: 0,
      orderType: OrderType.Limit,
      clientOrderId: 4,
    },
  ],
});

Loading All Markets for a Trader

// Get clients for all markets where trader has a seat
const clients = await ManifestClient.getClientsReadOnlyForAllTraderSeats(
  connection,
  trader.publicKey,
);

for (const client of clients) {
  console.log('Market:', client.market.address.toBase58());
  const baseBalance = client.market.getWithdrawableBalanceTokens(
    trader.publicKey,
    true,
  );
  console.log('Base balance:', baseBalance);
}

Fill Feed (Monitoring Trades)

import { FillFeed } from '@cks-systems/manifest-sdk';

const fillFeed = new FillFeed(connection);

// Subscribe to fills (runs indefinitely)
fillFeed.on('fill', (fill) => {
  console.log('Fill:', {
    market: fill.market.toBase58(),
    maker: fill.maker.toBase58(),
    taker: fill.taker.toBase58(),
    baseTokens: fill.baseTokens,
    quoteTokens: fill.quoteTokens,
    price: fill.price,
    takerIsBuy: fill.takerIsBuy,
  });
});

await fillFeed.parseLogs(); // Starts monitoring

Error Handling

try {
  const tx = new Transaction().add(client.placeOrderIx(/* ... */));
  await sendAndConfirmTransaction(connection, tx, [trader]);
} catch (error) {
  if (error.message.includes('InsufficientFunds')) {
    console.log('Need to deposit more funds');
  } else if (error.message.includes('PostOnlyWouldTake')) {
    console.log('Post-only order would have crossed the spread');
  } else if (error.message.includes('InvalidOrderType')) {
    console.log('Order type not allowed');
  } else {
    throw error;
  }
}

Token2022 Support

The SDK automatically handles Token2022 tokens. No special configuration needed:

// Works the same for both SPL Token and Token2022
const client = await ManifestClient.getClientForMarket(
  connection,
  marketAddress, // Market with Token2022 tokens
  trader,
);

// Token program is detected automatically
console.log('Is base Token2022:', client.isBase22);
console.log('Is quote Token2022:', client.isQuote22);

// All operations work identically
const depositIx = client.depositIx(
  trader.publicKey,
  client.market.baseMint(),
  10.0,
);

API Reference

ManifestClient

MethodDescription
getClientForMarket(connection, marketPk, keypair)Create client with auto-setup
getClientForMarketNoPrivateKey(connection, marketPk, trader)Create read-only client
getSetupIxs(connection, marketPk, trader)Get setup instructions for wallet integration
listMarketPublicKeys(connection)List all market addresses
listMarketsForMints(connection, base, quote)Find markets for token pair
depositIx(payer, mint, amount)Deposit tokens to market
withdrawIx(payer, mint, amount)Withdraw tokens from market
withdrawAllIx()Withdraw all funds
placeOrderIx(params)Place an order
cancelOrderIx(clientOrderId)Cancel specific order
cancelAllIx()Cancel all orders
batchUpdateIx(params)Batch cancel and place orders

Market

MethodDescription
loadFromAddress({connection, address})Load market from chain
loadFromBuffer({address, buffer})Load from account data
reload(connection)Refresh market data
bids()Get bid orders
asks()Get ask orders
bestBidPrice()Get best bid price
bestAskPrice()Get best ask price
getWithdrawableBalanceTokens(trader, isBase)Get trader's available balance
hasSeat(trader)Check if trader has seat
baseMint() / quoteMint()Get token mints
baseDecimals() / quoteDecimals()Get token decimals

Global

MethodDescription
loadFromAddress({connection, address})Load global account
findGlobalAddress(mint)Derive global account PDA
getGlobalBalanceTokens(connection, trader)Get trader's global balance
hasSeat(trader)Check if trader has global seat
tokenMint()Get token mint

版本与发布记录

@cks-systems/manifest-sdk 共发布 77 个版本,首次发布于 2024/10/03;过去 12 个月发布了 22 个版本。

版本发布日期距今
0.2.38latest2026/01/179 个月前
0.2.372026/01/0310 个月前
0.2.362026/01/0310 个月前
0.2.352025/12/0211 个月前
0.2.342025/12/0111 个月前
0.2.332025/11/2711 个月前

关于 @cks-systems/manifest-sdk 的常见问题

@cks-systems/manifest-sdk 是什么?

TypeScript SDK for Manifest

如何安装 @cks-systems/manifest-sdk?

在项目目录运行 npm install @cks-systems/manifest-sdk,或使用 pnpm add / yarn add / bun add。

@cks-systems/manifest-sdk 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cks-systems/manifest-sdk 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@cks-systems/manifest-sdk 可以商用吗?

@cks-systems/manifest-sdk 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@cks-systems/manifest-sdk 的下载量有多少?

根据 npm 官方下载统计,@cks-systems/manifest-sdk 在 2026/10/10 – 2026/11/08 这 30 天内被下载 6,262 次,日均约 209 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cks-systems/manifest-sdk 还在维护吗?

最新版本 0.2.38 发布于 2026/01/17(9 个月前);至今共发布 77 个版本,其中过去 12 个月发布了 22 个;首次发布于 2024/10/03。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。