# Saturn Indexer SDK

A TypeScript SDK for interacting with the Saturn Titan indexer.

## Requirements

- Node.js 20 or higher

## Installation

```bash
npm install @saturnbtcio/indexer-sdk
```

## Usage

### Basic API usage

Inputs and outputs for the SDK methods should be fully typed and will help you along in making valid requests.

```typescript
import { SaturnIndexerSDK } from '@saturnbtcio/indexer-sdk';

// Initialize with base URL
const sdk = new SaturnIndexerSDK('https://api.example.com');

// Make requests
const res = await sdk.api.pool.findByTokenFilter({
  name: ['token1', 'token2'],
  limit: 20,
  offset: 0,
});

// Check for success
if (res.status === 200) {
  console.log(res.data.response);
  console.log(res.data.offset);
}
```

### WebSocket Client

The SDK includes a WebSocket client for subscribing to real-time events.

#### Initializing the WebSocket Client

```typescript
import { WebSocketClient, EventType } from '@saturnbtcio/indexer-sdk';

const wsClient = new WebSocketClient({
  url: 'https://api.example.com/ws', // Will be converted to ws:// or wss:// automatically
  maxReconnectAttempts: 5, // Optional, defaults to 5 (0 for unlimited)
  reconnectInterval: 2000, // Optional, milliseconds between reconnect attempts
});
```

#### Subscribing to Events

You can subscribe to events in multiple ways:

```typescript
// Simple subscription to all events of a type
await wsClient.subscribe([EventType.Swap]);

// Subscribe to multiple event types at once
await wsClient.subscribe([EventType.Swap, EventType.Transaction]);

// Subscribe with filters
await wsClient.subscribeWithFilter(EventType.Swap, {
  assetPair: 'ETH/USDC', // Only receive swap events for this pair
});

// Subscribe to multiple events with different filters
await wsClient.subscribe([
  {
    event_type: EventType.Swap,
    filters: { assetPair: 'ETH/USDC' },
  },
  {
    event_type: EventType.Transaction,
    filters: { sender: '0x123abc...' },
  },
]);
```

#### Handling Events

Register event handlers to process events as they arrive:

```typescript
// Handle swap events
const unsubscribeSwaps = wsClient.on(EventType.Swap, (swapEvent) => {
  console.log(
    `Swap: ${swapEvent.amountIn} ${swapEvent.assetPair.base} → ${swapEvent.amountOut} ${swapEvent.assetPair.quote}`,
  );
  console.log(`Price: ${swapEvent.price}`);
});

// Handle transaction events
wsClient.on(EventType.Transaction, (transaction) => {
  console.log(`New transaction: ${transaction.hash}`);
});
```

#### Unsubscribing and Cleanup

```typescript
// Unsubscribe from all subscriptions for specific event types
await wsClient.unsubscribe([EventType.Swap]);

// Unsubscribe from a specific filter for an event type
await wsClient.unsubscribeFilter(EventType.Swap, { assetPair: 'ETH/USDC' });

// Unsubscribe from multiple specific filters
await wsClient.unsubscribeFilters([
  { 
    event_type: EventType.Swap, 
    filter: { assetPair: 'ETH/USDC' } 
  },
  { 
    event_type: EventType.Transaction, 
    filter: { sender: '0x123abc...' } 
  }
]);

// Unregister event handler with the function returned by .on()
unsubscribeSwaps();

// Close the WebSocket connection
wsClient.close();
```

#### Reconnection Handling

The WebSocket client automatically handles reconnection if the connection is lost. You can configure this behavior with `maxReconnectAttempts` and `reconnectInterval` options.

#### Connection Event Handling

In addition to data events, you can also listen for WebSocket connection events:

```typescript
import { WebSocketClient, ConnectionEventType } from '@saturnbtcio/indexer-sdk';

const wsClient = new WebSocketClient({
  url: 'https://api.example.com/ws',
});

// Define handlers as standalone functions to be able to reference them for removal
const onConnected = () => {
  console.log('Connection established!');
};

const onDisconnect = (event) => {
  console.log(`Disconnected with code ${event.data.code}`);
};

// Register handlers
wsClient.onConnection(ConnectionEventType.Connected, onConnected);
wsClient.onConnection(ConnectionEventType.Disconnected, onDisconnect);

// Later, remove specific handlers
wsClient.offConnection(ConnectionEventType.Connected, onConnected);

// Or remove all handlers for a specific event type
wsClient.offAllConnections(ConnectionEventType.Disconnected);

// Or remove all connection event handlers
wsClient.offAllConnectionEvents();

// The returned function approach still works too
const removeHandler = wsClient.onConnection(ConnectionEventType.Error, (event) => {
  console.error('Connection error:', event.data);
});

// Later
removeHandler(); // This will remove the handler
```

Connection events can be especially useful for:
- Subscribing to topics when the connection is established
- Displaying connection status to users
- Implementing custom reconnection logic
- Cleaning up resources on disconnection

#### Complete Example

```typescript
import { WebSocketClient, EventType } from '@saturnbtcio/indexer-sdk';

async function main() {
  // Initialize client
  const wsClient = new WebSocketClient({
    url: 'https://api.example.com/ws',
  });

  // Connect and subscribe
  await wsClient.connect();

  // Subscribe to swap events with a filter
  await wsClient.subscribeWithFilter(EventType.Swap, {
    assetPair: 'ETH/USDC',
  });

  // Register event handler
  wsClient.on(EventType.Swap, (swapEvent) => {
    console.log(
      `Swap at ${swapEvent.createdAt}: ${swapEvent.amountIn} ${swapEvent.assetPair.base} → ${swapEvent.amountOut} ${swapEvent.assetPair.quote}`,
    );
  });

  // Keep connection alive for this example
  console.log('Listening for events. Press Ctrl+C to exit.');
}

main().catch(console.error);
```
