# ORO SDK for TypeScript

Official TypeScript SDK for the ORO Bittensor Subnet API.

This SDK is auto-generated from the OpenAPI specification using [@hey-api/openapi-ts](https://github.com/hey-api/openapi-ts).

## Installation

```bash
npm install @oro-ai/sdk @hey-api/client-fetch
```

## Quick Start

### Public API (No Auth Required)

```typescript
import { configurePublicClient, getLeaderboard, getTopAgent } from '@oro-ai/sdk';

// Configure the client
configurePublicClient('https://api.oro.ai');

// Get leaderboard
const { data: leaderboard } = await getLeaderboard();
leaderboard?.entries.forEach(entry => {
  console.log(`${entry.rank}. ${entry.miner_hotkey}: ${entry.final_score}`);
});

// Get top agent for emissions
const { data: top } = await getTopAgent();
if (top) {
  console.log(`Top miner: ${top.top_miner_hotkey} with score ${top.top_score}`);
}
```

### Authenticated API (Validators/Miners)

Use `configureBittensorAuth` to automatically sign all requests:

```typescript
import { configureBittensorAuth, claimWork, heartbeat, completeRun } from '@oro-ai/sdk';

// Configure with your wallet's signing function
configureBittensorAuth('https://api.oro.ai', {
  hotkey: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
  sign: (message) => {
    // Sign the message with your Bittensor wallet
    // Returns signature as hex string
    return wallet.sign(message);
  },
});

// All requests are now automatically authenticated!

// Validator: Claim work
const { data: work } = await claimWork();
if (work) {
  console.log(`Claimed eval run: ${work.eval_run_id}`);

  // Send heartbeat
  const { data: hb } = await heartbeat({ path: { eval_run_id: work.eval_run_id } });
  console.log(`Lease extended to: ${hb?.lease_expires_at}`);

  // Complete run
  const { data: result } = await completeRun({
    path: { eval_run_id: work.eval_run_id },
    body: {
      terminal_status: 'SUCCESS',
      validator_score: 0.85,
    },
  });
  console.log(`Completed! Eligible: ${result?.agent_version_became_eligible}`);
}
```

### Miner API

```typescript
import { configureBittensorAuth, submitAgent, getOwnedAgentVersionStatus } from '@oro-ai/sdk';

// Configure auth
configureBittensorAuth('https://api.oro.ai', {
  hotkey: minerHotkey,
  sign: (message) => minerWallet.sign(message),
});

// Submit an agent
const file = new File([agentCode], 'agent.py', { type: 'text/x-python' });
const { data: response } = await submitAgent({
  body: { file },
});

if (response?.admission_status === 'ACCEPTED') {
  console.log(`Submitted! Version ID: ${response.agent_version_id}`);

  // Check status
  const { data: status } = await getOwnedAgentVersionStatus({
    path: { agent_version_id: response.agent_version_id },
  });
  console.log(`State: ${status?.state}, Score: ${status?.final_score}`);
}
```

## Auth Helpers

### `configureBittensorAuth(baseUrl, config)`

Configures the client with automatic Bittensor authentication.

```typescript
import { configureBittensorAuth } from '@oro-ai/sdk';

configureBittensorAuth('https://api.oro.ai', {
  hotkey: '5GrwvaEF...',      // Your SS58 hotkey address
  sign: async (message) => {   // Signs "nonce:timestamp" format
    return wallet.sign(message);
  },
});
```

### `configurePublicClient(baseUrl)`

Configures the client for public (unauthenticated) endpoints only.

```typescript
import { configurePublicClient } from '@oro-ai/sdk';

configurePublicClient('https://api.oro.ai');
```

### `generateAuthHeaders(config, nonce?)`

Generates auth headers manually if needed.

```typescript
import { generateAuthHeaders } from '@oro-ai/sdk';

const headers = await generateAuthHeaders({
  hotkey: '5GrwvaEF...',
  sign: (msg) => wallet.sign(msg),
});
// { 'X-Hotkey': '...', 'X-Signature': '...', 'X-Nonce': '...', 'X-Timestamp': '...' }
```

## API Structure

All SDK functions follow the pattern:
```typescript
const { data, error, response } = await functionName({ path?, query?, body? });
```

- `data` - Parsed response body (typed)
- `error` - Error object if request failed
- `response` - Raw fetch Response object

## Development

### Running Tests

```bash
# Install dependencies
npm install

# Run tests
npm test

# Run tests in watch mode
npm run test:watch
```

### Regenerating the SDK

When the API changes:

```bash
cd packages/typescript
npm run generate
```

Or from the repo root:

```bash
./scripts/generate-typescript.sh
```

## License

MIT
