> For the complete documentation index, see [llms.txt](https://docs.ckboost.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ckboost.com/integration/client-package.md).

# Client Package

## @ckboost/client SDK

### Overview

The `@ckboost/client` SDK provides a simple, type-safe way to integrate CKBoost acceleration services into your dApp. CKBoost reduces ckBTC conversion times from 1 hour (6 confirmations) to 7-10 minutes (1-2 confirmations) through a network of liquidity providers. We are planning to expend ckBoost and support other chain-key tokens (ckETH, in the future ckSOL, etc)&#x20;

#### Key Features

* 🚀 **Fast Integration**: Simple API with just two main functions
* 📝 **TypeScript First**: Full type safety and excellent developer experience
* ⚡ **Real-time Monitoring**: Track boost request status changes
* 🔒 **Secure**: Built on Internet Computer Protocol (ICP)
* 🎯 **dApp Ready**: Designed specifically for frontend integration

### Installation

```bash
npm install @ckboost/client
```

```bash
yarn add @ckboost/client
```

```bash
pnpm add @ckboost/client
```

### Quick Start

```typescript
import { ckTESTBTCClient, BoostStatus } from '@ckboost/client';

// Initialize client
const client = new ckTESTBTCClient({
  host: 'https://icp-api.io',
  timeout: 30000
});

// Create a boost request
const result = await client.generateDepositAddress({
  amount: '0.01',              // 0.01 ckTESTBTC
  maxFeePercentage: 1.5        // 1.5% maximum fee
});

if (result.success) {
  const { requestId, address, explorerUrl } = result.data;
  
  // Show deposit address to user
  console.log(`Send Bitcoin to: ${address}`);
  console.log(`Track at: ${explorerUrl}`);
  
  // Monitor status
  const statusResult = await client.getBoostRequest(requestId);
  if (statusResult.success) {
    console.log(`Status: ${statusResult.data.status}`);
  }
}
```

### API Reference

#### Client Initialization

**`ckTESTBTCClient`**

Creates a new client instance for ckTESTBTC (Bitcoin testnet).

```typescript
import { ckTESTBTCClient } from '@ckboost/client';

const client = new ckTESTBTCClient(config?: ClientConfig);
```

**Parameters:**

| Parameter | Type           | Default | Description                   |
| --------- | -------------- | ------- | ----------------------------- |
| `config`  | `ClientConfig` | `{}`    | Optional client configuration |

**ClientConfig:**

```typescript
interface ClientConfig {
  host?: string;     // ICP host URL (default: 'https://icp-api.io')
  timeout?: number;  // Request timeout in ms (default: 30000)
}
```

#### Core Methods

**`generateDepositAddress()`**

Creates a new boost request and returns deposit information.

```typescript
async generateDepositAddress(
  params: DepositAddressParams
): Promise<ApiResponse<DepositInfo>>
```

**Parameters:**

```typescript
interface DepositAddressParams {
  amount: string;                    // Amount in ckTESTBTC (e.g., "0.01")
  maxFeePercentage: number;          // Maximum fee as percentage (e.g., 1.5)
  confirmationsRequired?: number;    // Override default confirmations
  preferredBooster?: string;         // Specific booster principal ID
}
```

**Returns:**

```typescript
interface DepositInfo {
  requestId: string;           // Unique request identifier
  address: string;             // Bitcoin deposit address
  amount: string;              // Amount in ckTESTBTC
  amountRaw: string;           // Amount in satoshis
  maxFeePercentage: number;    // Maximum fee percentage
  explorerUrl: string;         // Block explorer URL
}
```

**`getBoostRequest()`**

Retrieves detailed information about a specific boost request.

```typescript
async getBoostRequest(
  requestId: string
): Promise<ApiResponse<BoostRequest>>
```

**Parameters:**

| Parameter   | Type     | Description                   |
| ----------- | -------- | ----------------------------- |
| `requestId` | `string` | The unique request identifier |

**Returns:**

```typescript
interface BoostRequest {
  id: string;                    // Request ID
  status: BoostStatus;           // Current status
  amount: string;                // Requested amount in ckTESTBTC
  receivedAmount: string;        // Amount received so far
  maxFeePercentage: number;      // Maximum fee percentage
  confirmationsRequired: number;  // Required confirmations
  depositAddress?: string;       // Bitcoin deposit address
  booster?: string;             // Assigned booster principal
  createdAt: number;            // Creation timestamp (ms)
  updatedAt: number;            // Last update timestamp (ms)
}
```

**`getPendingBoostRequests()`**

Retrieves all pending boost requests.

```typescript
async getPendingBoostRequests(): Promise<ApiResponse<BoostRequest[]>>
```

#### Utility Methods

**`getTokenConfig()`**

Returns the current token configuration.

```typescript
getTokenConfig(): TokenConfig
```

**Returns:**

```typescript
interface TokenConfig {
  token: SupportedToken;         // Token type
  minimumAmount: string;         // Minimum boost amount
  maximumAmount: string;         // Maximum boost amount
  standardFee: string;           // Standard fee amount
  confirmationsRequired: number; // Default confirmations
  decimals: number;             // Token decimals (8 for Bitcoin)
  isTestnet: boolean;           // Whether this is testnet
  blockExplorerUrl: string;     // Block explorer base URL
}
```

**`rawToTokenAmount()`**

Converts raw amount (satoshis) to token amount (ckTESTBTC).

```typescript
rawToTokenAmount(rawAmount: string | bigint): string
```

**`tokenToRawAmount()`**

Converts token amount (ckTESTBTC) to raw amount (satoshis).

```typescript
tokenToRawAmount(tokenAmount: string): string
```

### Types Reference

#### Enums

**`BoostStatus`**

```typescript
enum BoostStatus {
  PENDING = 'pending',       // Waiting for Bitcoin deposit
  ACTIVE = 'active',         // Processing the boost
  COMPLETED = 'completed',   // ckTESTBTC delivered
  CANCELLED = 'cancelled'    // Request cancelled
}
```

**`SupportedToken`**

```typescript
enum SupportedToken {
  CK_TEST_BTC = 'ckTESTBTC'
}
```

**`CKBoostErrorType`**

```typescript
enum CKBoostErrorType {
  INVALID_AMOUNT = 'INVALID_AMOUNT',
  NETWORK_ERROR = 'NETWORK_ERROR',
  REQUEST_NOT_FOUND = 'REQUEST_NOT_FOUND',
  CANISTER_ERROR = 'CANISTER_ERROR',
  VALIDATION_ERROR = 'VALIDATION_ERROR',
  UNKNOWN_ERROR = 'UNKNOWN_ERROR'
}
```

#### Response Types

**`ApiResponse<T>`**

All API methods return this discriminated union type:

```typescript
type ApiResponse<T> = 
  | { success: true; data: T; }
  | { success: false; error: CKBoostError; };

interface CKBoostError {
  type: CKBoostErrorType;
  message: string;
  details?: any;
}
```

### Examples

#### Basic Integration

```typescript
import { ckTESTBTCClient, BoostStatus } from '@ckboost/client';

class BitcoinAccelerator {
  private client = new ckTESTBTCClient();

  async createBoost(amount: string, maxFee: number) {
    const result = await this.client.generateDepositAddress({
      amount,
      maxFeePercentage: maxFee
    });

    if (result.success) {
      return {
        success: true,
        depositAddress: result.data.address,
        requestId: result.data.requestId,
        explorerUrl: result.data.explorerUrl
      };
    } else {
      return {
        success: false,
        error: result.error.message
      };
    }
  }

  async checkStatus(requestId: string) {
    const result = await this.client.getBoostRequest(requestId);
    
    if (result.success) {
      const request = result.data;
      return {
        status: request.status,
        progress: {
          requested: request.amount,
          received: request.receivedAmount,
          percentage: (parseFloat(request.receivedAmount) / parseFloat(request.amount)) * 100
        },
        isComplete: request.status === BoostStatus.COMPLETED
      };
    }
    
    return { error: result.error.message };
  }
}
```

#### React Hook Integration

```typescript
import { useState, useEffect } from 'react';
import { ckTESTBTCClient, BoostRequest, BoostStatus } from '@ckboost/client';

export function useBoostRequest(requestId?: string) {
  const [request, setRequest] = useState<BoostRequest | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const client = new ckTESTBTCClient();

  useEffect(() => {
    if (!requestId) return;

    const pollStatus = async () => {
      setLoading(true);
      setError(null);

      try {
        const result = await client.getBoostRequest(requestId);
        
        if (result.success) {
          setRequest(result.data);
        } else {
          setError(result.error.message);
        }
      } catch (err) {
        setError('Failed to fetch boost request');
      } finally {
        setLoading(false);
      }
    };

    pollStatus();
    
    // Poll every 10 seconds until complete
    const interval = setInterval(() => {
      if (request?.status !== BoostStatus.COMPLETED && 
          request?.status !== BoostStatus.CANCELLED) {
        pollStatus();
      }
    }, 10000);

    return () => clearInterval(interval);
  }, [requestId, request?.status]);

  return { request, loading, error };
}
```

#### Complete dApp Integration

```typescript
import { ckTESTBTCClient, BoostStatus } from '@ckboost/client';

class CKBoostService {
  private client: ckTESTBTCClient;
  private activeRequests = new Map<string, NodeJS.Timeout>();

  constructor() {
    this.client = new ckTESTBTCClient({
      host: 'https://icp-api.io',
      timeout: 30000
    });
  }

  async createBoostRequest(amount: string, maxFeePercentage: number) {
    // Validate amount first
    const config = this.client.getTokenConfig();
    const amountNum = parseFloat(amount);
    const minAmount = parseFloat(config.minimumAmount);
    const maxAmount = parseFloat(config.maximumAmount);

    if (amountNum < minAmount || amountNum > maxAmount) {
      return {
        success: false,
        error: `Amount must be between ${minAmount} and ${maxAmount} ckTESTBTC`
      };
    }

    const result = await this.client.generateDepositAddress({
      amount,
      maxFeePercentage
    });

    if (result.success) {
      // Start monitoring this request
      this.startMonitoring(result.data.requestId);
      
      return {
        success: true,
        data: result.data
      };
    }

    return {
      success: false,
      error: result.error.message
    };
  }

  private startMonitoring(requestId: string, onUpdate?: (request: BoostRequest) => void) {
    // Clear existing timeout for this request
    if (this.activeRequests.has(requestId)) {
      clearTimeout(this.activeRequests.get(requestId)!);
    }

    const poll = async () => {
      const result = await this.client.getBoostRequest(requestId);
      
      if (result.success) {
        const request = result.data;
        
        // Notify about update
        if (onUpdate) {
          onUpdate(request);
        }

        // Continue polling if not in final state
        if (request.status !== BoostStatus.COMPLETED && 
            request.status !== BoostStatus.CANCELLED) {
          const timeout = setTimeout(poll, 10000); // Poll every 10 seconds
          this.activeRequests.set(requestId, timeout);
        } else {
          this.activeRequests.delete(requestId);
        }
      }
    };

    // Start immediate poll
    poll();
  }

  stopMonitoring(requestId: string) {
    if (this.activeRequests.has(requestId)) {
      clearTimeout(this.activeRequests.get(requestId)!);
      this.activeRequests.delete(requestId);
    }
  }

  destroy() {
    // Clean up all active monitoring
    this.activeRequests.forEach(timeout => clearTimeout(timeout));
    this.activeRequests.clear();
  }
}
```

### Error Handling

#### Error Types

The SDK provides specific error types to help you handle different scenarios:

```typescript
import { CKBoostErrorType } from '@ckboost/client';

async function handleBoostRequest() {
  const result = await client.generateDepositAddress({
    amount: '0.01',
    maxFeePercentage: 1.5
  });

  if (!result.success) {
    switch (result.error.type) {
      case CKBoostErrorType.INVALID_AMOUNT:
        // Show amount validation error to user
        alert('Please enter a valid amount between the minimum and maximum limits');
        break;
        
      case CKBoostErrorType.NETWORK_ERROR:
        // Show network error and retry option
        alert('Network error. Please check your connection and try again');
        break;
        
      case CKBoostErrorType.CANISTER_ERROR:
        // Backend service error
        alert('Service temporarily unavailable. Please try again later');
        break;
        
      default:
        // Generic error handling
        alert(`Error: ${result.error.message}`);
    }
  }
}
```

#### Best Practices

1. **Always check the `success` property** before accessing `data`
2. **Provide user-friendly error messages** based on error types
3. **Implement retry logic** for network errors
4. **Validate amounts** before making requests
5. **Monitor request status** until completion

### Configuration

#### Canister IDs

The SDK includes the required canister IDs:

```typescript
import { ckTESTBTC_CANISTER_IDS } from '@ckboost/client';

console.log('Backend Canister:', ckTESTBTC_CANISTER_IDS.CKBOOST_BACKEND);
console.log('Ledger Canister:', ckTESTBTC_CANISTER_IDS.CKTESTBTC_LEDGER);
```

#### Network Configuration

For production applications, use the default configuration:

```typescript
const client = new ckTESTBTCClient({
  host: 'https://icp-api.io',  // Production ICP host
  timeout: 30000               // 30 second timeout
});
```

For development, you might want to use a local replica:

```typescript
const client = new ckTESTBTCClient({
  host: 'http://localhost:4943',  // Local dfx replica
  timeout: 10000                  // Shorter timeout for local testing
});
```

### Monitoring and Real-time Updates

#### Polling Strategy

For production applications, implement efficient polling:

```typescript
class BoostMonitor {
  private intervals = new Map<string, NodeJS.Timeout>();

  startMonitoring(requestId: string, callback: (request: BoostRequest) => void) {
    let attempts = 0;
    const maxAttempts = 360; // Monitor for 1 hour max (10s intervals)
    
    const poll = async () => {
      attempts++;
      
      const result = await client.getBoostRequest(requestId);
      if (result.success) {
        const request = result.data;
        callback(request);
        
        // Stop if complete or max attempts reached
        if (request.status === BoostStatus.COMPLETED || 
            request.status === BoostStatus.CANCELLED ||
            attempts >= maxAttempts) {
          this.stopMonitoring(requestId);
          return;
        }
      }
      
      // Continue polling with exponential backoff
      const delay = Math.min(10000 + (attempts * 1000), 30000);
      const timeout = setTimeout(poll, delay);
      this.intervals.set(requestId, timeout);
    };
    
    poll();
  }
  
  stopMonitoring(requestId: string) {
    const interval = this.intervals.get(requestId);
    if (interval) {
      clearTimeout(interval);
      this.intervals.delete(requestId);
    }
  }
}
```

#### WebSocket Alternative

For real-time updates, consider implementing WebSocket connections to the backend canister (when available) instead of polling.

### Troubleshooting

#### Common Issues

**Import Errors**

```typescript
// ❌ Don't do this
import CKBoostClient from '@ckboost/client';

// ✅ Do this
import { ckTESTBTCClient } from '@ckboost/client';
```

**Type Errors**

Make sure you have TypeScript configured properly:

```json
// tsconfig.json
{
  "compilerOptions": {
    "moduleResolution": "node",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true
  }
}
```

**Network Errors**

If you're getting network errors:

1. Check your internet connection
2. Verify the ICP host URL is correct
3. Ensure the canister IDs are valid
4. Try increasing the timeout value

### Support

* **Documentation**: [docs.ckboost.com](https://docs.ckboost.com)
* **GitHub**: [github.com/ckboost/ckboost-packages](https://github.com/ckboost/ckboost-packages)
* **Issues**: Report bugs and feature requests on GitHub


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.ckboost.com/integration/client-package.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
