SDK

Complete API reference for interacting with CMX Protocol smart contracts.

SDK Overview

The CMX Protocol SDK provides a TypeScript/JavaScript interface for all protocol interactions.

Installation

npm install @capsign/sdk
# or
yarn add @capsign/sdk

Basic Setup

import { CMXClient, Network } from "@capsign/sdk";

const client = new CMXClient({
  network: Network.BASE_SEPOLIA,
  privateKey: process.env.PRIVATE_KEY,
  // Optional: custom RPC endpoint
  rpcUrl: "https://sepolia.base.org",
  // Optional: etherscan API key for verification
  etherscanApiKey: process.env.BASESCAN_API_KEY,
});

Asset Management

Create Assets

Create Share Class

const shareClass = await client.assets.createShareClass({
  name: "Example Corp Class A",
  symbol: "EXMP-A",
  totalShares: 1000000,
  votingRights: true,
  dividendRights: true,
  transferRestrictions: {
    requireKYC: true,
    accreditedOnly: false,
    lockupPeriod: 0,
  },
  governanceConfig: {
    votingPower: 1,
    quorumPercentage: 25,
    votingPeriod: 604800, // 7 days
  },
});

console.log(`Share class created at: ${shareClass.address}`);

Create Off-Chain Asset

const asset = await client.assets.createOffChainAsset({
  name: "Manhattan Office Building",
  symbol: "MOB-001",
  assetType: "REAL_ESTATE",
  totalValue: ethers.utils.parseEther("10000000"), // $10M
  jurisdiction: "US-NY",
  compliance: {
    requireKYC: true,
    accreditedOnly: true,
    qualifiedPurchaser: true,
  },
  metadata: {
    location: "Manhattan, New York",
    propertyType: "Office Building",
    sqft: 50000,
    ipfsHash: "QmX...", // IPFS hash of detailed asset information
  },
});

Asset Operations

Transfer Assets

// Simple transfer (if compliance allows)
const transferTx = await client.assets.transfer({
  assetAddress: "0x123...",
  to: "0x456...",
  amount: ethers.utils.parseEther("100"),
});

// Transfer with compliance check
const complianceTransfer = await client.assets.transferWithCompliance({
  assetAddress: "0x123...",
  to: "0x456...",
  amount: ethers.utils.parseEther("100"),
  complianceData: {
    kycVerified: true,
    accreditationLevel: "QUALIFIED_PURCHASER",
    jurisdictionApproved: true,
  },
});

Asset Queries

// Get asset information
const assetInfo = await client.assets.getAssetInfo("0x123...");
console.log(assetInfo);
// Returns:
// {
//   name: 'Example Corp Class A',
//   symbol: 'EXMP-A',
//   totalSupply: '1000000',
//   votingRights: true,
//   dividendRights: true,
//   ...
// }

// Get user balance
const balance = await client.assets.getBalance("0x123...", "0x456...");

// Get transfer restrictions
const restrictions = await client.assets.getTransferRestrictions("0x123...");

Trading & Markets

Order Book Trading

Place Orders

// Place buy order
const buyOrder = await client.trading.placeBuyOrder({
  market: "0x789...",
  asset: "0x123...",
  amount: ethers.utils.parseEther("100"),
  price: ethers.utils.parseEther("10"), // $10 per share
  orderType: "LIMIT",
  timeInForce: "GTC", // Good Till Cancelled
});

// Place sell order
const sellOrder = await client.trading.placeSellOrder({
  market: "0x789...",
  asset: "0x123...",
  amount: ethers.utils.parseEther("50"),
  price: ethers.utils.parseEther("11"),
  orderType: "LIMIT",
  timeInForce: "FOK", // Fill Or Kill
});

Order Management

// Cancel order
await client.trading.cancelOrder("0x789...", buyOrder.orderId);

// Get order status
const orderStatus = await client.trading.getOrder("0x789...", buyOrder.orderId);

// Get order book
const orderBook = await client.trading.getOrderBook("0x789...", "0x123...");
console.log(orderBook);
// Returns:
// {
//   bids: [
//     { price: '10.00', amount: '100', orderId: '123' },
//     { price: '9.95', amount: '200', orderId: '124' }
//   ],
//   asks: [
//     { price: '10.05', amount: '150', orderId: '125' },
//     { price: '10.10', amount: '75', orderId: '126' }
//   ]
// }

Auction Markets

Create Auction

const auction = await client.auctions.createAuction({
  asset: "0x123...",
  amount: ethers.utils.parseEther("1000"),
  auctionType: "ENGLISH", // or 'DUTCH', 'SEALED_BID'
  startingPrice: ethers.utils.parseEther("5"),
  reservePrice: ethers.utils.parseEther("8"),
  duration: 86400, // 24 hours
  bidIncrement: ethers.utils.parseEther("0.1"),
});

