Sample audits · Open-source projects and documentation, eight more

Helius docs: pages changed or added since May

Only the Helius documentation pages that changed or were added since our May audit (204 changed, 113 added, including API specifications); unchanged pages were not audited again.

Auditedhelius.dev documentation, changed and added pages, pages fetched 11 October 2026
Date11 October 2026
How it rancloud session, full audit, Standard review
Verdict after reviewPass with notes (rule: Fail if a High finding remains after review, otherwise Pass with notes)

Related: Helius API documentation (May 2026) · Helius Gatekeeper documentation (June 2026)

0
High after review
9
Medium after review
81
Low after review
1
Info after review
0
excluded on review
How to read this page

Each finding keeps the number it has in the audit report. The rating shown first is the one after review; the first automated rating is listed with it. 67 findings were first rated Medium or High; 9 of them are Medium or High after review. Text marked "From the report" is quoted from the audit report; fixes are suggestions and were not tested. Locations are paths inside the fetched copy of the documentation.

Medium after review (9)

3. Medium LaserStream Rust install snippet pins a version below the documented minimum
First rating: Medium · Reviewed rating: Medium · Review: confirmed
Location: laserstream/clients.md:115
From the report
Evidence

helius-laserstream = "0.2"

Why it matters

Line 111 says to use 0.6.3 or later, because older releases mishandle transaction v1. Cargo's "0.2" resolves to versions >=0.2.0, <0.3.0, so it can never reach 0.6.3.

Suggested fix, not tested

Change it to "0.6" (at least 0.6.3), or use cargo add. Pin the Go snippet at line 171 the same way.

Review: Line 111: "Use helius-laserstream 0.6.3 or later. Earlier releases ship a proto that predates transaction v1". Line 115: helius-laserstream = "0.2", which Cargo reads as ^0.2, so a copy-paste resolves to 0.2.x. The defect is silent: v1 transactions arrive without their transactionConfig fields. Contradiction sits four lines apart on one page. (cuckoo-filters.md:48 also says "0.2", but there 0.2.0 is the feature minimum. The Go snippet at 171 has no version at all, so "pin it the same way" is a minor misstatement.)

10. Medium Exponential-backoff reconnector never reconnects
First rating: Medium · Reviewed rating: Medium · Review: confirmed
Location: rpc/websocket.md:341 (with lines 378 and 392-394)
From the report
Evidence

if (this.isReconnecting) return; … this.isReconnecting = true; … setTimeout(() => { this.connect(); }, jitteredDelay);

Why it matters

scheduleReconnect() sets the flag and then calls connect(), which returns at once because the flag is set. The flag is only cleared in onopen, which is never reached. After the first disconnect the client stays dead and its subscriptions are lost.

Suggested fix, not tested

Clear the flag just before calling connect() in the timer, or remove the guard from connect().

Review: connect() begins if (this.isReconnecting) return;. scheduleReconnect() sets isReconnecting = true (378) and its timer then calls this.connect() (393), which returns immediately. The flag is cleared only in onopen (356), which is never reached. After the first drop (and onclose itself routes through scheduleReconnect, 360-364) the client stays dead with no error. The section exists to teach reconnection, so this is a silent core-path failure. Unchanged since May (not in the diff).

49. Medium Sender quickstart now transfers 1 SOL instead of 0.001 SOL
First rating: Medium · Reviewed rating: Medium · Review: confirmed
Location: sending-transactions/sender.md:128 (kit tab: line 229)
From the report
Evidence

lamports: 1 * LAMPORTS_PER_SOL, / amount: lamports(1_000_000_000n), // 1 SOL

Why it matters

The diff shows the amount was changed from 0.001 SOL. A developer who runs the "simple transfer" sample on mainnet with a real key moves 1 SOL, and the transfer cannot be undone.

Suggested fix, not tested

Restore 0.001 SOL in both tabs.

Review: Diff lines 107-108 and 140-141 show 0.001 * LAMPORTS_PER_SOL and lamports(1_000_000n), // 0.001 SOL replaced by 1 * LAMPORTS_PER_SOL and lamports(1_000_000_000n), // 1 SOL. The sibling pages (sender-max.md:178, sender-swqos-only.md:144) still use 0.001. Looks like a find/replace slip when the tip changed; the 0.001 SOL tip sits right beside it (133, 238). Real money, irreversible, new in this delta.

50. Medium Docs tell browser apps to put the project API key in the Sender URL
First rating: Medium · Reviewed rating: Medium · Review: confirmed
Location: sending-transactions/sender.md:514
From the report
Evidence

Tab "Frontend/Browser Applications": https://sender.helius-rpc.com/fast?api-key=YOUR_API_KEY

Why it matters

Anyone visiting the site can read the key and spend the project's credits and quota. agents/skills/phantom.md:42 says "Never expose Helius API keys in client code".

Suggested fix, not tested

Recommend a server-side relay or a restricted, separate browser key, and align the Phantom page.

Review: Tab "Frontend/Browser Applications" shows https://sender.helius-rpc.com/fast?api-key=YOUR_API_KEY; the browser samples at diff lines 123 and 159 do the same. agents/skills/phantom.md:42 says "Never expose Helius API keys in client code - only https://sender.helius-rpc.com/fast is browser-safe without an API key", and api-reference/authentication.md:12 says the same. The Sender page never mentions domain restriction (waas/securing-your-key.md:36 describes it). The project key also works for credit-metered RPC, and a keyless option exists, so MEDIUM stands.

59. Medium Real-looking dedicated-node credentials published in the sample
First rating: Medium · Reviewed rating: Medium · Review: confirmed
Location: dedicated-nodes/getting-started.md

A live-looking API key and token are printed on this page.

68. Medium NFT-sale webhook handler treats the payload array as a single object
First rating: Medium · Reviewed rating: Medium · Review: confirmed
Location: webhooks/transaction-types.md:993
From the report
Evidence

