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

# Indexing with SQD

SOON integrates with SQD to provide powerful data indexing capabilities. This guide will walk you through using SQD's Solana API to index and query data from SOON's networks.

## Available Networks

SOON's data is accessible through these Subsquid archives:

```typescript theme={"system"}
const NETWORKS = {
  testnet: 'https://v2.archive.subsquid.io/network/soon-testnet',
  devnet: 'https://v2.archive.subsquid.io/network/soon-devnet'
  mainnet: 'https://v2.archive.subsquid.io/network/soon-mainnet'
}
```

## Understanding SQD Architecture

SQD uses a distributed worker system to efficiently serve blockchain data. Each worker handles a specific range of blocks, and queries are routed to appropriate workers through a central gateway.

### Core Concepts

1. **Router**: The main entry point that directs queries to specific workers

2. **Workers**: Distributed nodes that store and serve blockchain data

3. **Block Ranges**: Each worker handles a specific range of blocks

4. **Archive Height**: The latest block available in the archive

## Query Flow

### 1. Check Archive Height

First, verify the current height of the archive:

```typescript theme={"system"}
async function getArchiveHeight() {
  const response = await fetch(
    'https://v2.archive.subsquid.io/network/soon-testnet/height'
  )
  const height = await response.text()
  return parseInt(height)
  // Returns: 366804 (example)
}
```

### 2. Get Worker Assignment

Request a worker URL for your desired block range:

```typescript theme={"system"}
async function getWorker(blockNumber: number) {
  const response = await fetch(
    `https://v2.archive.subsquid.io/network/soon-testnet/${blockNumber}/worker`
  )
  const workerUrl = await response.text()
  // Returns: https://lm07.sqd-archive.net/worker/query/czM6Ly9zb29uLXRlc3RuZXQtMQ
  return workerUrl
}
```

### 3. Query Data

Make your data request to the assigned worker:

```typescript theme={"system"}
async function queryData(workerUrl: string, fromBlock: number) {
  const response = await fetch(workerUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    },
    body: JSON.stringify({
      type: "solana",
      fromBlock: fromBlock,
      fields: {
        instruction: {
          programId: true,
          data: true
        }
      },
      instructions: [
        { isCommitted: true }
      ]
    })
  })
  
  const data = await response.json()
  return data
}
```

Example Response:

```json theme={"system"}
[
  {
    "header": {
      "number": 366800,
      "hash": "11111111111111111111111111111111"
    },
    "instructions": [
      {
        "transactionIndex": 0,
        "instructionAddress": [0],
        "programId": "L1BLockinfo11111111111111111111111111111111",
        "data": "2JyQzTaqty3gKAuyyDEir3yZird2V55..."
      }
    ]
  }
]
```

## Additional Resources

For more advanced SQD features, configurations, and detailed API references, check out the <a href="https://docs.sqd.ai/" target="_blank" rel="noopener noreferrer">SQD documentation</a>. The official docs cover topics like:

* Advanced query patterns and optimizations
* Custom data transformations
* Real-time subscriptions and webhooks
* Performance tuning and monitoring
* Integration with popular frameworks

## Query Options

### Instruction Queries

Filter and fetch specific instruction data:

```typescript theme={"system"}
const instructionQuery = {
  type: "solana",
  fromBlock: startBlock,
  fields: {
    instruction: {
      programId: true,
      data: true,
      accounts: true  // Include account information
    }
  },
  instructions: [
    {
      programId: ["YourProgramID"],  // Filter by program
      isCommitted: true
    }
  ]
}
```

### Transaction Queries

Get full transaction details:

```typescript theme={"system"}
const transactionQuery = {
  type: "solana",
  fromBlock: startBlock,
  fields: {
    transaction: {
      feePayer: true,
      instructions: true,
      logs: true
    }
  },
  transactions: [
    {
      feePayer: ["SpecificFeePayer"]  // Optional filter
    }
  ]
}
```

### Log Queries

Fetch program logs:

```typescript theme={"system"}
const logQuery = {
  type: "solana",
  fromBlock: startBlock,
  fields: {
    log: {
      programId: true,
      message: true
    }
  },
  logs: [
    {
      kind: ["log", "data"],  // Filter by log type
      programId: ["YourProgramID"]  // Filter by program
    }
  ]
}
```

## Best Practices

### Handling Pagination

For large datasets, implement pagination:

```typescript theme={"system"}
async function fetchAllData(startBlock: number, endBlock: number) {
  let currentBlock = startBlock
  const results = []
  
  while (currentBlock <= endBlock) {
    const workerUrl = await getWorker(currentBlock)
    const data = await queryData(workerUrl, currentBlock)
    
    results.push(...data)
    
    // Update current block to last received block + 1
    const lastBlock = data[data.length - 1].header.number
    currentBlock = lastBlock + 1
  }
  
  return results
}
```

### Error Handling

Implement robust error handling:

```typescript theme={"system"}
async function fetchWithRetry(workerUrl: string, query: any, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await queryData(workerUrl, query)
      return response
    } catch (error) {
      if (i === retries - 1) throw error
      await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i)))
    }
  }
}
```

## Common Use Cases

### Track Program Interactions

Monitor specific program activities:

```typescript theme={"system"}
const programQuery = {
  type: "solana",
  fromBlock: startBlock,
  fields: {
    instruction: {
      programId: true,
      data: true,
      accounts: true
    },
    transaction: {
      logs: true
    }
  },
  instructions: [
    {
      programId: ["YourProgramID"],
      isCommitted: true
    }
  ]
}
```

### Monitor Account Activity

Track account changes and interactions:

```typescript theme={"system"}
const accountQuery = {
  type: "solana",
  fromBlock: startBlock,
  fields: {
    tokenBalance: {
      account: true,
      amount: true,
      owner: true
    }
  },
  tokenBalances: [
    {
      account: ["AccountToTrack"]
    }
  ]
}
```

## Rate Limits and Performance

* Keep block ranges reasonable (suggested: ≤1000 blocks per query)

* Cache worker URLs when querying consecutive blocks

* Implement exponential backoff for retries

* Consider using webhooks for real-time updates

## TypeScript Support

SQD provides TypeScript typings for better developer experience:

```typescript theme={"system"}
interface SQDQuery {
  type: 'solana'
  fromBlock: number
  fields: {
    instruction?: InstructionFields
    transaction?: TransactionFields
    log?: LogFields
  }
  instructions?: InstructionFilter[]
  transactions?: TransactionFilter[]
  logs?: LogFilter[]
}

// Use with your API calls
const query: SQDQuery = {
  type: 'solana',
  fromBlock: 366800,
  fields: {
    instruction: {
      programId: true,
      data: true
    }
  }
}
```