Bid on Auction

const bid = await client.auctions.placeBid({
  auctionId: auction.auctionId,
  amount: ethers.utils.parseEther("9.5"),
});

OTC Trading

Create OTC Offer

const otcOffer = await client.otc.createOffer({
  asset: "0x123...",
  amount: ethers.utils.parseEther("5000"),
  price: ethers.utils.parseEther("12"),
  counterparty: "0x456...", // Optional: specific counterparty
  expiry: Math.floor(Date.now() / 1000) + 3600, // 1 hour
});

Accept OTC Offer

await client.otc.acceptOffer(otcOffer.offerId);

Fund Management

Create Investment Fund

const fund = await client.funds.createUniversalFund({
  name: "Growth Equity Fund I",
  symbol: "GEF-I",
  fundType: "HEDGE_FUND",
  strategy: "GROWTH_EQUITY",
  baseCurrency: "USD",
  managementFee: 200, // 2% (in basis points)
  performanceFee: 2000, // 20%
  highWaterMark: true,
  lockupPeriod: 31536000, // 1 year
  redemptionFrequency: "QUARTERLY",
  minimumInvestment: ethers.utils.parseEther("1000000"), // $1M
  gateProvisions: {
    enabled: true,
    maxRedemptionPercentage: 25, // 25% per quarter
  },
});

Fund Operations

Investor Operations

// Deposit (invest in fund)
const investment = await client.funds.deposit({
  fundAddress: fund.address,
  amount: ethers.utils.parseEther("5000000"), // $5M investment
  investor: "0x456...",
});

// Withdraw (redeem from fund)
const redemption = await client.funds.withdraw({
  fundAddress: fund.address,
  shares: ethers.utils.parseEther("1000"), // Fund shares to redeem
  investor: "0x456...",
});

// Get investor position
const position = await client.funds.getInvestorPosition(
  fund.address,
  "0x456..."
);

Fund Administration

// Calculate NAV
const nav = await client.funds.calculateNAV(fund.address);

// Process performance fees
await client.funds.processPerformanceFees(fund.address);

// Get fund performance
const performance = await client.funds.getPerformanceMetrics(fund.address);
console.log(performance);
// Returns:
// {
//   totalReturn: '15.5', // 15.5%
//   annualizedReturn: '12.3',
//   sharpeRatio: '1.45',
//   maxDrawdown: '8.2',
//   volatility: '18.7'
// }

Compliance & Attestations

KYC/AML Operations

Create Attestation

const kycAttestation = await client.compliance.createKYCAttestation({
  subject: "0x456...",
  verificationLevel: "ENHANCED",
  accreditationStatus: "ACCREDITED_INVESTOR",
  jurisdictions: ["US", "EU"],
  expiryDate: Math.floor(Date.now() / 1000) + 31536000, // 1 year
  verifierSignature: "0x...", // Signature from authorized verifier
});

Verify Compliance

// Check if address meets compliance requirements
const complianceCheck = await client.compliance.verifyCompliance({
  address: "0x456...",
  requirements: {
    kycRequired: true,
    accreditedInvestor: true,
    qualifiedPurchaser: false,
    jurisdiction: "US",
  },
});

console.log(complianceCheck.approved); // true/false
console.log(complianceCheck.reasons); // Array of compliance issues if any

Document Management

Register Document

const documentHash = await client.documents.register({
  documentType: "PROSPECTUS",
  ipfsHash: "QmX...",
  title: "Growth Equity Fund I Prospectus",
  version: "1.0",
  signatories: ["0x123...", "0x456..."],
});

Verify Document

const isValid = await client.documents.verify(documentHash);
const documentInfo = await client.documents.getInfo(documentHash);

Governance

Proposal Management

Create Proposal

const proposal = await client.governance.createProposal({
  title: "Increase Management Fee Cap",
  description:
    "Proposal to increase the maximum management fee from 2% to 2.5%",
  targets: ["0x123..."], // Contract addresses to call
  values: [0], // ETH values to send
  calldatas: ["0x..."], // Encoded function calls
  votingPeriod: 604800, // 7 days
});

Vote on Proposal

// Vote in favor
await client.governance.vote({
  proposalId: proposal.proposalId,
  support: true,
  reason: "This change will help attract top talent",
});

// Delegate voting power
await client.governance.delegate({
  delegatee: "0x456...", // Address to delegate voting power to
});

Execute Proposal

// After voting period ends and proposal passes
await client.governance.execute(proposal.proposalId);

Utilities & Helpers

Price Feeds

// Get current price
const price = await client.prices.getPrice("0x123...");

// Get historical prices
const historicalPrices = await client.prices.getHistoricalPrices("0x123...", {
  from: startTimestamp,
  to: endTimestamp,
  interval: "DAILY",
});

