# Helius getTransactionsForAddress (Carbon 2.0)

> Backfill full transactions for an address in pages of 100 with Helius getTransactionsForAddress, filtered by slot, time, signature or status.

`HeliusGtfaDatasource` pages through Helius' `getTransactionsForAddress`, which returns full transactions with metadata in one call, and emits them as transaction updates. Compared with the [RPC transaction crawler](https://carbon.sevenlabs.org/datasources/rpc-transaction-crawler.md), it needs one request per 100 transactions instead of one per transaction, can go oldest-first, and filters by slot, block time, signature range or status on the server. Use it to backfill an address's history on Helius.

|          |                                                                                                                                          |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| Crate    | `carbon-helius-gtfa-datasource` 2.0.0                                                                                                    |
| Install  | `cargo add carbon-helius-gtfa-datasource@2.0.0`                                                                                          |
| Emits    | `Transaction`                                                                                                                            |
| Mode     | Historical. Finishes after the last page.                                                                                                |
| Provider | A Helius RPC URL with API key, on a plan that includes `getTransactionsForAddress`.                                                      |
| API docs | [docs.rs](https://docs.rs/carbon-helius-gtfa-datasource/2.0.0/carbon_helius_gtfa_datasource/)                                            |
| Source   | [`datasources/helius-gtfa-datasource`](https://github.com/sevenlabs-hq/carbon/blob/v2.0.0/datasources/helius-gtfa-datasource/src/lib.rs) |

## Quick example

This program backfills 1,000 slots of Orca Whirlpool transactions, oldest first, prints each `swapV2`, and exits. It compiles as shown; to run it, set `HELIUS_API_KEY` and `START_SLOT`.

```sh
cargo new helius-gtfa && cd helius-gtfa
cargo add carbon-core@2.0.0 carbon-log-metrics@2.0.0 carbon-orca-whirlpool-decoder@2.0.0 carbon-helius-gtfa-datasource@2.0.0
cargo add solana-commitment-config@3.1.1
cargo add tokio@1 --features full
cargo add env_logger@0.11 log@0.4
```

`src/main.rs`:

```rust
use {
    carbon_core::{
        error::CarbonResult, instruction::InstructionProcessorInputType, pipeline::Pipeline,
        processor::Processor,
    },
    carbon_helius_gtfa_datasource::{
        HeliusGtfaConfig, HeliusGtfaDatasource, HeliusGtfaFilters, SlotFilter, SortOrder,
    },
    carbon_log_metrics::LogMetrics,
    carbon_orca_whirlpool_decoder::{
        instructions::OrcaWhirlpoolInstruction, OrcaWhirlpoolDecoder, PROGRAM_ID,
    },
    solana_commitment_config::CommitmentConfig,
    std::{env, sync::Arc},
};

#[tokio::main]
async fn main() -> CarbonResult<()> {
    env_logger::init();

    let start_slot: u64 = env::var("START_SLOT").expect("START_SLOT must be set").parse().unwrap();

    let config = HeliusGtfaConfig::new(
        Some(SortOrder::Asc), // oldest first
        Some(100),            // transactions per page (max 100)
        Some(CommitmentConfig::finalized()),
        Some(HeliusGtfaFilters {
            slot: Some(SlotFilter {
                gte: Some(start_slot),
                lt: Some(start_slot + 1_000),
                gt: None,
                lte: None,
            }),
            block_time: None,
            signature: None,
            status: None, // successful transactions only
        }),
        None, // min_context_slot
    );

    let datasource = HeliusGtfaDatasource::new_with_config(
        format!(
            "https://mainnet.helius-rpc.com/?api-key={}",
            env::var("HELIUS_API_KEY").expect("HELIUS_API_KEY must be set")
        ),
        PROGRAM_ID,
        config,
    );

    Pipeline::builder()
        .datasource(datasource)
        .metrics(Arc::new(LogMetrics::new()))
        .instruction(OrcaWhirlpoolDecoder, SwapLogger)
        .build()?
        .run()
        .await
}

struct SwapLogger;

impl Processor<InstructionProcessorInputType<'_, OrcaWhirlpoolInstruction>> for SwapLogger {
    async fn process(
        &mut self,
        input: &InstructionProcessorInputType<'_, OrcaWhirlpoolInstruction>,
    ) -> CarbonResult<()> {
        let tx = &input.metadata.transaction_metadata;
        if let OrcaWhirlpoolInstruction::SwapV2 { data, accounts, .. } = input.decoded_instruction {
            println!("slot {} swapV2 pool={} amount={}", tx.slot, accounts.whirlpool, data.amount);
        }
        Ok(())
    }
}
```

```sh
HELIUS_API_KEY=your-helius-api-key START_SLOT=467000000 RUST_LOG=info cargo run
```

Swaps print in slot order, followed by `Reached end of pagination` and pipeline shutdown. With an invalid key:

Output:

```text
[ERROR carbon_helius_gtfa_datasource] RPC request failed with status 401 Unauthorized: Unauthorized
[ERROR carbon_core::pipeline] error consuming datasource: FailedToConsumeDatasource("HTTP error 401 Unauthorized: Unauthorized")
```

## Configuration

### Constructors

```rust
pub fn new(helius_rpc_url: String, address: Pubkey) -> Self
pub fn new_with_config(helius_rpc_url: String, address: Pubkey, config: HeliusGtfaConfig) -> Self
```

`helius_rpc_url` is the full URL including `?api-key=`. `address` is the account whose transactions you want: a program, wallet, pool or mint.

### `HeliusGtfaConfig`

```rust
pub fn new(
    sort_order: Option<SortOrder>,
    limit: Option<u32>,
    commitment: Option<CommitmentConfig>,
    filters: Option<HeliusGtfaFilters>,
    min_context_slot: Option<u64>,
) -> Self
```

| Field              | Type                        | `Default`   | Meaning                                                                                      |
| ------------------ | --------------------------- | ----------- | -------------------------------------------------------------------------------------------- |
| `sort_order`       | `Option<SortOrder>`         | `Some(Asc)` | `SortOrder::Asc` (oldest first) or `Desc`. `None` (possible with `new`) leaves it to Helius. |
| `limit`            | `Option<u32>`               | `Some(100)` | Transactions per page. Capped at 100; `None` in `new` also means 100.                        |
| `commitment`       | `Option<CommitmentConfig>`  | `confirmed` | `None` (possible with `new`) leaves it to Helius.                                            |
| `filters`          | `Option<HeliusGtfaFilters>` | `None`      | Server-side filters. A filter with every field empty is not sent.                            |
| `min_context_slot` | `Option<u64>`               | `None`      | Reject the request if Helius is behind this slot.                                            |

The datasource always requests `transactionDetails: "full"`, Base64 encoding and `maxSupportedTransactionVersion: 1`.

### `HeliusGtfaFilters`

| Field        | Type                              | Meaning                                                                        |
| ------------ | --------------------------------- | ------------------------------------------------------------------------------ |
| `slot`       | `Option<SlotFilter>`              | `RangeFilter<u64>` with `gte`, `gt`, `lte`, `lt`.                              |
| `block_time` | `Option<BlockTimeFilter>`         | Unix seconds: `gte`, `gt`, `lte`, `lt`, `eq`.                                  |
| `signature`  | `Option<SignatureFilter>`         | `RangeFilter<String>` of base58 signatures.                                    |
| `status`     | `Option<TransactionStatusFilter>` | `Succeeded`, `Failed` or `Any`. Applied by Helius and again by the datasource. |

The datasource's own status check: `None` and `Succeeded` drop failed transactions, `Failed` keeps only failed ones, `Any` keeps both.

## Behaviour

- **Paging.** Pages are fetched one at a time, following `paginationToken` until Helius returns none. Order within and across pages follows `sort_order`.
- **Updates.** `slot`, `block_time` and `index` (the transaction's position in its block, when Helius returns it) are set; `block_hash` is `None` and `is_vote` is `false`.
- **Backpressure.** Updates are sent with `send().await`; nothing is dropped.
- **Finishing.** `consume` returns after the last page. A pipeline with only this datasource then shuts down.
- **Errors.** There are no retries. A non-2xx status, a body that isn't JSON, an RPC error, or a transaction whose metadata can't be converted stops the datasource with `FailedToConsumeDatasource`. Transactions that fail to decode are skipped with `Failed to decode transaction`.
- **Cancellation.** Checked before each page and between transactions.
- **Metrics.** `helius_gtfa_pages_fetched_total`, `helius_gtfa_transactions_processed_total` (counters), `helius_gtfa_fetch_duration_milliseconds` (histogram).

## Troubleshooting

### `HTTP error 401 Unauthorized`

The API key is missing or invalid. The URL must end in `?api-key=<your key>`.

### `RPC error: … (code: …)`

Helius rejected the request: an unsupported method on your plan, a malformed filter, or a bad address. The message is Helius' own.

### The backfill stops halfway with an error

There are no retries. Restart with a `slot` filter (`gte` = the last slot you stored, with `Asc`) to resume, and make your writes idempotent so the overlap is harmless.

### Failed transactions are missing

By default the datasource drops them. Set `status: Some(TransactionStatusFilter::Failed)` or `Any`.

## See also

- [Backfill transactions](https://carbon.sevenlabs.org/guides/backfill-transactions.md)
- [RPC transaction crawler](https://carbon.sevenlabs.org/datasources/rpc-transaction-crawler.md)
- [Helius gPA v2](https://carbon.sevenlabs.org/datasources/helius-gpa-v2.md)
- [Datasources concept](https://carbon.sevenlabs.org/concepts/datasources.md) and [update types](https://carbon.sevenlabs.org/concepts/updates.md)

---

Carbon 2.0.0 documentation · Web: https://carbon.sevenlabs.org/datasources/helius-gtfa · Last updated 2026-11-09 · Index of all pages: https://carbon.sevenlabs.org/llms.txt
