<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Rugsight Blog]]></title><description><![CDATA[Rugsight Blog]]></description><link>https://rugsight.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Mon, 02 Nov 2026 18:45:46 GMT</lastBuildDate><atom:link href="https://rugsight.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Why "top 10 holders own 90%" is often wrong on Solana]]></title><description><![CDATA[Raw largest-account lists on Solana mix liquidity pools, bonding curves, program accounts and burn addresses with real wallets. Here is how to measure…]]></description><link>https://rugsight.hashnode.dev/why-top-10-holders-own-90-is-often-wrong-on-solana</link><guid isPermaLink="true">https://rugsight.hashnode.dev/why-top-10-holders-own-90-is-often-wrong-on-solana</guid><category><![CDATA[Security]]></category><category><![CDATA[Solana]]></category><category><![CDATA[Blockchain]]></category><category><![CDATA[Web3]]></category><dc:creator><![CDATA[Rugsight]]></dc:creator><pubDate>Sat, 31 Oct 2026 15:28:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6ae605fddce73aa746a76a14/cb40623d-4219-4e22-988b-5dc6a23450d0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Paste almost any new Solana token into a holder list and you'll see something like "top 10 holders: 92%". It looks like a rug waiting to happen. Often it isn't, because most of that 92% is not held by anyone who can sell.</p>
<p>This post explains why raw holder lists mislead, how Rugsight computes holder concentration instead, and the cases where even a careful method can't give you a number.</p>
<h2>Token accounts are not holders</h2>
<p>On Solana, a wallet doesn't hold tokens directly. Tokens live in <strong>token accounts</strong>, and each token account has an <strong>owner</strong>. The RPC call most tools start from, <code>getTokenLargestAccounts</code>, returns the 20 largest <em>token accounts</em> for a mint, not the 20 largest <em>owners</em>.</p>
<p>That causes two problems:</p>
<ol>
<li><strong>One owner can have several token accounts.</strong> Usually a wallet has one associated token account per mint, but nothing stops it from holding more. Counting accounts can split one whale into several smaller "holders".</li>
<li><strong>Many of the largest accounts are owned by programs, not people.</strong> That's the bigger problem.</li>
</ol>
<h2>What sits at the top of a typical list</h2>
<p>For a token that trades on a DEX, the largest token accounts usually include:</p>
<ul>
<li><strong>The liquidity pool's vault.</strong> An AMM pool holds one side of the pair in a token account owned by the pool program (or a PDA derived from it). On a thin token, that vault can hold 30% to 80% of the supply. Those tokens are the market; they're what buyers buy from.</li>
<li><strong>The pump.fun bonding curve.</strong> Before a pump.fun token graduates, most of its supply sits in the bonding-curve account. Calling that "one holder owns 80%" is wrong.</li>
<li><strong>Other program-owned accounts</strong>: lockers, vesting contracts, staking vaults, bridges.</li>
<li><strong>Burn and dead addresses.</strong> Tokens sent to an address nobody controls are gone in practice, even if they still count in the supply.</li>
</ul>
<p>None of those can dump on you the way a single wallet can. Count them and nearly every new token looks like 90% concentration. Then the metric tells you nothing.</p>
<h2>How Rugsight measures it</h2>
<p>For each mint we:</p>
<ol>
<li>Read the largest token accounts (<code>getTokenLargestAccounts</code>) and the total supply.</li>
<li>Resolve the <strong>owner</strong> of each of those accounts.</li>
<li>Classify each owner. If it's a known burn address, it's <strong>burn</strong>. If it's one of the token's DEX pool addresses, it's a <strong>pool</strong>. If the owner account belongs to the System Program, it's a normal <strong>wallet</strong>. Anything else (a program-derived address such as a bonding curve, vault or locker) is a <strong>program</strong>. If we can't resolve an owner, we count it as a wallet, so errors push the number up, not down.</li>
<li>Merge accounts that belong to the same owner.</li>
<li>Report <strong>top-1 wallet %</strong> and <strong>top-10 wallet %</strong> using real wallets only, and list what we excluded and why.</li>
</ol>
<p>The full report shows the top-20 breakdown with each entry labeled (wallet, pool, program, burn), so you can check our classification instead of trusting a single number.</p>
<p>Scoring then uses the wallet-only numbers: over 80% in the top 10 wallets costs 30 points, over 50% costs 20, over 30% costs 10, and any single wallet over 20% costs another 15.</p>
<h2>Where it still breaks</h2>
<p><strong>Huge tokens.</strong> For a mint with millions of token accounts, <code>getTokenLargestAccounts</code> has to rank all of them. On USDC, USDT and wrapped SOL (each with more than 10 million accounts), public and free-tier RPC nodes refuse or time out. There's no free, reliable way to get that list, so for those tokens Rugsight says plainly that holder concentration is unavailable and leaves it out of the score, instead of guessing.</p>
<p><strong>Overloaded indexes.</strong> Even for mid-size tokens like BONK or WIF, an RPC provider sometimes answers "index overloaded". We retry with backoff, fall back to another RPC, and as a last resort use the last successful holder snapshot (up to 7 days old), marked as cached in the report.</p>
<p><strong>Wallets that look like wallets.</strong> A team can split its supply across 50 fresh wallets. Each is a real wallet on-chain, so it counts as a wallet, but no single one looks large. Holder concentration alone can't catch that; you need funding-graph analysis (who funded these wallets?), which bubble-map tools do and Rugsight does not yet.</p>
<p><strong>Centralized exchange wallets.</strong> An exchange hot wallet holding 15% of a listed token is technically one wallet, but it represents thousands of customers. We don't relabel exchange wallets yet, so large listed tokens can look a bit more concentrated than they are.</p>
<h2>What to take away</h2>
<ul>
<li>Treat any "top 10 = 90%" number with suspicion until you know what's in the top 10.</li>
<li>Look for the pool and bonding-curve accounts and set them aside.</li>
<li>Concentration in <em>real wallets</em> over 50%, or one wallet over 20%, is the signal worth worrying about.</li>
<li>Even a clean distribution doesn't rule out a coordinated group of wallets.</li>
</ul>
<p>You can see the wallet-only numbers for any token on its Rugsight page: try <a href="https://rugsight.rugsight.workers.dev/token/bonk">BONK</a>, browse <a href="https://rugsight.rugsight.workers.dev/new">new tokens</a>, or read the full checklist in <a href="https://rugsight.rugsight.workers.dev/blog/how-to-check-a-solana-token-for-rug-pull-risk">how to check a Solana token for rug-pull risk</a>. The <a href="https://rugsight.rugsight.workers.dev/sample/bonk">free sample report</a> shows the labeled top-20 breakdown.</p>
<p><em>Automated technical analysis of public on-chain data. Not financial advice.</em></p>
<hr />
<p><em>Originally published on the <a href="https://rugsight.rugsight.workers.dev/blog/why-top-10-holders-is-often-wrong-on-solana">Rugsight blog</a>.</em></p>
<p><em>Drafted with AI assistance and reviewed by the author.</em></p>
]]></content:encoded></item><item><title><![CDATA[Charging AI agents per API call with x402 on Solana: notes from building Rugsight]]></title><description><![CDATA[How Rugsight sells a 0.03 USDC token-risk report to AI agents over HTTP 402 with no API keys, using the x402 exact scheme on Solana and the PayAI…]]></description><link>https://rugsight.hashnode.dev/charging-ai-agents-per-api-call-with-x402-on-solana-notes-from-building-rugsight</link><guid isPermaLink="true">https://rugsight.hashnode.dev/charging-ai-agents-per-api-call-with-x402-on-solana-notes-from-building-rugsight</guid><category><![CDATA[Solana]]></category><category><![CDATA[AI]]></category><category><![CDATA[api]]></category><category><![CDATA[Web3]]></category><dc:creator><![CDATA[Rugsight]]></dc:creator><pubDate>Sat, 31 Oct 2026 15:24:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6ae605fddce73aa746a76a14/d7ba00b7-01be-483f-a588-7042add7afdf.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Rugsight has two kinds of customers: people who paste a token into a web page, and AI agents that call an API before they buy, swap or recommend a Solana token. People can pay 1 USDC with Solana Pay. For agents, we wanted something with no sign-up, no API key and no monthly plan. We used <strong>x402</strong>: the server answers <code>402 Payment Required</code> with a price, and the client pays in the next request.</p>
<p>This post covers how the flow works on Solana, what we chose, and the things that tripped us up. It's written for developers; there's nothing to buy here.</p>
<h2>The flow</h2>
<ol>
<li>The agent calls <code>GET /api/v1/report?mint=&lt;mint&gt;</code> with no payment.</li>
<li>The server returns <strong>HTTP 402</strong>. For x402 v2, the payment requirements go in a base64 JSON <code>PAYMENT-REQUIRED</code> header; we also return the v1 JSON body for older clients. The requirements say: scheme <code>exact</code>, network Solana mainnet, asset USDC, amount <code>30000</code> (0.03 USDC in 6-decimal units), and the address to pay.</li>
<li>The client builds a Solana transaction that transfers exactly that amount of USDC, signs it as the payer, and resends the request with the payload in a <code>PAYMENT-SIGNATURE</code> (v2) or <code>X-PAYMENT</code> header.</li>
<li>The server asks a <strong>facilitator</strong> to <code>/verify</code> the payload.</li>
<li>If it's valid, the server builds the report.</li>
<li>Only then does it ask the facilitator to <code>/settle</code>, which submits the transaction on-chain.</li>
<li>The server returns <code>200</code> with the report and a <code>PAYMENT-RESPONSE</code> receipt header.</li>
</ol>
<p>The order of steps 5 and 6 matters. If the report can't be built (an RPC outage, an invalid mint), we never settle, so the agent is never charged for an error. Verify first, do the work, settle last.</p>
<h2>Why a facilitator</h2>
<p>On Solana, the facilitator can also be the <strong>fee payer</strong>: it co-signs and pays the SOL network fee, so the agent's wallet only needs USDC. That removes the most common onboarding failure ("you need SOL for gas"). We use the PayAI facilitator; its fee-payer address is part of the payment requirements so the client can build the transaction correctly.</p>
<p>The facilitator also checks things you don't want to re-implement: that the transfer instruction matches the requirements, that the amount and mint are right, and that the transaction will simulate.</p>
<h2>Things that went wrong</h2>
<p><strong>The pay-to token account didn't exist.</strong> On Solana, USDC goes to the treasury's <em>associated token account</em> (ATA), not the wallet itself. Our treasury had never held USDC, so its ATA didn't exist, and every payment failed at simulation. The fix is just to create the account (send any amount of USDC to it once), but nothing in the 402 response tells a client why it failed. We now expose <code>x402PayToReady</code> in <code>/api/health</code>, so the problem shows up before a customer finds it.</p>
<p><strong>Local pre-checks save facilitator calls.</strong> Before calling <code>/verify</code> we decode the transaction and check the obvious things ourselves: the right program, mint, destination and amount. Garbage payloads get a fast 402 with a clear error instead of a round trip.</p>
<p><strong>v1 and v2 clients both exist in the wild.</strong> Supporting both headers and both body formats cost a few dozen lines and avoided a lot of "it doesn't work with my client" debugging.</p>
<p><strong>Discovery is half the product.</strong> An API that agents can pay for is useless if agents can't find it. We publish <code>/.well-known/x402</code>, an OpenAPI document with the price on each paid route, <code>llms.txt</code>, and an MCP server with a free tool and a paid tool. The 402 response also carries a <code>bazaar</code> extension with input and output schemas, which facilitator directories use to list services after their first settled payment.</p>
<h2>Pricing</h2>
<p>0.03 USDC per report is low enough that an agent can check every token it touches, and high enough to cover the RPC and market-data calls behind a full report. The basic score (grade, verdict, flag codes) stays free at <code>/api/score/&lt;mint&gt;</code>, so an agent can triage for free and only pay when it needs the detail.</p>
<h2>Try it</h2>
<ul>
<li>Free score: <code>curl https://rugsight.rugsight.workers.dev/api/score/DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263</code></li>
<li>See the 402: <code>curl -i "https://rugsight.rugsight.workers.dev/api/v1/report?mint=DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"</code></li>
<li>Clients: <code>npm i rugsight</code>, <code>pip install rugsight</code>, and <a href="https://rugsight.rugsight.workers.dev/docs/ai-sdk">Vercel AI SDK tools</a>. The source is <a href="https://github.com/rugsightapp/rugsight">on GitHub</a> (MIT).</li>
</ul>
<p>If you're building an agent that trades or recommends Solana tokens, the <a href="https://rugsight.rugsight.workers.dev/docs">docs</a> show how to plug in a payment-aware <code>fetch</code>.</p>
<p><em>Rugsight is an automated technical tool. Not financial advice.</em></p>
<hr />
<p><em>Originally published on the <a href="https://rugsight.rugsight.workers.dev/blog/charging-ai-agents-per-call-with-x402-on-solana">Rugsight blog</a>.</em></p>
<p><em>Drafted with AI assistance and reviewed by the author.</em></p>
]]></content:encoded></item></channel></rss>