// Set price (if authorized)
await client.prices.setPrice("0x123...", ethers.utils.parseEther("15.50"));

Escrow Services

// Create escrow
const escrow = await client.escrow.create({
  asset: "0x123...",
  amount: ethers.utils.parseEther("1000"),
  beneficiary: "0x456...",
  releaseConditions: {
    timelock: Math.floor(Date.now() / 1000) + 2592000, // 30 days
    approvalRequired: true,
    approvers: ["0x789..."],
  },
});

// Release escrow
await client.escrow.release(escrow.escrowId);

Batch Operations

// Batch multiple operations in one transaction
const batchTx = await client.batch.execute([
  {
    target: '0x123...',
    calldata: client.assets.interface.encodeFunctionData('transfer', ['0x456...', '100'])
  },
  {
    target: '0x789...',
    calldata: client.trading.interface.encodeFunctionData('placeBuyOrder', [...])
  }
]);

Event Subscriptions

Subscribe to Events

// Subscribe to asset transfers
client.events.subscribe("AssetTransfer", {
  filter: {
    asset: "0x123...",
  },
  callback: (event) => {
    console.log(
      `Transfer: ${event.from} -> ${event.to}, Amount: ${event.amount}`
    );
  },
});

// Subscribe to trade executions
client.events.subscribe("TradeExecuted", {
  filter: {
    market: "0x789...",
  },
  callback: (event) => {
    console.log(`Trade executed: ${event.amount} at ${event.price}`);
  },
});

// Subscribe to governance events
client.events.subscribe("ProposalCreated", {
  callback: (event) => {
    console.log(`New proposal: ${event.description}`);
  },
});

Error Handling

import { CMXError, ErrorCode } from "@capsign/sdk";

try {
  await client.assets.transfer({
    assetAddress: "0x123...",
    to: "0x456...",
    amount: ethers.utils.parseEther("100"),
  });
} catch (error) {
  if (error instanceof CMXError) {
    switch (error.code) {
      case ErrorCode.INSUFFICIENT_BALANCE:
        console.log("Insufficient balance for transfer");
        break;
      case ErrorCode.COMPLIANCE_VIOLATION:
        console.log("Transfer violates compliance rules");
        break;
      case ErrorCode.TRANSFER_RESTRICTED:
        console.log("Asset has transfer restrictions");
        break;
      default:
        console.log(`Protocol error: ${error.message}`);
    }
  } else {
    console.log(`Unexpected error: ${error.message}`);
  }
}

Configuration Options

Advanced Client Configuration

const client = new CMXClient({
  network: Network.BASE_MAINNET,
  privateKey: process.env.PRIVATE_KEY,

  // Gas configuration
  gasConfig: {
    gasLimit: 1000000,
    maxFeePerGas: ethers.utils.parseUnits("20", "gwei"),
    maxPriorityFeePerGas: ethers.utils.parseUnits("2", "gwei"),
  },

  // Retry configuration
  retryConfig: {
    maxRetries: 3,
    retryDelay: 1000,
    exponentialBackoff: true,
  },

  // Logging configuration
  logging: {
    level: "INFO",
    includeTransactionDetails: true,
  },

  // Cache configuration
  cache: {
    enabled: true,
    ttl: 300000, // 5 minutes
  },
});

Environment-Specific Settings

// Development configuration
const devClient = new CMXClient({
  network: Network.BASE_SEPOLIA,
  privateKey: process.env.DEV_PRIVATE_KEY,
  debug: true,
  simulateTransactions: true,
});

// Production configuration
const prodClient = new CMXClient({
  network: Network.BASE_MAINNET,
  privateKey: process.env.PROD_PRIVATE_KEY,
  confirmations: 3, // Wait for 3 confirmations
  timeout: 60000, // 60 second timeout
  fallbackRpcUrls: [
    "https://mainnet.base.org",
    "https://base-mainnet.infura.io/v3/YOUR-PROJECT-ID",
  ],
});

Rate Limiting & Best Practices

Efficient API Usage

// Use batch operations when possible
const results = await client.batch.query([
  () => client.assets.getBalance("0x123...", "0x456..."),
  () => client.funds.getNAV("0x789..."),
  () => client.trading.getOrderBook("0xabc...", "0x123..."),
]);

// Cache frequently accessed data
const cachedPrice =
  (await client.cache.get("price:0x123...")) ||
  (await client.prices.getPrice("0x123..."));

// Use event subscriptions instead of polling
client.events.subscribe("AssetTransfer", {
  filter: { asset: "0x123..." },
  callback: updateUI,
});

This comprehensive API reference provides all the tools needed to build sophisticated capital markets applications on the CMX Protocol.

Last updated

Was this helpful?