Monitor Orca Whirlpool swap instructions to build DEX analytics dashboards, analyze liquidity patterns, or create price feeds.
Use Case
DEX swap tracking enables you to:
- Build DEX trading analytics and volume trackers
- Monitor liquidity pool activity
- Analyze trading patterns and arbitrage
- Create real-time price feeds
Code Example
curl --compressed -X POST "https://portal.sqd.dev/datasets/solana-mainnet/stream" \
-H 'Content-Type: application/json' \
-d '{
"type": "solana",
"fromBlock": 280000000,
"toBlock": 280000003,
"fields": {
"block": {
"number": true,
"timestamp": true
},
"instruction": {
"programId": true,
"accounts": true,
"data": true,
"transactionIndex": true
}
},
"instructions": [{
"programId": ["whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"],
"d8": ["0xf8c69e91e17587c8"]
}]
}'
import { DataSource } from "@subsquid/portal-client";
const dataSource = new DataSource({
network: "solana-mainnet",
});
// Orca Whirlpool program ID
const WHIRLPOOL_PROGRAM = "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc";
// Swap instruction discriminator (first 8 bytes)
const SWAP_D8 = "0xf8c69e91e17587c8";
const blocks = await dataSource.getBlocks({
from: 280000000,
to: 280000003,
fields: {
block: { number: true, timestamp: true },
instruction: {
programId: true,
accounts: true,
data: true,
transactionIndex: true,
},
},
instructions: [
{
programId: [WHIRLPOOL_PROGRAM],
d8: [SWAP_D8],
},
],
});
// Process swaps
for (const block of blocks) {
for (const instruction of block.instructions) {
console.log({
slot: block.header.number,
timestamp: block.header.timestamp,
pool: instruction.accounts[2], // Whirlpool account (typically at index 2)
txIndex: instruction.transactionIndex,
// Decode swap amounts from instruction.data as needed
});
}
}
import requests
import json
url = "https://portal.sqd.dev/datasets/solana-mainnet/stream"
headers = {"Content-Type": "application/json"}
# Orca Whirlpool program ID
whirlpool_program = "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"
# Swap instruction discriminator
swap_d8 = "0xf8c69e91e17587c8"
payload = {
"type": "solana",
"fromBlock": 280000000,
"toBlock": 280000003,
"fields": {
"block": {
"number": True,
"timestamp": True
},
"instruction": {
"programId": True,
"accounts": True,
"data": True,
"transactionIndex": True
}
},
"instructions": [{
"programId": [whirlpool_program],
"d8": [swap_d8]
}]
}
response = requests.post(url, headers=headers, json=payload)
for line in response.text.strip().split('\n'):
block = json.loads(line)
for instruction in block.get('instructions', []):
print({
"slot": block['header']['number'],
"timestamp": block['header']['timestamp'],
"pool": instruction['accounts'][2] if len(instruction['accounts']) > 2 else None,
"txIndex": instruction['transactionIndex']
})
Try it yourself with the interactive query interface below:
Key Parameters
| Parameter | Description |
|---|
programId | DEX program address (e.g., Orca Whirlpool) |
d8 | 8-byte instruction discriminator for swap instruction |
accounts | Instruction account addresses (includes pool, tokens, etc.) |
data | Instruction data payload (contains swap amounts) |
Different DEX protocols use different instruction discriminators. Check the
program IDL to find the correct discriminator for your target DEX.
Expected Output
{
"header": {
"number": 259985000,
"timestamp": 1697544779
},
"instructions": [
{
"programId": "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc",
"accounts": ["7qbRF6YsyGuLUVs6Y1q64bdVrfe4ZcUUz1JRdoVNUJnm", "..."],
"data": "base58encodeddata...",
"transactionIndex": 0
}
]
}
Track Specific Pool
Monitor swaps for a specific trading pair:
curl --compressed -X POST "https://portal.sqd.dev/datasets/solana-mainnet/stream" \
-H 'Content-Type: application/json' \
-d '{
"type": "solana",
"fromBlock": 280000000,
"toBlock": 280000003,
"fields": {
"instruction": {
"programId": true,
"accounts": true,
"data": true
}
},
"instructions": [{
"programId": ["whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"],
"d8": ["0xf8c69e91e17587c8"],
"accounts": ["7qbRF6YsyGuLUVs6Y1q64bdVrfe4ZcUUz1JRdoVNUJnm"]
}]
}'
const USDC_SOL_POOL = "7qbRF6YsyGuLUVs6Y1q64bdVrfe4ZcUUz1JRdoVNUJnm"; // USDC/SOL pool
const blocks = await dataSource.getBlocks({
from: 280000000,
to: 280000003,
fields: {
instruction: { programId: true, accounts: true, data: true },
},
instructions: [
{
programId: ["whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"],
d8: ["0xf8c69e91e17587c8"],
accounts: [USDC_SOL_POOL], // Filter by pool account
},
],
});
usdc_sol_pool = "7qbRF6YsyGuLUVs6Y1q64bdVrfe4ZcUUz1JRdoVNUJnm"
payload = {
"type": "solana",
"fromBlock": 280000000,
"toBlock": 280000003,
"fields": {
"instruction": {
"programId": True,
"accounts": True,
"data": True
}
},
"instructions": [{
"programId": ["whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"],
"d8": ["0xf8c69e91e17587c8"],
"accounts": [usdc_sol_pool]
}]
}
Decode Swap Amounts
Swap amounts are encoded in the data field. Here’s how to decode them for Orca Whirlpool:
- Filter by pool address: Query specific pools instead of all swaps
- Use slot ranges: Process data in 10k-50k slot batches
- Decode off-chain: Decode swap amounts in your application, not in the query
- Combine with token balances: Use token balances to track actual amounts transferred
Query Instructions
General instruction querying
Token Transfers
Track token movements
Query Transactions
Monitor wallet activity
API Reference
View complete API docs