Skip to main content

Installation

npm install @centuari/credit-kit
# or
yarn add @centuari/credit-kit
# or
pnpm add @centuari/credit-kit

Quick Start

import { CreditKit } from '@centuari/credit-kit';

// Initialize client
const client = new CreditKit({
  apiKey: process.env.CENTUARI_API_KEY,
  environment: 'production' // or 'sandbox'
});

// Create a lending position
const position = await client.lend({
  userId: 'user_123',
  asset: 'USDC',
  amount: '10000',
  rate: 0.08,
  maturity: '90d'
});

console.log(`Position created: ${position.positionId}`);

Configuration

Client Options

const client = new CreditKit({
  // Required
  apiKey: 'ck_live_...',

  // Optional
  environment: 'production', // 'production' | 'sandbox'
  timeout: 30000,            // Request timeout in ms
  retries: 3,                // Number of retries on failure
  baseUrl: 'https://...',    // Custom API URL (advanced)
});

Environment Variables

The SDK reads these environment variables:
VariableDescription
CENTUARI_API_KEYAPI key (if not passed to constructor)
CENTUARI_ENVEnvironment (production/sandbox)

Lending Operations

Easy Mode Lending

Let the protocol optimize rate and maturity:
const position = await client.easyLend({
  userId: 'user_123',
  asset: 'USDC',
  amount: '10000'
});

// Position auto-optimized for best available rate
console.log(`Rate: ${position.rate * 100}% APY`);
console.log(`Maturity: ${position.maturity}`);

Advanced Mode Lending

Full control over parameters:
const position = await client.lend({
  userId: 'user_123',
  asset: 'USDC',
  amount: '10000',
  rate: 0.085,              // Exactly 8.5% APY
  maturity: '2025-06-15',   // Specific date
  autoRollover: false       // Manual control
});

Batch Lending

Create multiple positions efficiently:
const positions = await client.batchLend([
  { userId: 'user_1', asset: 'USDC', amount: '10000' },
  { userId: 'user_2', asset: 'USDC', amount: '25000' },
  { userId: 'user_3', asset: 'USDT', amount: '15000' }
]);

console.log(`Created ${positions.length} positions`);

Borrowing Operations

Create Borrow Position

const position = await client.borrow({
  userId: 'user_456',
  collateral: {
    asset: 'ETH',
    amount: '5'
  },
  borrowAsset: 'USDC',
  borrowAmount: '8000',
  maturity: '90d',
  autoRefinance: true
});

console.log(`Borrowed: ${position.borrowAmount} USDC`);
console.log(`Health Factor: ${position.healthFactor}`);

Check Borrowing Power

const power = await client.getBorrowingPower({
  userId: 'user_456',
  collateral: {
    asset: 'ETH',
    amount: '5'
  },
  borrowAsset: 'USDC'
});

console.log(`Max borrow: ${power.maxBorrow} USDC`);
console.log(`LTV: ${power.ltv * 100}%`);

Repay Loan

// Full repayment
await client.repay({
  positionId: 'pos_xyz789'
});

// Partial repayment
await client.repay({
  positionId: 'pos_xyz789',
  amount: '4000'
});

Add Collateral

await client.addCollateral({
  positionId: 'pos_xyz789',
  asset: 'ETH',
  amount: '1'
});

Position Management

Get Position

const position = await client.getPosition('pos_abc123');

console.log({
  status: position.status,
  amount: position.amount,
  rate: position.rate,
  maturity: position.maturity,
  accruedInterest: position.accruedInterest
});

List Positions

// All positions for a user
const { positions, hasMore, nextCursor } = await client.listPositions({
  userId: 'user_123',
  status: 'active',
  type: 'lend',
  limit: 20
});

// Pagination
if (hasMore) {
  const nextPage = await client.listPositions({
    userId: 'user_123',
    cursor: nextCursor
  });
}

Cancel Order

await client.cancelOrder('pos_abc123');

Update Auto Features

await client.updatePosition('pos_abc123', {
  autoRollover: false
});

User Management

Get User Summary

const summary = await client.getUserSummary('user_123');

console.log({
  totalLent: summary.totalLent,
  totalBorrowed: summary.totalBorrowed,
  activePositions: summary.activePositions,
  totalEarned: summary.totalEarned
});

Get User Balances

const balances = await client.getUserBalances('user_123');

for (const balance of balances) {
  console.log(`${balance.asset}: ${balance.available} available`);
}

Withdraw Funds

const withdrawal = await client.withdraw({
  userId: 'user_123',
  asset: 'USDC',
  amount: '5000',
  destination: '0x...'
});

console.log(`Withdrawal ID: ${withdrawal.id}`);
console.log(`Status: ${withdrawal.status}`);

Market Data

Get Current Rates

const rates = await client.getRates();