const event = req.body; / if (event.type === 'NFT_SALE') {

Why it matters

Webhooks deliver an array, as data-streaming/quickstart.md:166 shows. event.type is always undefined, so no sale is ever processed.

Suggested fix, not tested

Iterate over req.body.

Review: const event = req.body; if (event.type === 'NFT_SALE'). webhooks.md:49 shows the delivered payload as a JSON array, and data-streaming/quickstart.md:166 iterates req.body.forEach. The branch never runs and nothing is logged: silent. The fields read (event.seller, event.buyer, event.amount) are also not top-level in the documented payload.

74. Medium Reconnect guide sample crashes on the failures it is meant to survive
First rating: Medium · Reviewed rating: Medium · Review: confirmed
Location: parsed-streams/guides/handling-reconnects.md:56
From the report
Evidence

const ws = new WebSocket(URL); (handlers registered: open, message and close only)

Why it matters

With ws, an error event with no listener is thrown. DNS failures, refused connections and 401/429 handshake rejections kill the process before the backoff runs.

Suggested fix, not tested

Add an error handler and let close own the retry.

Review: Handlers registered: open, message, close. Contrast track-pumpfun-mints.md:89, which does register error. One-line fix, but the guide's whole purpose is this path.

79. Medium Subscription IDs from Date.now() collide
First rating: Medium · Reviewed rating: Medium · Review: confirmed
Location: rpc/websocket/quickstart.md:350
From the report
Evidence

const requestId = Date.now();

Why it matters

Back-to-back subscribe() calls (lines 410 and 497) in the same millisecond overwrite each other in the map. Subscriptions are silently dropped, including on resubscribe.

Suggested fix, not tested

Use an incrementing counter.

Review: requestId = Date.now() is the Map key. The page's own use cases call subscribe three times back to back (412, 419, 425) and twice for the portfolio tracker (503, 510); calls within one millisecond overwrite each other in the Map, so subscriptions are silently dropped (and resubscribeAll, 366-375, re-sends only the survivors). Contrast rpc/websocket.md:424, which adds Math.random(). Pre-existing.

89. Medium Confirmation loop reports a failed transaction as confirmed
First rating: Medium · Reviewed rating: Medium · Review: confirmed
Location: sending-transactions/send-manually.md:213
From the report
Evidence

if (status && (status.confirmationStatus === 'confirmed' || status.confirmationStatus === 'finalized')) {

Why it matters

status.err is never checked, so a transaction that landed but failed is treated as success.

Suggested fix, not tested

Check status.err first.

Review: The sample sends with skipPreflight: true (204), which lets failing transactions land, then logs "Transaction confirmed!" on confirmationStatus alone; status.err is never read. Line 230 concedes the loop is basic but does not mention errors. A landed-but-failed transaction is reported as success.

Low after review (81)

1. Low Keyless Sender access cut to 1 request/s with no transition notice
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: sending-transactions/sender.md:496
From the report
Evidence

* **Keyless**: 1 request per second per egress IP, per region. ... Rejected 429 requests count toward the limit

Why it matters

The previous docs said standard users need no key and get 50 TPS. The new limit has no announcement, cut-over date or migration path. Keyless samples are still published (for example the cURL samples on the sender-max and sender-swqos-only pages), faqs/sender.md:18 still says "standard limit is 50 TPS", and api-reference/sender/llms.txt:70 says "Default 50 TPS". Existing keyless integrations will be throttled without warning.

Suggested fix, not tested

Publish a dated change notice and a migration path. Update every keyless sample and every "50 TPS default" statement.

Review: Limit is stated plainly on the page; "no announcement" is vendor policy, not a doc defect. Real residue: faqs/sender.md:18 and api-reference/sender/llms.txt:70,77 still say 50 TPS default.

2. Low Privacy deposit sample hard-codes the classic token program while claiming Token-2022 support
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: privacy/guides/deposit.md:443 (also line 427)
From the report
Evidence

tokenProgram: TOKEN_PROGRAM_ADDRESS,

Why it matters

Line 365 says DepositAsset.spl covers "SPL and Token 2022 assets". With a Token-2022 mint, this sample builds the interface and the deposit against the wrong program, so the transaction fails.

Suggested fix, not tested

Read the mint account's owner and require it to be either the classic token program or Token-2022. Pass that program ID in both places, and add a Token-2022 variant.

Review: Real (line 365 says SPL and Token 2022) but the sample is the SPL path; a Token-2022 user fails loudly and edits one constant.

4. Low Wallet sign-in example signs a constant message
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: waas/using-the-wallet.md:50
From the report
Evidence

const signature = await signMessage("Sign in to Acme");

Why it matters

A signature over a fixed string can be replayed. Readers copy this as their login proof.

Suggested fix, not tested

Show a challenge flow: the server issues a nonce with a domain and an expiry, the wallet signs it, and the server verifies the signature and consumes the nonce.

Review: exists

5. Low Sign-and-send example ignores user rejection and the landing result
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: waas/using-the-wallet.md:94
From the report
Evidence

const signature = await signAndSendTransaction(serialized);

Suggested fix, not tested

Wrap the call in try/catch to handle a cancelled prompt. Confirm with getSignatureStatuses before treating the action as done.

Review: exists

6. Low Deprecated staked endpoint is still advertised with benefits and has no sunset date
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: api-reference/endpoints.md:55
From the report
Evidence

The staked endpoint (staked.helius-rpc.com) is deprecated. ... * **Higher landing rates**: Guaranteed access to staked connections

Suggested fix, not tested

Give a sunset date, or state that there is none, and present the benefits as legacy behaviour.

Review: exists (benefit bullets 58-61)

7. Low Enhanced Transactions deprecation messaging conflicts between pages
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: parsed-events/guides/migrate-from-enhanced-transactions.md:183
From the report
Evidence

Enhanced Transactions keeps working while you migrate — there is no forced cutoff.

Why it matters

The llms-full FAQ says the API "will be deprecated", and other pages call it maintenance mode. Readers cannot plan a migration from that.

Suggested fix, not tested

Publish one message: the current phase, the minimum support window and the target date.

Review: exists

8. Low Replacement guidance for removed APIs was deleted
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: src/diffs/HeliusAPI_full/_llms.txt.diff:153
From the report
Evidence

-| mintCompressedNft | Use Metaplex Bubblegum SDK directly | Helius mint API is deprecated |

Why it matters

Both pages now only redirect, and nothing tells existing callers what to use instead.

Suggested fix, not tested

Keep a short "removed — use X" notice for at least one release.

Review: removed section starts at 153, mint row at 156

9. Low API reference landing page has no legacy marker on Enhanced Transactions
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: api-reference.md:32
From the report
Evidence

<Card title="Enhanced Transactions" ... Retrieve pre-parsed transaction data in human-readable format.

Suggested fix, not tested

Mark it as legacy and link to Parsed Events and the migration guide.


Review: exists

11. Low Reconnect gap detection depends on the next notification arriving
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: parsed-streams/guides/handling-reconnects.md:76
From the report
Evidence

if (lastSlotSeen !== null && slot > lastSlotSeen) {

Why it matters

This condition is also true in normal operation. On a quiet filter, the idle case the guide covers, no notification may arrive after reconnect, so the missed window is never backfilled.

Suggested fix, not tested

On open after a reconnect, read the current slot and backfill explicitly from lastSlotSeen to that slot.

Review: Block body is a one-line stub comment. Gap is found late (on next notification), not "never backfilled".

12. Low A new ping timer starts on every reconnect and is never cleared
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: rpc/websocket/stream-pump-amm-data.md:86
From the report
Evidence

function startPing(ws: WebSocket): void { / setInterval(() => {

Why it matters

Each reconnect adds another 30 s interval that keeps old sockets alive. Timers pile up for as long as the process runs.

Suggested fix, not tested

Keep the interval ID, clear it in the close handler, and start only one timer per connection.

Review: Leak is real but tiny (max 5 retries per outage); the interval gates on the old socket's readyState === OPEN, so it does not keep old sockets alive as claimed.

13. Low React cleanup calls a disconnect() method that does not exist
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: rpc/websocket/quickstart.md:714
From the report
Evidence

if (manager) manager.disconnect();

Why it matters

WebSocketManager (lines 306-377) defines no disconnect(). Unmount throws, and every mount leaks a metered connection. The "production-ready" class also leaves reconnection as a comment (line 345).

Suggested fix, not tested

Add disconnect() that sets a closing flag and calls ws.close(), and implement the reconnect.

Review: Confirmed: class (306-377) has no disconnect; unmount throws TypeError (loud). Reconnect left as a comment at 345. Borderline LOW/MEDIUM.

14. Low Retry loop on 429 never gives up
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: rpc/optimization-techniques.md:416
From the report
Evidence

while (true) {

Why it matters

A key that is exhausted or blocked keeps hammering the API forever. billing/rate-limits.md prescribes at most 5 attempts with delays up to 30 s.

Suggested fix, not tested

Limit the number of attempts, honour Retry-After, and rethrow after the last attempt.

15. Low Resubscribe sends every filter in a burst against the message-rate limit
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: parsed-streams/guides/handling-reconnects.md:60
From the report
Evidence

filters.forEach((filter, i) => { / ws.send(JSON.stringify({

Suggested fix, not tested

Pace the resubscriptions and check each response for rate-limit errors.

Review: exists

16. Low Health-check interval has no handle and is never cleared
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: rpc/websocket.md:499
From the report
Evidence

setInterval(() => {

Suggested fix, not tested

Store the interval ID and clear it on shutdown.

Review: exists

17. Low Keepalive interval is never cleared and the sample has no close handler
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: rpc/websocket/transaction-subscribe.md:201
From the report
Evidence

setInterval(() => ws.ping(), 30_000);

Suggested fix, not tested

Add a close handler that clears the interval and then reconnects or exits.

Review: exists

18. Low Resume slot is read from an environment variable that the handler cannot update
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: laserstream/historical-replay.md:157
From the report
Evidence

let lastProcessedSlot = Number(process.env.LAST_PROCESSED_SLOT ?? 0);

Why it matters

The slot is written to one place and read from another. After a restart the value is stale, and a missing value is silently turned into a 48-hour replay.

Suggested fix, not tested

Read and write the resume slot through the same store.

Review: exists; code comment says load from your own store

19. Low Idle consumer wakes every 1 ms
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: preprocessed-transactions/guides/trade-on-preprocessed.md:99
From the report
Evidence

if (!item) { await new Promise(r => setTimeout(r, 1)); continue; }

Suggested fix, not tested

Have the producer signal when an item arrives instead of polling.

Review: exists

20. Low Portfolio balances are never refreshed when live events arrive
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: quickstart/portfolio-tracker.md:429
From the report
Evidence

setLive((prev) => [JSON.parse(e.data), ...prev].slice(0, 10));

Suggested fix, not tested

On a live event and on stream reconnect, refetch the balances and history, with a debounce.


21. Low Raw amounts are documented as exact strings, but the recommended conversion uses parseInt
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: wallet-api/transfers.md:200, wallet-api/overview.md:132
From the report
Evidence

Serialized as a string to avoid floating-point precision loss. ... amount = parseInt(amountRaw) / 10**decimals

Why it matters

parseInt brings back the precision loss that the string format exists to avoid. Raw amounts above 2^53 are silently rounded. wallet-api/balance-at.md already advises BigInt.

Suggested fix, not tested

Use BigInt(amountRaw) and decimal-string formatting.

Review: Formula yields a float display amount (and amount is already supplied); precision matters only above 2^53 raw. balance-at.md:207 shows BigInt, so this is doc consistency.

22. Low Stale Sender minimum tip in the Rust SDK best practices
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: agents/rust-sdk/best-practices.md:203
From the report
Evidence

Minimum 0.0002 SOL (Dual mode) or 0.000005 SOL (SWQOS-only).

Why it matters

The current Sender pages set a 0.001 SOL minimum for Sender Max, and a smaller tip misses the priority buffer. Line 69 still mentions "Dual".

Suggested fix, not tested

Update the figure and the mode name.

Review: Stale figure confirmed (0.0002 vs 0.001 Max), but the same line says the SDK determines and appends the tip itself. Unchanged text, informational.

24. Low Token balance deltas are computed with parseInt
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: laserstream/guides/decoding-transaction-data.md:621
From the report
Evidence

const preAmount = preBalance ? parseInt(preBalance.uiTokenAmount.amount) : 0;

Suggested fix, not tested

Use BigInt arithmetic (also at lines 734-735).

Review: exists (also 734-735)

25. Low Raw-amount filter bounds are typed as JSON numbers
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: api-reference/rpc/http/gettransfersbyaddress.md:467
From the report
Evidence

gt: / type: number

Suggested fix, not tested

Accept string-encoded raw amounts so values above 2^53 work in both directions.

Review: exists

26. Low "Exact" integer is derived from a floating-point balance
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: wallet-api/balances.md:238
From the report
Evidence

derive it as Math.round(balance * 10 ** decimals).

Suggested fix, not tested

Expose a raw string field, or state that the derived value is approximate.

Review: exists

27. Low Guide converts a u64 fee to Number before summing it
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: laserstream/guides/stream-pump-amm-data.md:169
From the report
Evidence

Wrap it in Number(...) before doing arithmetic.

Suggested fix, not tested

Accumulate with BigInt and convert only for display.

Review: exists

28. Low Replay window hard-coded as a slot count in client code
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: laserstream/historical-replay.md:162
From the report
Evidence

const maxReplaySlot = currentSlot - 691_200;

Suggested fix, not tested

Treat the window as a time value set by the server, or derive the earliest slot from the server's response.

Review: exists

29. Low Load button starts overlapping requests
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: quickstart/portfolio-tracker.md:395
From the report
Evidence

const load = async () => {

Suggested fix, not tested

Ignore clicks while a load is in flight, or disable the button.


Review: exists

30. Low AGENTS.md quick start runs a signup command that no longer returns a key
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: AGENTS.md:11 (delivered as AGENTS.md.nxdata)
From the report
Evidence

npx helius-cli signup --json

Why it matters

agents/cli.md says signup now needs --email, --first-name and --last-name, and by default it returns a payment link. The key only comes from --resume or --pay. An autonomous agent following this file gets no key.

Suggested fix, not tested

Show the three-step flow from _docs_AGENTS.md.

Review: Stale (agents/cli.md:34,63 need --email/--first-name/--last-name; default is a payment link) but unchanged since May and the failure is a loud CLI error naming the missing flags.

31. Low Agents index shows an API key in the response of the default signup
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: agents/llms.txt:114
From the report
Evidence

helius signup --email you@example.com --first-name Jane --last-name Doe --json, followed by "apiKey": "your-api-key-here"

Suggested fix, not tested

State that the apiKey payload comes only from --resume or --pay.

Review: Same root cause as 30; example output mismatch (cli.md:62-66).

32. Low Plugin install one-liner is the form the plugin page says fails
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: AGENTS.md:55 (also line 76, and _www_llms.txt:78)
From the report
Evidence

/plugin marketplace add helius-labs/core-ai && /plugin install helius@helius-labs

Why it matters

agents/claude-code-plugin.md:40 says to run the two commands separately and that pasting both at once fails.

Suggested fix, not tested

Show two separate commands.

Review: Contradiction real (agents/claude-code-plugin.md:40); failure is loud, retry trivial.

33. Low AGENTS.md describes authentication as one query parameter everywhere
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: AGENTS.md:40
From the report
Evidence

Auth: every surface requires an api-key query parameter

Why it matters

The same file lists plain-HTTP regional Sender hosts (line 30) and an x-token header for LaserStream (line 36). An agent following this line will attach the key to unencrypted URLs.

Suggested fix, not tested

Describe authentication per surface, never put the key on http:// URLs, and prefer the header where it is supported.

Review: Overgeneralisation; the same file lists the x-token header (36). Plain-HTTP regional hosts are vendor design (see 51).

34. Low LaserStream index gives the old replay window and the wrong mainnet plan
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: api-reference/laserstream/grpc/llms.txt:38 (also lines 13, 46, 241, 301)
From the report
Evidence

- 24-hour historical replay (216,000 slots) / Choose your plan (Devnet: Developer/Business, Mainnet: Professional)

Why it matters

The source pages say about 48 h (about 691,200 slots), and that Business also gets mainnet. Line 53 of the same file lists Business with mainnet.

Suggested fix, not tested

Regenerate the file from the current pages.

Review: Real: 24 h / 216,000 vs 48 h / 691,200 (historical-replay.md:19); line 13 says mainnet = Professional only, line 53 lists Business too. Understates, conservative.

35. Low Shred Delivery index gives the old replay window and links a removed page
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: shred-delivery/llms.txt:76 (and 195)
From the report
Evidence

| Historical replay | No | No | 24 hours |

Suggested fix, not tested

Change the replay window to 48 hours, and link /docs/preprocessed-transactions/overview.

Review: Real; DELTA_MANIFEST.md:58 confirms shred-delivery/preprocessed-transactions.md redirects away.

36. Low Dedicated Nodes index contradicts its source page
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: dedicated-nodes/llms.txt:17
From the report
Evidence

- 24-hour historical replay

Suggested fix, not tested

Change it to 48-hour, matching dedicated-nodes/getting-started.md:82.

Review: Real; getting-started.md:82 says 48 h.

37. Low Agents index puts the priority-fee tool under the wrong MCP tool
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: agents/llms.txt:49
From the report
Evidence

heliusTransaction (parsing, history, priority fees)

Why it matters

agents/mcp/tools.md:112 lists getPriorityFeeEstimate under heliusChain, so agents will call the wrong tool.

Suggested fix, not tested

Update the summary.

Review: Real (heliusTransaction vs tools.md:112 heliusChain); one summary phrase, the catalog page is right.

38. Low Section indexes show SDK code for an older SDK API
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: api-reference/das/llms.txt:596 (also the webhooks, enhanced-transactions, priority-fee, rpc/http, wallet-api and sender indexes)
From the report
Evidence

import Helius from 'helius-sdk'; / const helius = new Helius('YOUR_API_KEY');

Why it matters

The current TypeScript SDK pages document createHelius({ apiKey }) with methods directly on the client. The current Rust page requires Helius::new(key, Cluster)?.

Suggested fix, not tested

Regenerate the snippets against the current SDKs.

Review: Real in 7 files (new Helius(key) vs createHelius, agents/typescript-sdk.md:26) but fails loudly at construction.

39. Low Sender index sample says it sends via Sender but calls the standard RPC
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: api-reference/sender/llms.txt:296
From the report
Evidence

// Build transaction with tip and priority fee, then send via Sender / const signature = await helius.rpc.sendTransaction(serializedTransaction, {

Why it matters

The tip is paid but Sender routing is not used.

Suggested fix, not tested

Use the SDK's Sender method (sendTransactionWithSender).

Review: Real: comment says "via Sender", call is helius.rpc.sendTransaction; correct is helius.tx.sendTransactionWithSender (agents/typescript-sdk/api-reference.md:60).

40. Low Billing index contradicts itself on plan entitlements
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: billing/llms.txt:29 vs :187; :91
From the report
Evidence

| **Enhanced WebSockets** | No | Yes | Yes | Yes | vs | WebSocket Types | Standard | Standard | Standard + Enhanced |

Why it matters

Developer-plan access to Enhanced WebSockets and LaserStream mainnet differs within the file. Line 91 keeps a "Developer+ only" restriction on getTransactionsForAddress that the prose pages dropped.

Suggested fix, not tested

Reconcile the file with the plans, credits and rate-limit pages.

Review: Real internal contradiction (Developer: Enhanced WS Yes vs Standard); rpc/endpoints.md:48 supports line 29. Index inconsistency only.

41. Low llms-full gives a per-call limit 10× lower than the method page
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: src/diffs/HeliusAPI_full/_llms-full.txt.diff:908
From the report
Evidence

batches of up to 100 full transactions or 1,000 signatures.

Why it matters

rpc/gettransactionsforaddress.md:15 says up to 1,000 full transactions per call.

Suggested fix, not tested

Correct the figure, and re-check the other figures in the bundle against their source pages.

Review: Real ("up to 100 full transactions" vs rpc/gettransactionsforaddress.md:15 "1,000"); stale low figure in an FAQ.

42. Low Privy migration guide implies social login works today
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: waas/migrating-from-privy.md:9
From the report
Evidence

the mental model (embedded, non-custodial, social/passkey login) is the same.

Why it matters

waas/configuration.md:56-63 lists Google, Apple, Discord and X as "Coming soon". Apps that rely on social login cannot migrate their users yet.

Suggested fix, not tested

State the gap in the guide and in its mapping table.

Review: configuration.md:56-63 does say Google/Apple/Discord/X are "Coming soon"; the guide's phrase is one clause in a mental-model sentence.

43. Low www llms.txt says signup always needs SOL and USDC
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: _www_llms.txt:84
From the report
Evidence

The autonomous helius signup --json flow requires a 1 USDC payment ... plus ~0.001 SOL

Suggested fix, not tested

Say that this applies only to --pay.

Review: exists

44. Low AGENTS.md links pages that were removed
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: AGENTS.md:28 (and 33)
From the report
Evidence

[/docs/rpc/overview](https://www.helius.dev/docs/rpc/overview)

Suggested fix, not tested

Link the current RPC and ZK Compression pages.

Review: exists; DELTA_MANIFEST.md:56,62 lists rpc/overview and zk-compression/introduction as REMOVED (307)

45. Low MCP tool count differs between pages
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: agents/mcp.md:7 vs agents/overview.md:11
From the report
Evidence

9 routed tools plus expandResult vs 10 routed tools

Suggested fix, not tested

Use one wording everywhere.

Review: exists

46. Low Troubleshooting example names a sign-in method that is not available
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: waas/troubleshooting.md:39
From the report
Evidence

### The wrong sign-in methods appear (e.g. Google shows, external wallet is missing)

Suggested fix, not tested

Use a sign-in method that exists today as the example.

Review: exists

47. Low Privy removal has no verification step and sits in an optional section
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: waas/migrating-from-privy.md:76
From the report
Evidence

Once users are on their Helius wallets, remove the Privy SDK.

Suggested fix, not tested

Make removal a main step. Then verify in a browser network log that no requests go to Privy hosts, and list the leftovers to clean up (env vars, CSP entries, lockfile).

Review: exists

48. Low Unpinned install script piped into bash
First rating: Low · Reviewed rating: Low · Review: location checked, kept as rated
Location: agents/skills/okx.md:55 (also line 90)
From the report
Evidence

curl -fsSL https://raw.githubusercontent.com/okx/onchainos-skills/main/install.sh | bash

Suggested fix, not tested

Pin to a tag or commit and publish a checksum.


Review: exists

51. Low API key sent over plain HTTP to regional Sender hosts
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: sending-transactions/sender.md:520-526; sending-transactions/guides/land-trades-with-sender.md:32,128
From the report
Evidence

http://slc-sender.helius-rpc.com/fast?api-key=YOUR_API_KEY / fetch(${SENDER}/fast?api-key=${HELIUS_API_KEY}, {

Why it matters

The key travels unencrypted in the query string and can be sniffed or logged on the network path.

Suggested fix, not tested

Offer HTTPS regional endpoints or header authentication, and warn against sending keys over http://.

Review: True and unwarned, but regional endpoints are HTTP by vendor design (sender-max.md:108-114) and an HTTPS global host exists. Passive sniffing of a server-to-edge hop is low-likelihood.

52. Low Preconfirmation reaction sample uses keyless Sender, now limited to 1 request/s
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: pre-confirmations/guides/trade-on-preconfirmations.md:102
From the report
Evidence

await fetch('http://ewr-sender.helius-rpc.com/fast', {

Suggested fix, not tested

Add the key on the server side and note the rate-limit dependency. Fix the same URL in jupiter-swap-api-via-sender.md:79.

Review: The Jupiter page (line 79) defines a key constant.

53. Low Preconfirmation listener decodes with a decoder that fails on transaction v1, inside an unguarded handler
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: pre-confirmations/guides/trade-on-preconfirmations.md:78
From the report
Evidence

const tx = VersionedTransaction.deserialize(buf.subarray(18));

Why it matters

preconf-subscribe.md:269-272 says older VersionedTransaction.deserialize handles only legacy and v0. The first v1 frame throws in the message handler and kills the trading process.

Suggested fix, not tested

Use a decoder that supports v1, wrap decode and handler in try/catch, and fix the "bincode" wording.

Review: preconf-subscribe.md:272 already warns to check the library version for v1; close exits for the supervisor by design (84).

54. Low Same decoder issue in the preprocessed drain loop
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: preprocessed-transactions/guides/trade-on-preprocessed.md:100
From the report
Evidence

const tx = VersionedTransaction.deserialize(item.txBytes);

Suggested fix, not tested

Same as finding 53, and catch errors per item inside the while (true) loop.

Review: Same as 53; preprocessed-subscribe.md:128 carries the caveat.

55. Low Native SOL mint value differs between Wallet API guides and reference
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: wallet-api/transfers.md:201 vs api-reference/wallet-api/transfers.md:158
From the report
Evidence

(So11111111111111111111111111111111111111111 for native SOL) vs (So11111111111111111111111111111111111111112 for

Why it matters

Code that compares mint with the documented constant misses SOL if it followed the wrong page. wallet-api/balances.md:195/202 shows both values in one response.

Suggested fix, not tested

State which value the API returns, and update every page to it.

Review: Inconsistency real (...111 pseudo-mint in guides and in the request mint param, ...112 in reference response descriptions). The request param is consistent everywhere (api-reference/wallet-api/balance-at.md:18). Which constant the API returns cannot be decided from the audited copy.

56. Low Wallet API identity and funding endpoints: Free plan access contradicts across pages
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: wallet-api/overview.md:116
From the report
Evidence

| GET /v1/wallet/{wallet}/identity | 403 — paid plans only |

Why it matters

billing/plans.md:148 lists the Wallet API as included on Free, and billing/rate-limits.md:257 gives Free a limit that covers these endpoints.

Suggested fix, not tested

Reconcile the pages and mark the exception in the plans table.

57. Low Wallet troubleshooting points users back to a public API key
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: waas/troubleshooting.md:29
From the report
Evidence

* NEXT_PUBLIC_HELIUS_API_KEY is set and valid.

Why it matters

The recommended setup in waas/quickstart.md:27-57 keeps the key on the server. This check pushes users to ship the key in the browser bundle.

Suggested fix, not tested

Make the check depend on the setup mode.

Review: waas/quickstart.md:71-83 documents the prototyping key shortcut and domain restriction; the check serves that mode.

58. Low Privy migration tells users to pass the API key to the browser provider
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: waas/migrating-from-privy.md:44
From the report
Evidence

Replace PrivyProvider with HeliusWalletProvider and pass your Helius API key

Suggested fix, not tested

Follow the quickstart: leave the key out of the provider and use the server route handler.

Review: Wording contradicts quickstart.md:31 (omit key) but links to that Setup section.

60. Low Portfolio tracker SSE relay can crash the server and is open to anyone
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: quickstart/portfolio-tracker.md:316 (route starts at line 306)
From the report
Evidence

const ws = new WebSocket(wss://mainnet.helius-rpc.com/?api-key=${process.env.HELIUS_API_KEY}); — only open and message handlers are registered

Why it matters

In the ws library, an error event with no listener is thrown as an exception. A failed upstream connection, or closing the socket while it is still connecting, takes down the Next.js process. When the upstream closes, the feed dies silently. The route has no authentication or limits, so any caller can open metered upstream sockets.

Suggested fix, not tested

Add error and close handlers that close the stream once. Validate address, and add per-IP limits.

Review: No error listener on ws is real; tutorial demo app, unauthenticated relay is demo-grade.

61. Low First CLI command fails in zsh
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: quickstart/deploy-program.md:82
From the report
Evidence

solana config set --url https://devnet.helius-rpc.com/?api-key=YOUR_API_KEY

Why it matters

zsh, the default macOS shell, treats the unquoted ? as a glob and stops with "no matches found".

Suggested fix, not tested

Quote the URL.

Review: Real (unquoted ?), loud, one-quote fix.

62. Low MCP fund-moving tools documented without approval or limit guidance
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: agents/mcp/tools.md:162
From the report
Evidence

| transferSol | Send SOL to another wallet (supports sendMax to drain full balance) |

Why it matters

The MCP and plugin pages also describe autopay from a local keypair that is stored unencrypted. A search of agents/ for approval, confirmation and spending limits found such guidance only on the OKX page.

Suggested fix, not tested

Require explicit human approval for transfers and autopay. Advise keeping only a minimal balance in that keypair and restricting the keypair file's permissions.

Review: Tool listed as claimed; the premise "keypair stored unencrypted" is not in the audited copy (grep found no such statement); approval is client-side. Missing-guidance finding.

63. Low Enhanced WebSockets blog sample is a syntax error and uses outdated hosts and plans
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: src/pages/HeliusGatekeeper_full/blog/introducing-next-generation-enhanced-websockets.md:152-156
From the report
Evidence

const / RAYDIUM_LAUNCHPAD_PROG / = ' (a string literal broken across lines)

Why it matters

The script does not parse. The post also uses atlas-* hosts and says Enhanced WebSockets need a Business plan (line 134), while current pages say Developer.

Suggested fix, not tested

Fix the literal and the hosts, or mark the post as historical.

Review: Confirmed (' string broken across lines 154-156; atlas hosts 139-141; Business plan line 134). It is a dated blog post, not reference documentation.

64. Low Replay reconnect clamps to the exact edge of the window, so the request is rejected
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: laserstream/historical-replay.md:166
From the report
Evidence

lastProcessedSlot = maxReplaySlot;

Why it matters

The window keeps moving between computing the slot and subscribing. Line 136 says an out-of-window slot is rejected.

Suggested fix, not tested

Add a safety margin, or retry with a newer slot when the request is rejected.

Review: Only on the already-lossy branch (disconnect over 48 h); plausible rejection by a few slots, a retry fixes it.

65. Low Replay resume re-delivers the slot already processed
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: laserstream/historical-replay.md:177
From the report
Evidence

lastProcessedSlot = Number(data.transaction.slot);

Why it matters

Resuming with fromSlot set to this value replays transactions that were already handled, and the sample does not deduplicate.

Suggested fix, not tested

Deduplicate by signature, or advance the watermark only when the slot is complete.

Review: Inclusive resume duplicates same-slot transactions; at-least-once is normal and benign for most consumers.

66. Low LaserStream devnet plan eligibility contradicts across pages
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: billing/credits.md:314 vs laserstream/clients.md:44
From the report
Evidence

LaserStream gRPC Devnet is available on all plans. vs Devnet is available on Developer and above.

Suggested fix, not tested

Choose one policy and apply it on every page.

Review: Contradiction real (all plans vs Developer and above); laserstream.md:41 and grpc.md:115 say all plans, four other pages say Developer+.

67. Low Webhook creation sample uses unsupported authentication and a wrong type value
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: data-streaming/quickstart.md:152-157
From the report
Evidence

-H "Authorization: Bearer YOUR_API_KEY" / "transactionTypes": ["Any"],

Why it matters

The webhook reference authenticates with ?api-key=. "Bearer" appears there only as the user's own authHeader value. Any matches no documented type (a search of webhooks/ found none).

Suggested fix, not tested

Use ?api-key= and a documented type, or leave transactionTypes empty to match all types.

Review: Differs from the reference style (?api-key=, api-reference/webhooks/llms.txt:83) and "Any" is undocumented in the audited copy; actual server behaviour not verifiable, failure would be loud.

69. Low Webhook receiver samples never verify the sender
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: data-streaming/quickstart.md:165
From the report
Evidence

app.post("/webhook", (req, res) => { / req.body.forEach((event) => {

Why it matters

Anyone who knows the URL can post forged events. authHeader is listed only as an undescribed field on the create and update reference pages.

Suggested fix, not tested

Document authHeader, check it in constant time, and reject mismatches with 401.

Review: Minimal quickstart handler; authHeader usage is shown in api-reference/webhooks/llms.txt:105,122,205, so "only an undescribed field" is partly wrong. Guidance gap, not a defect.

70. Low Contradictory end-of-pagination rule
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: api-reference/rpc/http/getprogramaccountsv2.md:46 (same text in gettokenaccountsbyownerv2.md:57)
From the report
Evidence

End of pagination is only indicated when **no accounts are returned**. ... always continue pagination until paginationKey is null.

Suggested fix, not tested

State one rule (presumably that paginationKey is null).

Review: Wording clumsy; the operative instruction ("continue until paginationKey is null") is unambiguous.

71. Low Invisible zero-width characters inside the Token program ID
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: rpc/how-to-index-solana-data.md:347 (and 394)
From the report
Evidence

'​​TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', (two U+200B characters before the ID)

Why it matters

The pasted value is not a valid public key, so the filter errors or matches nothing.

Suggested fix, not tested

Remove the characters.

Review: Confirmed: two U+200B before the ID at both lines (byte check). Pre-existing (not in diff). Error would be loud ("invalid pubkey") though hard to diagnose. Borderline.

72. Low Wrong filter field name in the LaserStream indexing sample
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: rpc/how-to-index-solana-data.md:346
From the report
Evidence

accountsInclude: [

Why it matters

Every other sample uses accountInclude, and an unknown field means the program filter is not applied.

Suggested fix, not tested

Rename the field to accountInclude.

Review: Only occurrence in the audited copy (others accountInclude, e.g. laserstream/grpc.md:129). Effect of an unknown field is not verifiable here.

73. Low Replay window given as 24 h on pages that also say 48 h
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: data-streaming.md:39, 57 (line 140 says 48 h); rpc/how-to-index-solana-data.md:319
From the report
Evidence

<Card title="24-Hour Historical Replay" / ✅ 24h

Suggested fix, not tested

Use 48 h everywhere.

Review: Real; stale low figure.

75. Low Dead-connection watchdog described in the text is not in the code
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: parsed-streams/guides/handling-reconnects.md:22
From the report
Evidence

If you see nothing at all for over a minute ... assume the connection is dead and reconnect

Why it matters

A half-open socket never fires close, so the at-most-once stream stalls silently.

Suggested fix, not tested

Track the time of the last activity, and terminate the socket when it is stale.

Review: Text/code gap real; the code is explicitly a skeleton (stub comment at 77).

76. Low Keepalive guidance contradicts the samples
First rating: Medium · Reviewed rating: Low · Review: could not be settled
Location: parsed-streams/guides/handling-reconnects.md:17
From the report
Evidence

Protocol-level WebSocket pings that client libraries send automatically do **not** reset the idle timer.

Why it matters

Samples on other pages use ws.ping() as their only keepalive, for example trade-on-preconfirmations.md:63 and data-streaming/quickstart.md:130. If this page is right, those samples are disconnected after 10 quiet minutes.

Suggested fix, not tested

State per endpoint what resets the idle timer, and use that in every sample.

Review: The "pings do not reset the idle timer" sentence is about Parsed Streams; data-streaming/quickstart.md:130 uses the standard mainnet WebSocket, where rpc/websocket.md:642 says a ping is right. Only the preconf sample (same beta host family) is arguably in conflict, and the audited copy does not say how preconf treats pings.

77. Low Reconnector stores callbacks but never dispatches notifications
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: rpc/websocket.md:399
From the report
Evidence

this.subscriptions.set(id, { method, params, callback });

Why it matters

The class has no onmessage handler, so callbacks never fire. The migration example (line 751) calls an unsubscribe() that does not exist.

Suggested fix, not tested

Add message routing and unsubscribe(), as in the quickstart manager.

Review: Confirmed: class (328-427) has no onmessage or unsubscribe; it is a reconnection-focused sketch that never claims completeness. Pre-existing.

78. Low Stream gives up after about 31 s of retries but leaves the process running
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: rpc/websocket/stream-pump-amm-data.md:147
From the report
Evidence

if (retryCount >= MAX_RETRIES) { … return;

Suggested fix, not tested

Cap the delay and keep retrying, or exit so a supervisor restarts the process.

Review: 1+2+4+8+16 = 31 s confirmed; an explicit logged give-up message is a design choice.

80. Low Sample reads .result from a Promise
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: rpc/optimization-techniques.md:72
From the report
Evidence

const { priorityFeeEstimate } = await response.json().result;

Why it matters

This throws a TypeError every time it runs.

Suggested fix, not tested

Write const { result } = await response.json();.

Review: Confirmed (await response.json().result destructures undefined, TypeError every run), but loud with a one-line fix. Body also lacks jsonrpc/id (64-70).

81. Low Incremental sync reads one page and never advances its watermark
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: rpc/optimization-techniques.md:182-183
From the report
Evidence

limit: 1000, / changedSinceSlot: lastProcessedSlot

Suggested fix, not tested

Loop on paginationKey, and advance the watermark to a slot captured before the first request.

Review: Fragment demonstrating the parameter; paging is shown just above (160-164).

82. Low "Get all accounts" baseline is a single page with the watermark taken afterwards
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: agents/typescript-sdk/best-practices.md:162
From the report
Evidence

const baseline = await helius.getProgramAccountsV2([programId, { limit: 10_000 }]);

Suggested fix, not tested

Read the slot first, page through the whole baseline, then use the earlier slot as the watermark.

Review: Fragment; currentSlot undefined; comment says "all accounts" with one page. Misleading but small.

83. Low Parallel pagination uses an async Promise executor, so failures never settle
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: das/pagination.md:216
From the report
Evidence

let promise: Promise<number> = new Promise(async (resolve, reject) => {

Why it matters

A 429 or error response throws inside the executor. reject is never called and Promise.all hangs.

Suggested fix, not tested

Use plain async functions and check the responses.

Review: Anti-pattern real; but a throw inside an async executor is an unhandled rejection that terminates Node (15+), so it fails loudly rather than hanging.

84. Low "Get all transactions" examples read only the first page
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: rpc/gettransactionsforaddress.md:97, 709
From the report
Evidence

console.log('Successful transactions in January:', data.result.data); / .flatMap(r => r.result.data)

Why it matters

Busy addresses are silently truncated at 1,000 results, and an error response makes the flatMap throw.

Suggested fix, not tested

Loop on paginationToken and check r.error.

Review: Real; line 713 tells the reader to iterate windows, pagination documented elsewhere on the page.

85. Low Heartbeat sends pings but never detects a dead connection
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: pre-confirmations/guides/trade-on-preconfirmations.md:63 (prose at line 122)
From the report
Evidence

setInterval(() => ws.ping(), 30_000); // keep the connection alive

Why it matters

The text says the ping tells a quiet stream from a dead one, but nothing checks for a pong.

Suggested fix, not tested

Track the time of the last pong, and terminate the socket when it is stale.

Review: Real; pong monitoring is a robustness extra, close then exit is the stated design.

86. Low Pump.fun mint tracker claims to log every new token but loses gaps
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: parsed-streams/guides/track-pumpfun-mints.md:36 (code at line 95)
From the report
Evidence

keep the connection alive on a quiet filter, and reconnect automatically on close.

Why it matters

The code has no keepalive and no slot-gap backfill, and it retries forever on auth errors. Delivery is at-most-once, so tokens deployed during a gap are lost.

Suggested fix, not tested

Add a backfill, bounded backoff and a stop on auth errors, or change the claim.

Review: Text claims keepalive (36); code has none (68-98). Tip at 104 points to the reconnect guide.

87. Low History scan silently skips items the parser failed on
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: parsed-events/guides/fetch-pumpfun-mints.md:92
From the report
Evidence

if (result.parserStatus !== "OK") continue;

Suggested fix, not tested

Collect and report failed signatures, and retry or fetch them.

Review: Deliberate filter in a demo; a nice-to-have at most.

88. Low Retry helper does not retry network errors that its own table lists as retryable
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: billing/rate-limits.md:434
From the report
Evidence

const res = await request();

Suggested fix, not tested

Catch thrown errors and apply the same backoff.

Review: Real vs table line 420; example only.

90. Low Token-balance check searches only the first page
First rating: Medium · Reviewed rating: Low · Review: rated too high
Location: wallet-api/balances.md:302
From the report
Evidence

const token = balances.find(t => t.mint === tokenMint);

Why it matters

Pages hold at most 100 tokens sorted by value, so low-value tokens are reported as "not found".

Suggested fix, not tested

Page through the results until the token is found.

Review: Real; the same page documents paging (352-361) and the 100-token cap (17).

91. Low Rust SDK quickstart does not compile
First rating: Medium · Reviewed rating: Low · Review: could not be settled
Location: sdks/rust.md:61
From the report
Evidence

let response: Result<Vec<EnhancedTransaction>, HeliusError> = helius.parse_transactions(request).await;

Why it matters

helius::error::Result (imported at line 44) takes one type parameter, and HeliusError is never imported.

Suggested fix, not tested

Write let response = helius.parse_transactions(request).await;.


Review: Line 44 imports helius::error::Result and line 61 gives it two type arguments; whether that alias takes one parameter needs the crate source, which is not in the audited copy. Likely true; a compile error is loud either way.

Info after review (1)

23. Info Admin usage response replaced in one step, with no transition
First rating: Medium · Reviewed rating: Info · Review: rated too high
Location: src/diffs/HeliusAPI_full/api-reference__admin__get-project-usage.md.diff:75
From the report
Evidence

-<ParamField body="usage" type="object"> … +<ParamField body="credits" type="object">

Why it matters

Clients that read usage.rpc, usage.stream or usage.websocket now get undefined values, with no deprecation note.

Suggested fix, not tested

Keep usage as a deprecated alias for a stated period, and publish a mapping from old keys to new keys.

Review: The docs faithfully record an API change (usage to credits). Nothing in the audited copy shows the old fields still exist; "no deprecation note" is a product-policy complaint, not a doc defect.

Want this for your code?

Upload a ZIP or link a public GitHub repo, pick the areas and the depth, and get findings by severity with fixes.