How to watch new Solana mints in the browser (runnable demo)
Want a dashboard, alert, or bot that spots a new mint as soon as it lands? You do not always need Geyser first. This post is a how-to: scenario and mechanics first, then a **StackBlitz runnable demo** that subscribes to Token Program logs, filters InitializeMint / InitializeMint2, and resolves the mint from a signature with getTransaction.
This post does **not** depend on custom RunSnippet / OPTIONS; StackBlitz is the runnable path. The demo defaults to BlockReq **public** endpoints (HTTPS
getHealthprobed successfully → ok). Public nodes are IP rate-limited — fine for learning, not for long high-frequency production subscriptions.
1. Scenario: why watch new mints
Typical needs fall into three buckets:
- **Dashboards**: list newly launched mints, then enrich with metadata, liquidity, and deployer.
- **Alerts**: care only about a specific program path (e.g. a launchpad) or unusually frequent creates.
- **Bots**: detect a create instruction, then parse / trade (latency and false positives both matter).
The common thread: you want a push when “this class of instruction just appeared,” not polling getProgramAccounts. On the browser, the smallest path is WebSocket logsSubscribe; for high server-side throughput, look at Geyser / Yellowstone.
2. Principle: logsSubscribe vs Geyser
logsSubscribe (JSON-RPC WebSocket) | Geyser / Yellowstone gRPC | |
|---|---|---|
| Integration cost | Browser and any language can connect | Needs a gRPC client; not browser-friendly |
| Data shape | Log strings + signature | Structured account / transaction protobuf |
| Latency & throughput | Fine for dashboards and alerts; can jitter under load | Better for low latency and large-scale filtering |
| Filter granularity | mentions is **one address per subscription**; detail scanning happens client-side | Server-side filters by program / account / etc. |
| Disconnects | Easy to miss a window after reconnect; you must backfill | Some implementations can resume / replay from a slot |
**How to choose:** prototypes, browser demos, light alerts → logsSubscribe. Production snipers, large-scale indexing → Geyser, then fill details via RPC when needed.
A classic SPL Token create shows up in logs roughly like:
Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]
Program log: Instruction: InitializeMint
Or, more often, InitializeMint2. Token-2022 uses a different program ID, but the instruction name still appears in the logs.
Official reference: [logsSubscribe](https://solana.com/docs/rpc/websocket/logssubscribe).
3. Runnable demo #1: subscribe Token Program → filter InitializeMint
After opening the StackBlitz embed below, click **Run** if the preview does not start on its own (ctl=1). Defaults:
- WSS:
wss://solana-rpc.blockreq.com/v1/rpc/public - HTTPS:
https://solana-rpc.blockreq.com/v1/rpc/public - No API key, no
.envsecrets
Repo: [blockreq/blog-demos](https://github.com/blockreq/blog-demos) (examples/solana-new-mint).
Program constants:
- SPL Token:
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - Token-2022:
TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
4. Walkthrough: what the demo does
Step-by-step against src/index.ts / src/shared.ts:
- **Connect WSS** — open the BlockReq public WebSocket.
- **Two logsSubscribe calls** —
mentionsaccepts only one address per call, so Token and Token-2022 each get a subscription withcommitment: "confirmed". - **Filter logs** — regex for
Instruction: InitializeMint/InitializeMint2; drop failed txs (err != null). - **Dedupe** — a
signatureSet avoids replay spam. - **Print the signature** — first
[mint?] slot=… sig=…, then optionally resolve the mint viagetTransaction. - **Reconnect** — on
close, exponential backoff and resubscribe.
Subscribe params (sketch):
params: [{ mentions: [programId] }, { commitment: 'confirmed' }]
Filter core:
const MINT_LOG = /Instruction:\s*InitializeMint2?/i;
if (!logs.some((line) => MINT_LOG.test(line))) return;
5. From signature to mint: getTransaction
A log subscription usually **does not** hand you the mint pubkey. Production flow: see InitializeMint* → call getTransaction over HTTPS on the same provider (encoding: "jsonParsed") → scan top-level and inner instructions for initializeMint / initializeMint2 → read parsed.info.mint.
The second entry lives in the same example: src/get-mint.ts (page get-mint.html). Click **Run** in the embed if needed.
Resolution steps (same as the demo):
POSTgetTransactionwithmaxSupportedTransactionVersion: 0.- Merge
message.instructionsandmeta.innerInstructions[].instructions. - Keep Token / Token-2022 instructions whose
parsed.typecontainsinitializemint. - Return
parsed.info.mint.
Paste a signature from the watcher into the second page to verify.
6. Switching to BlockReq keyed: prose only — demo has no keys
The runnable demo **intentionally uses public endpoints only**; the repo will not contain an API key. For long-lived subscriptions in your own app:
| Use | Endpoint |
|---|---|
| Public HTTPS | https://solana-rpc.blockreq.com/v1/rpc/public |
| Private HTTPS | https://solana-rpc.blockreq.com/v1/rpc/{API_KEY} |
| Public / private WSS | wss://…/public or wss://…/{API_KEY} |
Public is **rate-limited by IP**; prefer a private key for long subscriptions, and confirm in the console that WSS / subscriptions are enabled for your plan. You still own: exponential backoff reconnect, resubscribe, and signature dedupe. Multi-upstream failover means “the node can fail over,” not “the browser WebSocket never drops.”
More: [Public Endpoints](https://docs.blockreq.com/build/public-endpoints/) · [Solana API](https://docs.blockreq.com/build/api-reference/solana/)
7. Pitfalls: noise, junk mints, confirmations, launchpads
**Noise** — subscribing to the Token Program floods Transfer / MintTo traffic; always filter InitializeMint(2) first, then getTransaction. processed is faster but noisier; dashboards can use confirmed; money-moving logic prefers finalized.
**Junk / spam launches** — being able to InitializeMint on-chain ≠ liquidity ≠ trustworthy metadata. Secondary checks help: mint authority revoked immediately, pool created right away, metadata URI, deployer history.
**Launchpads** — pump.fun and similar usually go through their own program create, not a bare Token InitializeMint. Watch them with mentions on that program ID and parse by that program’s rules; Token-only misses launchpads, launchpad-only misses manual spl-token create-token.
**Confirmations and missed messages** — reconnect gaps, rate limits, and truncated logs drop events. For important flows, reconcile against a second source (short getSignaturesForAddress sweeps or a Geyser backup stream). Failed txs can still contain the instruction-name string — the example drops err != null.
---
Takeaways
- Browser path:
WebSocket→logsSubscribe+mentions: [Token Program]→ filterInitializeMint(2)→getTransactionfor the mint. - Subscribe to Token and Token-2022 separately; subscribe to launchpad programs separately.
logsSubscribefits prototypes and light alerts; low-latency scale wants Geyser.- Runnable demo lives in StackBlitz / [blog-demos](https://github.com/blockreq/blog-demos); switching to keyed BlockReq is a URL change — never commit keys to a public repo.
If you wire this into a dashboard or bot, next steps are usually: parse mint → fetch metadata → watch pool creation. That is a story for another post.