for (const rate of rates) {
  console.log(`${rate.asset} ${rate.maturity}: Lend ${rate.lendRate * 100}%, Borrow ${rate.borrowRate * 100}%`);
}

Get Order Book

const orderBook = await client.getOrderBook({
  asset: 'USDC',
  maturity: '90d',
  depth: 10
});

console.log('Lend orders:', orderBook.lends);
console.log('Borrow orders:', orderBook.borrows);

Get Market Stats

const stats = await client.getMarketStats('USDC');

console.log({
  totalLent: stats.totalLent,
  totalBorrowed: stats.totalBorrowed,
  averageRate: stats.averageRate
});

Webhooks

Webhook Handler

import express from 'express';
import { CreditKit } from '@centuari/credit-kit';

const app = express();

app.post('/webhooks/centuari', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-centuari-signature'] as string;

  try {
    const event = CreditKit.verifyWebhook(
      req.body,
      signature,
      process.env.WEBHOOK_SECRET
    );

    switch (event.type) {
      case 'position.matched':
        console.log(`Position matched: ${event.data.positionId}`);
        break;
      case 'position.matured':
        console.log(`Position matured: ${event.data.positionId}`);
        break;
      case 'position.liquidated':
        console.log(`Position liquidated: ${event.data.positionId}`);
        break;
    }

    res.json({ received: true });
  } catch (err) {
    console.error('Webhook error:', err);
    res.status(400).json({ error: 'Invalid signature' });
  }
});

Event Types

import { WebhookEvent } from '@centuari/credit-kit';

type PositionMatchedEvent = WebhookEvent<'position.matched'>;
type PositionMaturedEvent = WebhookEvent<'position.matured'>;
type PositionLiquidatedEvent = WebhookEvent<'position.liquidated'>;

Error Handling

Error Types

import {
  CreditKitError,
  AuthenticationError,
  ValidationError,
  InsufficientFundsError,
  RateLimitError
} from '@centuari/credit-kit';

try {
  await client.lend({ ... });
} catch (error) {
  if (error instanceof InsufficientFundsError) {
    console.log(`Need ${error.required}, have ${error.available}`);
  } else if (error instanceof RateLimitError) {
    console.log(`Retry after ${error.retryAfter}ms`);
  } else if (error instanceof CreditKitError) {
    console.log(`Error: ${error.code} - ${error.message}`);
  }
}

Retries

Built-in retry logic for transient failures:
const client = new CreditKit({
  apiKey: '...',
  retries: 3,              // Number of retries
  retryDelay: 1000,        // Initial delay (ms)
  retryBackoff: 2          // Exponential backoff multiplier
});

TypeScript Support

Full TypeScript support with types:
import {
  CreditKit,
  Position,
  LendParams,
  BorrowParams,
  PositionStatus,
  Asset
} from '@centuari/credit-kit';

const params: LendParams = {
  userId: 'user_123',
  asset: 'USDC' as Asset,
  amount: '10000',
  rate: 0.08
};

const position: Position = await client.lend(params);

Testing

Mock Client

import { MockCreditKit } from '@centuari/credit-kit/testing';

const mockClient = new MockCreditKit();

// Configure mock responses
mockClient.onLend().resolves({
  positionId: 'mock_pos_123',
  status: 'active',
  rate: 0.08
});

// Use in tests
const position = await mockClient.lend({ ... });
expect(position.positionId).toBe('mock_pos_123');

Sandbox Testing

const sandbox = new CreditKit({
  apiKey: 'ck_test_...',
  environment: 'sandbox'
});

// Test with fake tokens
const position = await sandbox.lend({
  userId: 'test_user',
  asset: 'USDC',
  amount: '1000000' // Test with any amount
});

Examples

Complete Integration Example

import { CreditKit } from '@centuari/credit-kit';
import express from 'express';

const client = new CreditKit({ apiKey: process.env.API_KEY });
const app = express();

// User wants to lend
app.post('/api/lend', async (req, res) => {
  const { userId, amount } = req.body;

  try {
    const position = await client.easyLend({
      userId,
      asset: 'USDC',
      amount
    });

    res.json({
      success: true,
      position: {
        id: position.positionId,
        rate: `${(position.rate * 100).toFixed(2)}%`,
        maturity: position.maturity,
        projectedReturn: position.projectedReturn
      }
    });
  } catch (error) {
    res.status(400).json({ error: error.message });
  }
});

// User checks their positions
app.get('/api/positions/:userId', async (req, res) => {
  const { positions } = await client.listPositions({
    userId: req.params.userId
  });

  res.json({ positions });
});

// Webhook handler
app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
  const event = CreditKit.verifyWebhook(req.body, req.headers['x-centuari-signature'], process.env.WEBHOOK_SECRET);

  // Handle event...
  res.json({ received: true });
});

app.listen(3000);

API Reference

View complete API documentation