The DDD ratio lives on-chain. Read stablecoin dominance directly from a Solana program account — no API keys, no middlemen, no rate limits.
The @snowplow1337/ddd-oracle-sdk package handles account deserialization. Peer dependency on @solana/web3.js.
// Read the DDD ratio from Solana mainnet import('@snowplow1337/ddd-oracle-sdk').then(async ({ readDDD }) => { const { Connection } = await import('@solana/web3.js'); const conn = new Connection('https://api.mainnet-beta.solana.com'); const s = await readDDD(conn); console.log('DDD = ', s.dddPercent.toFixed(4) + '%'); console.log('Stables = $' + (Number(s.totalStablesUsd) / 1e9).toFixed(2) + 'B'); });
node --input-type=module or use dynamic import() as shown above.
Versioned read-only endpoints backed by the same on-chain accounts as the SDK. Big integers are returned as strings. Send If-None-Match with the previous ETag to receive 304 Not Modified when the oracle sequence is unchanged.
GET /api/v1/oracle/snapshot — summary plus chain, issuer, and token books (one Solana multi-account read). Includes consistent; if false, retry later.GET /api/v1/oracle/summary — headline summary only (cheapest).GET /api/jupiter-solana-route — read-only Jupiter swap/v1 quote (no swap). Query: inputMint, outputMint, optional amount (raw units; default 1000000 when inputMint is USDC), slippageBps. Optional env JUPITER_API_KEY for higher Jupiter limits.Production: set SOLANA_RPC_URL in Netlify to your RPC provider. Optional ?debug=1 adds non-sensitive metadata.
No packages required — uses only Python's standard library to query the Solana JSON-RPC and decode the binary account layout directly.
import urllib.request, json, base64, struct from datetime import datetime, timezone # Base58 encoder (no deps) ALPH = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" def b58(b): n = int.from_bytes(b, 'big'); s = '' while n: n, r = divmod(n, 58); s = ALPH[r] + s return '1' * (len(b) - len(b.lstrip(b'\x00'))) + s # Fetch all 4 oracle accounts in one RPC call req = urllib.request.Request( 'https://api.mainnet-beta.solana.com', data=json.dumps({ "jsonrpc": "2.0", "id": 1, "method": "getMultipleAccounts", "params": [[ "8DAncbbsEkmsCCakHpNK5zf49XLcWQrryTBYdjgcLWxA", # summary "97g36T1PV3anxCwxV6ue5MmF2A9HQHMsLqevckrkqjzK", # chains "GznG6pxbLPrqeYDd5aFXJcXK5SQ4wXifBtqjep34DNe", # issuers "7FRjdiN489qMU2R8G2RumBPxRjanY9683gnXttKP4Fhv", # tokens ], {"encoding": "base64"}], }).encode(), headers={'Content-Type': 'application/json'}, ) r = json.loads(urllib.request.urlopen(req).read())['result']['value'] s, c, ib, t = (base64.b64decode(a['data'][0]) for a in r) ts_utc = lambda u: datetime.fromtimestamp(u, tz=timezone.utc).isoformat() # Summary account layout (offset 73): ddd, stables, m2, ts, slot, seq ddd, stb, m2, ts, slot, seq = struct.unpack_from('<QQQqQQ', s, 73) print(f"DDD ratio : {ddd/1e4:.4f}%") print(f"Stables : ${stb/1e9:,.4f}B") print(f"US M2 : ${m2/1e12:,.4f}T") print(f"Updated : {ts_utc(ts)} (slot {slot:,})") print(f"Sequence : {seq}") print(f"Admin : {b58(s[8:40])}") # Book accounts: chains, issuers, tokens def read_book(name, d): cnt = d[25] print(f"\n--- {name} (count={cnt}) ---") for k in range(cnt): o = 26 + k*29 nm = d[o+1:o+1+d[o]].decode('utf-8', errors='replace') sup, pct = struct.unpack_from('<QI', d, o+17) print(f" {k+1:<3} {nm:<16} ${sup/1e9:>10,.2f}B {pct/1e6:.4f}%") read_book('CHAINS', c) read_book('ISSUERS', ib) read_book('TOKENS', t)
The oracle writes to four accounts. Read any of them directly via getAccountInfo or getMultipleAccounts.
| Account | Role | Address | |
|---|---|---|---|
| program | Oracle program ID | XJjnewyPHcfb2ogMN1uAZGyt25XbKN2DWnm1GfAwddd | |
| summary | DDD ratio, totals, metadata | 8DAncbbsEkmsCCakHpNK5zf49XLcWQrryTBYdjgcLWxA | |
| chains | Supply breakdown by chain | 97g36T1PV3anxCwxV6ue5MmF2A9HQHMsLqevckrkqjzK | |
| issuers | Supply breakdown by issuer | GznG6pxbLPrqeYDd5aFXJcXK5SQ4wXifBtqjep34DNe | |
| tokens | Supply breakdown by token | 7FRjdiN489qMU2R8G2RumBPxRjanY9683gnXttKP4Fhv |
getAccountInfo call is all you need.
No SDK? Fetch the summary account directly with a standard Solana JSON-RPC call. Works with any HTTP client in any language.
$ curl -sS https://api.mainnet-beta.solana.com \ -X POST \ -H 'Content-Type: application/json' \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "getAccountInfo", "params": [ "8DAncbbsEkmsCCakHpNK5zf49XLcWQrryTBYdjgcLWxA", { "encoding": "base64", "commitment": "confirmed" } ] }'
A successful response is not meant to be human-readable at a glance. The RPC returns JSON; inside it, result.value.data[0] is a base64-encoded binary account (the oracle’s on-chain layout). Solana does not turn that into “DDD = 1.39%” for you — you decode base64, then read little-endian fields starting at byte 73 (see the layout table below). The giant string that looks like gibberish is normal.
If a python3 -c "…" example printed nothing: double quotes make bash/zsh expand $ inside Python f-strings before Python runs. Use the version below with single-quoted -c '…' so stdin from curl still reaches Python (do not use curl | python3 <<'PY' — that replaces stdin and breaks the pipe).
$ curl -sS 'https://api.mainnet-beta.solana.com' -X POST \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"getAccountInfo","params":["8DAncbbsEkmsCCakHpNK5zf49XLcWQrryTBYdjgcLWxA",{"encoding":"base64","commitment":"confirmed"}]}' \ | python3 -c ' import sys, json, base64, struct from datetime import datetime, timezone j = json.load(sys.stdin) b64 = j["result"]["value"]["data"][0] raw = base64.b64decode(b64) ddd, stb, m2, ts, slot, seq = struct.unpack_from("<QQQqQQ", raw, 73) print("DDD % ", round(ddd / 1e4, 4)) print("Stables ", "${:.2f}B".format(stb / 1e9)) print("US M2 ", "${:.2f}T".format(m2 / 1e12)) print("Updated ", datetime.fromtimestamp(ts, tz=timezone.utc).strftime("%Y-%m-%d %H:%M UTC")) print("Slot ", slot) print("Sequence ", seq) '
"commitment": "confirmed" in the params object; many setups need it. If nothing comes back: try the URL without a trailing slash; check QuickNode for an IP allowlist (your home IP must be allowed, or the call is rejected); run curl -sS (shown above) or add -v to see HTTP errors. On Windows, run the same command in Git Bash or WSL — PowerShell often breaks multiline JSON in single quotes.
The summary account is a packed binary struct. All integers are little-endian. The DDD ratio and supply figures start at byte offset 73.
| Field | Offset | Type | Description |
|---|---|---|---|
| discriminator | 0 | [u8; 8] | Anchor account discriminator |
| admin | 8 | [u8; 32] | Admin pubkey (base58 encoded) |
| authority | 40 | [u8; 32] | Update authority pubkey |
| ddd_ratio | 73 | u64 LE | DDD ratio × 10⁶. Divide by 10,000 for percentage. e.g. 13900 → 1.3900% |
| total_stables_usd | 81 | u64 LE | Total stablecoin supply in USD (raw cents × 10⁰). e.g. 319000000000 → $319B |
| m2_usd | 89 | u64 LE | US M2 money supply in USD. e.g. 21700000000000 → $21.7T |
| data_timestamp | 97 | i64 LE | Unix timestamp (UTC) of last data update |
| slot | 105 | u64 LE | Solana slot of last write |
| sequence | 113 | u64 LE | Monotonically increasing write counter. Use to detect stale reads. |
| chain_count | 121 | u8 | Number of chain entries in the chains book |
| issuer_count | 122 | u8 | Number of issuer entries in the issuers book |
| token_count | 123 | u8 | Number of token entries in the tokens book |
The GitHub Packages SDK returns a parsed object. All bigint fields are raw on-chain values.
| Field | JS Type | Description |
|---|---|---|
| dddPercent | number | DDD ratio as a percentage (e.g. 1.3900). Ready to display. |
| totalStablesUsd | bigint | Total stablecoin supply in USD (raw). Divide by 1e9 for billions. |
| m2Usd | bigint | US M2 in USD (raw). Divide by 1e12 for trillions. |
| dataTimestamp | number | Unix timestamp of last oracle update (UTC seconds). |
| slot | bigint | Solana slot when the data was last written. |
| sequence | bigint | Write sequence counter. Compare across reads to detect stale data. |
sequence numbers across the summary and book accounts. A mismatch flags a mid-write read.
api.mainnet-beta.solana.com. The green live terminal below uses a dedicated endpoint so browser reads stay reliable; use your own provider in production.
Humans often choose stablecoins based on preference, habit, brand trust or chain loyalty. Agents should use live data. DDD Oracle gives agents machine readable stablecoin signals, including digital dollar dominance, issuer concentration and chain distribution.
Monitor issuer concentration before recommending stablecoin allocation.
Alert when TCD, HHI or top issuer share rises too high.
Use chain distribution now, and future velocity data later, to help choose where stablecoins should move.
Read stablecoin data directly instead of scraping dashboards.
DDD decides. Execution providers execute.
Add the live stablecoin dominance ratio to any page. Real-time data from the DDD API on each load, no API key, free to use.
Questions? @dddtracker
Stay stable
One email a week. What moved the ratio, which chains grew, and which issuers gained ground.