# How to Track Solana Memecoins in Real Time: A $JEANPHIL Case Study

*A practical guide to monitoring pools, observing transactions and building automated trading signals with Go, Rust and Shredo.*

A memecoin chart tells you how a market has moved. A transaction-monitoring pipeline helps you investigate the activity behind it.

For developers building Solana memecoin trackers, wallet alerts or trading bots, the starting point is straightforward: identify the token, find its trading pools, observe relevant transactions and turn those observations into useful signals.

This guide uses **$JEANPHIL** as an example. The same approach applies to other Solana memecoins.

## Start with the mint, not the ticker

Token names, symbols and profile pictures can be copied. Your tracker should identify an asset by its mint address.

The [JEANPHIL page on pump.fun](https://pump.fun/coin/GTBxUiw6wJdmmkCGZgRHLyYxqu1vG4KtRpeox6yDpump) identifies this mint:

```text
GTBxUiw6wJdmmkCGZgRHLyYxqu1vG4KtRpeox6yDpump
```

Store it as configuration rather than repeatedly searching by ticker. Keep pool addresses, token accounts and wallet addresses separate: they represent different entities.

This prevents a convincing-looking copycat from silently entering your dataset.

## Find the pools where the token trades

One token can trade through multiple pools and venues. Watching one pool is not necessarily equivalent to watching its entire market.

For supported pools, [Shredo Pool Catalogue](https://docs.shredo.xyz/products/signed-pool-catalogue) provides searchable pool identities and dependency accounts. Your application can use that inventory to build its watchlist and update it as the catalogue changes.

The catalogue answers **which pools and accounts to investigate**. Live liquidity, prices and executable quotes require current on-chain state.

Before tracking a particular token, verify that the pools you need are covered. An empty search result does not prove that the token has no pools.

## Observe transactions involving those pools

[Shredo Decoded Transactions](https://docs.shredo.xyz/products/decoded-transactions) delivers signed Solana transactions over TLS gRPC, including instructions, account keys and observation metadata.

For a focused tracker, subscribe using verified pool accounts. Filtering only by a token’s mint can miss relevant swaps because a swap does not necessarily reference the mint directly.

The basic pipeline is:

```text
Verified mint
    → pool discovery
    → filtered transaction stream
    → DEX-specific instruction decoding
    → execution reconciliation
    → alerts or strategy evaluation
```

An observed transaction is not yet a successful trade. It may fail or never become part of the canonical chain. Keep early observations separate from confirmed execution results. [Solana’s transaction documentation](https://solana.com/docs/core/transactions) explains how instructions are executed together and how failures revert state changes.

## Go: subscribe to a pool account

The following excerpt illustrates a filtered subscription using Go bindings generated from Shredo’s [published Protobuf definition](https://shredo.xyz/protocol/decoded.proto).

Here, `pb` represents those generated bindings. The client must already be connected to `console.shredo.xyz:443` using TLS. The excerpt uses the standard `context` and `fmt` packages and `google.golang.org/grpc/metadata`; follow the [official gRPC Go setup](https://grpc.io/docs/languages/go/quickstart/) to generate client bindings.

```go
func observePool(
    ctx context.Context,
    client pb.DecodedTransactionsClient,
    apiKey string,
    poolAddress string,
) error {
    ctx, cancel := context.WithCancel(ctx)
    defer cancel()

    ctx = metadata.AppendToOutgoingContext(
        ctx, "authorization", "Bearer "+apiKey,
    )

    stream, err := client.Subscribe(ctx, &pb.SubscribeRequest{
        AccountKeys: []string{poolAddress},
    })
    if err != nil {
        return err
    }

    for {
        event, err := stream.Recv()
        if err != nil {
            return err
        }
        if event.GetSchemaVersion() != 1 {
            return fmt.Errorf("unsupported stream schema")
        }
        if gap := event.GetGap(); gap != nil {
            return fmt.Errorf("stream gap: %s", gap.GetReason())
        }
        if hb := event.GetHeartbeat(); hb != nil && !hb.GetInputHealthy() {
            return fmt.Errorf("stream input is unhealthy")
        }
        if tx := event.GetTransaction(); tx != nil {
            fmt.Printf("observed slot=%d resolution=%s\n",
                tx.GetSlot(), tx.GetAccountResolutionStatus())
        }
    }
}
```

This is a transport example, not a swap decoder. Its output describes observations; it does not label them as executed buys or sells.

## Rust: consume the same stream

The Rust equivalent uses generated Protobuf bindings with Tonic. As in the Go example, the supplied client must use a TLS connection. Generate the `pb` module from the same schema with [tonic-prost-build](https://docs.rs/tonic-prost-build/latest/tonic_prost_build/).

```rust
async fn observe_pool(
    client: &mut pb::decoded_transactions_client::DecodedTransactionsClient<
        tonic::transport::Channel,
    >,
    api_key: &str,
    pool_address: String,
) -> Result<(), Box<dyn std::error::Error>> {
    let mut request = tonic::Request::new(pb::SubscribeRequest {
        program_ids: vec![],
        account_keys: vec![pool_address],
    });
    request.metadata_mut().insert(
        "authorization",
        format!("Bearer {api_key}").parse()?,
    );

    let mut stream = client.subscribe(request).await?.into_inner();

    while let Some(event) = stream.message().await? {
        if event.schema_version != 1 {
            return Err("unsupported stream schema".into());
        }
        match event.event {
            Some(pb::stream_event::Event::Transaction(tx)) => {
                println!(
                    "observed slot={} resolution={}",
                    tx.slot, tx.account_resolution_status
                );
            }
            Some(pb::stream_event::Event::Gap(gap)) => {
                return Err(format!("stream gap: {}", gap.reason).into());
            }
            Some(pb::stream_event::Event::Heartbeat(hb))
                if !hb.input_healthy =>
            {
                return Err("stream input is unhealthy".into());
            }
            _ => {}
        }
    }

    Err("stream ended; continuity must be reassessed".into())
}
```

These are focused integration excerpts, not complete applications or live-tested JEANPHIL trading bots. Production clients also need bounded queues, reconnect backoff, duplicate handling and explicit continuity tracking.

Keep API keys in environment variables or a secret manager—not in source code, URLs or screenshots.

## Turn observations into useful alerts

A stream becomes useful when your application asks specific questions.

For example:

- Is activity involving a watched pool accelerating?
- Are selected wallets appearing more frequently?
- Does a decoded swap instruction request an unusually large trade?
- Are confirmed trades showing sustained buying or selling?
- Has liquidity changed enough to affect your strategy?

Each question needs an appropriate decoder and data source. Instruction amounts can represent requested inputs or limits rather than executed outputs. Confirmed trade sizes and prices require execution data.

Likewise, a busy wallet is not automatically “smart money,” and high activity is not automatically organic demand.

For JEANPHIL—or any other memecoin—the useful output is a consistent, inspectable event history rather than an unexplained “buy now” notification.

## From alerts to automated trading

Start by recording signals and testing what would have happened after each one.

A paper-trading model should include realistic execution delay, available liquidity, slippage, protocol fees, transaction fees and failed attempts. Simulated fills should not assume that your bot always receives the price visible when a signal first appears.

Only then connect a separately implemented execution layer, with position limits, maximum loss thresholds and a kill switch.

Earlier visibility can improve a system’s inputs. It does not establish that a strategy is profitable.

## Which Shredo product should you use?

**Decoded Transactions** is the direct starting point for developers who want a transaction stream without implementing shred reconstruction themselves.

**Pool Catalogue** helps maintain an inventory of supported pools and their required accounts.

[**Raw Shreds**](https://docs.shredo.xyz/products/raw-shreds) is the lower-level option for teams building their own reconstruction and transaction-processing infrastructure. It is not a prerequisite for Decoded Transactions.

You do not need all three products to start.

## Build a tracker that outlasts one meme

JEANPHIL makes the example recognizable. The reusable asset is the pipeline: verified identities, pool discovery, filtered observations, reliable decoding and measurable signals.

That infrastructure remains useful when attention moves to the next token.

Explore [Shredo’s documentation](https://docs.shredo.xyz/) or choose a feed in the [Shredo Console](https://console.shredo.xyz/).
