Skip to main content
Monitor new program deployments on Solana to track program launches, analyze deployment trends, or build program discovery tools.

Use Case

Program deployment tracking enables you:
  • Track new program launches
  • Monitor program upgrade activity
  • Analyze deployment trends
  • Build program discovery dashboards

Code Example

curl --compressed -X POST "https://portal.sqd.dev/datasets/solana-mainnet/stream" \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "solana",
    "fromBlock": 270000044,
    "toBlock": 270000047,
    "fields": {
      "block": {
        "number": true,
        "timestamp": true
      },
      "transaction": {
        "signatures": true,
        "feePayer": true
      },
      "instruction": {
        "programId": true,
        "accounts": true
      }
    },
    "instructions": [{
      "programId": ["BPFLoaderUpgradeab1e11111111111111111111111"]
    }]
  }'
import { DataSource } from "@subsquid/portal-client";

const dataSource = new DataSource({
  network: "solana-mainnet",
});

// BPF Upgradeable Loader program ID
const BPF_UPGRADEABLE_LOADER = "BPFLoaderUpgradeab1e11111111111111111111111";

const blocks = await dataSource.getBlocks({
  from: 270000044,
  to: 270000047,
  fields: {
    block: { number: true, timestamp: true },
    transaction: {
      signatures: true,
      feePayer: true,
    },
    instruction: {
      programId: true,
      accounts: true,
      transactionIndex: true,
    },
  },
  instructions: [
    {
      programId: [BPF_UPGRADEABLE_LOADER],
    },
  ],
});

// Process deployments
for (const block of blocks) {
  for (const instruction of block.instructions) {
    // The program account is typically the first account
    const programAccount = instruction.accounts[0];
    console.log({
      slot: block.header.number,
      timestamp: block.header.timestamp,
      programAccount: programAccount,
      txIndex: instruction.transactionIndex,
      deployer: block.transactions[instruction.transactionIndex]?.feePayer,
    });
  }
}
import requests
import json

url = "https://portal.sqd.dev/datasets/solana-mainnet/stream"
headers = {"Content-Type": "application/json"}

# BPF Upgradeable Loader program ID
bpf_upgradeable_loader = "BPFLoaderUpgradeab1e11111111111111111111111"

payload = {
    "type": "solana",
    "fromBlock": 270000044,
    "toBlock": 270000047,
    "fields": {
        "block": {
            "number": True,
            "timestamp": True
        },
        "transaction": {
            "signatures": True,
            "feePayer": True
        },
        "instruction": {
            "programId": True,
            "accounts": True
        }
    },
    "instructions": [{
        "programId": [bpf_upgradeable_loader]
    }]
}

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', []):
        program_account = instruction['accounts'][0] if instruction['accounts'] else None
        print({
            "slot": block['header']['number'],
            "timestamp": block['header']['timestamp'],
            "programAccount": program_account,
            "txIndex": instruction.get('transactionIndex')
        })
Try it yourself with the interactive query interface below:

Key Parameters

ParameterDescription
programIdBPF Upgradeable Loader program ID for deployments
accountsInstruction accounts (first account is typically the program)
transactionIndexTransaction index (use to match with transactions array)
Program deployments on Solana use the BPF Upgradeable Loader program. Different instruction types within this program indicate deployments, upgrades, or closures.

Expected Output

{
  "header": {
    "number": 259985000,
    "timestamp": 1697544779
  },
  "instructions": [
    {
      "programId": "BPFLoaderUpgradeab1e11111111111111111111111",
      "accounts": ["NewProgramAddress...", "..."],
      "transactionIndex": 0
    }
  ]
}

Filter by Deployer

Track deployments from specific addresses:
curl --compressed -X POST "https://portal.sqd.dev/datasets/solana-mainnet/stream" \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "solana",
    "fromBlock": 270000044,
    "toBlock": 270000047,
    "fields": {
      "transaction": {
        "signatures": true,
        "feePayer": true
      },
      "instruction": {
        "programId": true,
        "accounts": true,
        "transactionIndex": true
      }
    },
    "instructions": [{
      "programId": ["BPFLoaderUpgradeab1e11111111111111111111111"]
    }],
    "transactions": [{
      "feePayer": ["DeployerAddressHere"]
    }]
  }'
const blocks = await dataSource.getBlocks({
  from: 270000044,
  to: 270000047,
  fields: {
    transaction: { signatures: true, feePayer: true },
    instruction: { programId: true, accounts: true, transactionIndex: true },
  },
  instructions: [
    {
      programId: ["BPFLoaderUpgradeab1e11111111111111111111111"],
    },
  ],
  transactions: [
    {
      feePayer: ["DeployerAddressHere"],
    },
  ],
});
payload = {
    "type": "solana",
    "fromBlock": 270000044,
    "toBlock": 270000047,
    "fields": {
        "transaction": {
            "signatures": True,
            "feePayer": True
        },
        "instruction": {
            "programId": True,
            "accounts": True,
            "transactionIndex": True
        }
    },
    "instructions": [{
        "programId": ["BPFLoaderUpgradeab1e11111111111111111111111"]
    }],
    "transactions": [{
        "feePayer": ["DeployerAddressHere"]
    }]
}

Performance Tips

  1. Filter by deployer: Query deployments from specific addresses
  2. Use slot ranges: Process data in manageable batches
  3. Request minimal fields: Only request fields you need
  4. Combine filters: Use both program and transaction filters for precision

Query Instructions

Track program instructions

Query Transactions

Monitor wallet activity

DEX Swaps

Track DEX trading activity

API Reference

View complete API docs