> ## Documentation Index
> Fetch the complete documentation index at: https://dubhe.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Dubhe Engine Client SDK

> Complete TypeScript SDK for building frontend applications with Dubhe Engine

<div className="api-hero">
  <h1>🔧 Dubhe Engine Client SDK</h1>

  <p className="api-subtitle">
    Type-safe TypeScript SDK for seamless blockchain interaction
  </p>

  <div className="api-badges">
    <span className="badge">v2.0.0</span>
    <span className="badge">TypeScript</span>
    <span className="badge">Real-time</span>
  </div>
</div>

<Info>
  **Package:** `@0xobelisk/dubhe-client`\
  **License:** Apache-2.0\
  **GitHub:** [View Source](https://github.com/0xobelisk/dubhe)
</Info>

## 📦 Installation

<Tabs>
  <Tab title="npm">
    ```bash theme={null}
    npm install @0xobelisk/dubhe-client
    ```
  </Tab>

  <Tab title="yarn">
    ```bash theme={null}
    yarn add @0xobelisk/dubhe-client
    ```
  </Tab>

  <Tab title="pnpm">
    ```bash theme={null}
    pnpm add @0xobelisk/dubhe-client
    ```
  </Tab>
</Tabs>

## ⚡ Quick Start

```typescript theme={null}
import { DubheClient } from '@0xobelisk/dubhe-client';

const client = new DubheClient({
  network: 'devnet',
  packageId: 'YOUR_PACKAGE_ID'
});

// Query component data
const player = await client.getComponent({
  entity: 'PLAYER_ENTITY_ID',
  component: 'PlayerComponent'
});

// Execute system function
const txb = await client.tx.player_system.move({
  player: 'PLAYER_ID',
  direction: { x: 10, y: 5 }
});

const result = await client.signAndExecute(txb);
```

## 🏗️ DubheClient Class

### Constructor

```typescript theme={null}
new DubheClient(config: DubheClientConfig)
```

#### DubheClientConfig

| Property    | Type                                               | Required | Description               |
| ----------- | -------------------------------------------------- | -------- | ------------------------- |
| `network`   | `'mainnet' \| 'testnet' \| 'devnet' \| 'localnet'` | ✅        | Sui network to connect to |
| `packageId` | `string`                                           | ✅        | Your deployed package ID  |
| `endpoint`  | `string`                                           | ❌        | Custom RPC endpoint       |
| `options`   | `ClientOptions`                                    | ❌        | Additional configuration  |

#### ClientOptions

| Property              | Type      | Default | Description                                  |
| --------------------- | --------- | ------- | -------------------------------------------- |
| `enableCache`         | `boolean` | `false` | Enable query result caching                  |
| `cacheTimeout`        | `number`  | `30000` | Cache timeout in milliseconds                |
| `retryAttempts`       | `number`  | `3`     | Number of retry attempts for failed requests |
| `subscriptionTimeout` | `number`  | `60000` | WebSocket subscription timeout               |
| `gasPrice`            | `number`  | `1000`  | Default gas price for transactions           |

## 📊 Component Operations

<Tip>
  Components are the data containers in Dubhe's ECS architecture. Use these methods to read and query on-chain state.
</Tip>

### getComponent()

Retrieve a single component for an entity.

```typescript theme={null}
getComponent<T>(params: GetComponentParams): Promise<T | null>
```

#### Parameters

```typescript theme={null}
interface GetComponentParams {
  entity: string      // Entity ID
  component: string   // Component name (must match Move struct name)
}
```

#### Example

```typescript theme={null}
const playerData = await client.getComponent({
  entity: '0x123...',
  component: 'PlayerComponent'
});

if (playerData) {
  console.log(`Player health: ${playerData.health}`);
  console.log(`Player level: ${playerData.level}`);
}
```

### queryComponents()

Query multiple components with filtering.

```typescript theme={null}
queryComponents<T>(params: QueryComponentsParams): Promise<T[]>
```

#### Parameters

```typescript theme={null}
interface QueryComponentsParams {
  component: string           // Component name
  filter?: ComponentFilter    // Optional filtering criteria
  limit?: number             // Maximum number of results
  offset?: number            // Pagination offset
}

interface ComponentFilter {
  [field: string]: any       // Field-specific filters
  entityId?: {
    $in?: string[]          // Match any of these entity IDs
    $nin?: string[]         // Exclude these entity IDs
  }
}
```

#### Example

```typescript theme={null}
// Get all players with health > 50
const alivePlayers = await client.queryComponents({
  component: 'PlayerComponent',
  filter: {
    health: { $gt: 50 }
  },
  limit: 100
});

// Get specific players
const specificPlayers = await client.queryComponents({
  component: 'PlayerComponent',
  filter: {
    entityId: { $in: ['0x123...', '0x456...'] }
  }
});
```

## 💫 Transaction Operations

<Warning>
  Always ensure you have sufficient SUI for gas fees before executing transactions.
</Warning>

### System Transactions

Access generated system transaction builders through the `tx` property:

```typescript theme={null}
client.tx.system_name.function_name(params)
```

#### Example

```typescript theme={null}
// Player movement system
const moveTxb = await client.tx.player_system.move({
  player: 'PLAYER_ID',
  direction: { x: 10, y: 5 }
});

// Battle system
const attackTxb = await client.tx.battle_system.attack({
  attacker: 'ATTACKER_ID',
  target: 'TARGET_ID',
  weapon: 'WEAPON_ID'
});

// Inventory system
const equipTxb = await client.tx.inventory_system.equip_item({
  player: 'PLAYER_ID',
  item: 'ITEM_ID',
  slot: 'weapon'
});
```

### signAndExecute()

Sign and execute a transaction block.

```typescript theme={null}
signAndExecute(txb: TransactionBlock): Promise<TransactionResult>
```

#### TransactionResult

```typescript theme={null}
interface TransactionResult {
  digest: string                    // Transaction hash
  effects: TransactionEffects       // Transaction effects
  events: Event[]                   // Emitted events
  gasUsed: number                   // Gas consumed
  success: boolean                  // Transaction success status
}
```

#### Example

```typescript theme={null}
try {
  const result = await client.signAndExecute(moveTxb);
  
  if (result.success) {
    console.log('Transaction successful:', result.digest);
    console.log('Gas used:', result.gasUsed);
  }
} catch (error) {
  console.error('Transaction failed:', error.message);
}
```

## 🔄 Real-time Subscriptions

<Note>
  Subscriptions use WebSocket connections for real-time updates. Remember to clean up subscriptions when components unmount.
</Note>

### subscribe()

Subscribe to real-time component updates.

```typescript theme={null}
subscribe<T>(
  params: SubscribeParams, 
  callback: (data: T) => void
): () => void
```

#### Parameters

```typescript theme={null}
interface SubscribeParams {
  entity?: string       // Specific entity ID
  component: string     // Component name
  filter?: ComponentFilter  // Optional filtering
}
```

#### Example

```typescript theme={null}
// Subscribe to a specific player
const unsubscribe = client.subscribe({
  entity: 'PLAYER_ID',
  component: 'PlayerComponent'
}, (updatedPlayer) => {
  console.log('Player updated:', updatedPlayer);
  updateUI(updatedPlayer);
});

// Subscribe to all players
const unsubscribeAll = client.subscribe({
  component: 'PlayerComponent'
}, (players) => {
  console.log('Players updated:', players.length);
  updatePlayerList(players);
});

// Clean up subscriptions
unsubscribe();
unsubscribeAll();
```

### subscribeToComponent()

Subscribe to all entities of a specific component type.

```typescript theme={null}
subscribeToComponent<T>(
  componentName: string,
  callback: (entities: ComponentData<T>[]) => void
): () => void
```

#### Example

```typescript theme={null}
const unsubscribe = client.subscribeToComponent(
  'PlayerComponent',
  (entities) => {
    entities.forEach(entity => {
      console.log(`Entity ${entity.id} updated:`, entity.data);
    });
  }
);
```

## ⚠️ Error Handling

### Common Errors

| Error Code            | Description                         | Solution                           |
| --------------------- | ----------------------------------- | ---------------------------------- |
| `COMPONENT_NOT_FOUND` | Component doesn't exist for entity  | Check entity ID and component name |
| `INSUFFICIENT_GAS`    | Not enough SUI for transaction fees | Add SUI to wallet                  |
| `INVALID_SIGNATURE`   | Transaction signature invalid       | Check wallet connection            |
| `NETWORK_ERROR`       | Cannot connect to Sui network       | Check network configuration        |
| `PACKAGE_NOT_FOUND`   | Package ID not found                | Verify package deployment          |

### Error Handling Example

```typescript theme={null}
try {
  const component = await client.getComponent({
    entity: entityId,
    component: 'PlayerComponent'
  });
} catch (error) {
  switch (error.code) {
    case 'COMPONENT_NOT_FOUND':
      console.log('Player component not found');
      break;
    case 'NETWORK_ERROR':
      console.log('Network connection failed');
      break;
    default:
      console.error('Unexpected error:', error);
  }
}
```

## 🚀 Performance Tips

<Accordion title="Best Practices for Optimal Performance">
  1. **Enable caching** for frequently accessed data
  2. **Batch operations** to reduce network calls
  3. **Use selective subscriptions** to minimize data transfer
  4. **Implement pagination** for large datasets
  5. **Handle errors gracefully** with retry logic
</Accordion>

### Caching

Enable caching for frequently accessed data:

```typescript theme={null}
const client = new DubheClient({
  network: 'devnet',
  packageId: '0x...',
  options: {
    enableCache: true,
    cacheTimeout: 30000  // 30 seconds
  }
});
```

### Batch Operations

Batch multiple queries for better performance:

```typescript theme={null}
// Instead of multiple getComponent calls
const [player, inventory, stats] = await Promise.all([
  client.getComponent({ entity: id, component: 'PlayerComponent' }),
  client.getComponent({ entity: id, component: 'InventoryComponent' }),
  client.getComponent({ entity: id, component: 'StatsComponent' })
]);
```

### Selective Subscriptions

Only subscribe to components you actively display:

```typescript theme={null}
// Good: Subscribe only to visible players
const unsubscribe = client.subscribe({
  component: 'PlayerComponent',
  filter: { zone: currentZone }
}, updateVisiblePlayers);

// Avoid: Subscribing to all entities
```

## 🎯 Next Steps

<CardGroup cols={3}>
  <Card title="Smart Contracts" icon="file-contract" href="/api-reference/engine/smart-contracts">
    Explore Move contract interfaces
  </Card>

  <Card title="Schema Definitions" icon="database" href="/api-reference/engine/schemas">
    Understand data structures
  </Card>

  <Card title="Tutorial" icon="graduation-cap" href="/tutorials/first-dapp">
    Build your first DApp
  </Card>
</CardGroup>

<style>
  {`
    .api-hero {
      background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
      padding: 2.5rem;
      border-radius: 1rem;
      text-align: center;
      color: white;
      margin-bottom: 2rem;
    }

    .api-subtitle {
      font-size: 1.125rem;
      margin-top: 1rem;
      opacity: 0.95;
    }

    .api-badges {
      display: flex;
      justify-content: center;
      gap: 1rem;
      margin-top: 1.5rem;
    }

    .badge {
      padding: 0.5rem 1rem;
      border-radius: 2rem;
      font-size: 0.875rem;
      font-weight: 600;
      background: rgba(255, 255, 255, 0.2);
    }
    `}
</style>
