Loading page…
Loading page…
The complete reference for Commodify: user guides, protocol mathematics, and API endpoints. Commodity references do not convey ownership or redemption rights.
Commodify supports community-token launches using Raydium LaunchLab on Solana. Mainnet launch economics are separate from the illustrative local and devnet templates.
Mainnet launches: GLD retains its enabled 8 GLDx route. Newly admitted commodity references use the native SOL route and its common fixed target. Both require reviewed network readiness and an explicit wallet signature. Create-only is the default and makes no initial purchase. Existing pools retain their recorded on-chain economics.
Other templates: The 16 SOL local/devnet template is for testing, not the target for a new mainnet launch. Graduated mainnet CPMM trading remains gated.
The launched asset is a community token. Commodity quotes and SOL/USD values are informational references only: they are not backing, collateral, redemption rights, or a price guarantee. The token is not a commodity or a claim on any real-world physical asset.
Creating a new local market preview requires specific field formatting for the SOL-first launch direction. These checks do not submit a Solana transaction.
| Field | Validation Rules |
|---|---|
| Name | 3 to 80 characters. Trimmed. |
| Ticker | 2 to 10 characters. Must contain only ASCII letters and numbers. Automatically uppercased. |
| Description | Optional. Maximum 1000 characters. |
| Links (Web/X/Telegram) | Optional. Must start with http:// or https://, have a valid hostname/URL, contain no credentials. Maximum 2048 characters. |
| Image | Optional. PNG, JPEG, or WebP only. Maximum size 4 MB. Uploaded images become publicly accessible immediately. |
The launch interface allows pairing the community token with either a single commodity reference or a basket. The catalog contains various items across Metals, Energy, Agriculture, Livestock, Fast food, CS2, Game gold, Trading cards, Water, Cars, and Currencies. These commodity and SOL/USD values are informational references only; the launch quote asset is native SOL, represented as WSOL where an SPL token account is required.
Permits exactly one valid catalog symbol. The curve uses the item's USD reference for display and comparison only. It does not create a commodity claim or use the reference as collateral.
Select between 1 and 5 distinct symbols. The interface visually weights them equally. The basket's normalized USD value is informational; curve balances and trade amounts remain SOL-denominated.
Interacting with a local market preview follows these strict deterministic operations. The target quote asset is native SOL/WSOL.
The connected wallet interface acts only as a display layer. Under the hood, a browser-local practice wallet initializes with exactly 100 SOL of illustrative local SOL.
localStorage. Clearing site data permanently deletes these local preview records.Mainnet launches use a quote-specific Raydium LaunchLab constant-product policy. GLD settles in GLDx; newly admitted references settle in native SOL. Commodity USD and displayed conversion values remain informational only.
With zero migration fee, 1 billion supply and the 800M/200M allocation, valuations scale directly with the pool's quote-denominated net target. The native target is fixed from the finalized GLDx/WSOL baseline at slot 448085028 (3.795192310333775942 SOL per GLDx): ceil(8 × rate × 10⁹) = 30,361,538,483 lamports. Gross input is ceil(net × 10,000 / 9,925) = 30,590,970,764 lamports. These are curve parameters, not deposited funds or a liquidity guarantee.
const migrationSupply = totalSupply - curveSupply; // 200M
const openingFDV = netTarget * totalSupply * migrationSupply / curveSupply ** 2;
const graduationFDV = netTarget * totalSupply / migrationSupply;
const feeRate = 0.0075; // 0.25% Raydium + 0.50% COMMODIFY
const grossRequired = netTarget / (1 - feeRate);Buys use a constant-product formula. Gross input in the pool's actual quote asset is reduced by the unchanged 0.75% fee to determine net curve input.
const netQuote = grossQuote * (1 - feeRate);
const tokenOut = tokenReserve - (tokenReserve * quoteReserve) / (quoteReserve + netQuote);Sells calculate the gross SOL output, then apply the modeled fee. Fees are not added back to reserves.
const grossQuoteSOL = quoteReserve - (tokenReserve * quoteReserve) / (tokenReserve + tokenAmount);
const feeSOL = grossQuoteSOL * feeRate;
const netQuoteSOL = grossQuoteSOL - feeSOL;For the future 8 GLDx mainnet policy, the unchanged 80/20 construction gives a 2.5 GLDx opening FDV and 40 GLDx graduation FDV. Completing an 8 GLDx net target requires approximately 8.060453 GLDx of gross buys at a 0.75% fee.
1. Preserve allocations and fees:
1B supply = 800M curve + 200M migration; fee = 0.75%
2. Quadruple the original 2 GLDx target:
Net target = 8 GLDx; opening FDV = 2.5 GLDx; graduation FDV = 40 GLDx
3. Distinguish gross purchases:
8 / (1 - 0.0075) ≈ 8.060453 GLDx
A SOL equivalent is intentionally unavailable without a fresh GLDx/SOL quote and conversion-cost estimate.
The current model uses a fixed 0.75% total fee: 0.25% is the observed Raydium protocol fee and 0.50% is the proposed fixed COMMODIFY platform fee. This is not a holder-reward or treasury-allocation schedule.
Prices are sourced strictly from free-tier public endpoints with no subscription mechanisms. No endpoint accepts private keys or credentials. These commodity feeds expose informational USD references (including priceUSD) only; they do not determine the SOL quote reserve, provide backing, or create a commodity claim.
| Category / Provider | Symbols | Unit & Frequency | Source |
|---|---|---|---|
| Metals (Gold API) | GLD, SILV, PLAT, PALL, COPP | USD / troy oz (Copper: / lb) Current / Indicative | gold-api.com |
| FX (Frankfurter/ECB) | EUR, JPY | Base USD Daily Reference | frankfurter.dev |
| Energy (U.S. EIA via FRED) | WTI, BRENT, NGAS, GASO, HEAT | Barrel / MMBtu / Gallon Daily Government | fred.stlouisfed.org |
The following catalogue symbols represent display-only or theoretical components. They explicitly return an unavailable status from the API. Future integration with licensed providers (e.g. Barchart, Trading Economics) is pending legal and subscription approval.
ALUM, LUMB, WHEAT, CORN, SOY, SOYO, RICE, OATS, COFF, COCO, COTT, SUGAR, CATTLE, HOGS, FEED, BURG, FRIES, PIZZA, CS2, GP, TCG, WATER, CAR
The current named browser-injection set is Phantom, Solflare, Backpack, and Glow. The launch and market routes currently request Phantom explicitly; the on-chain auditor console can detect the other named providers for this contract harness. This is an implementation and test boundary, not a claim that every extension version is certified. A wallet is supportable only when its provider-contract evidence and the real-wallet checklist below are both recorded.
Run node --test tests/solana-wallet-compat.test.mjs from COMMODIFY artifact. The deterministic evidence schema is cmc.solana.wallet-compatibility.v1. Each record includesnoFundsSent: true and these checks:
{
"schema": "cmc.solana.wallet-compatibility.v1",
"wallet": { "id": "phantom", "displayName": "Phantom" },
"mode": "manual",
"noFundsSent": true,
"cluster": "devnet",
"capturedAtUtc": "<recorded UTC time>",
"checks": {
"prompt": { "status": "pass", "detail": "prompt shown" },
"publicKeyContinuity": { "status": "pass", "detail": "unchanged" },
"signedMessageImmutability": { "status": "pass", "detail": "unchanged" },
"rejection": { "status": "pass", "detail": "cancelled; no submission" },
"disconnect": { "status": "pass", "detail": "cleared and reconnected" },
"recovery": { "status": "pass", "detail": "pending record recovered" }
}
}Use a fresh browser profile or unlocked devnet wallet, with no mainnet approval and no valuable balance. The prompt/rejection checks must use the in-memory no-op transaction and must not be submitted. Save one evidence record per wallet, extension version, browser, and commit. Never paste a seed phrase or private key into the record.
Until every item is evidenced, describe the wallet as detected orprovider-contract tested, not as fully supported. Mainnet funds are outside this compatibility claim.
The public API provides system health, quote routing, and image storage services. No authentication keys are required. All responses use JSON unless otherwise specified.
The documentation snippets below use app.example.com or api.example.com as explicit domain placeholders to illustrate HTTP calls. In practice, you must query the exact host your frontend is running on. Upload requests enforce a strict Same-Origin Policy if the Origin header is present. Do not blindly copy-paste the example domains into your production code.
Read-only Solana/Raydium readiness check. The server calls only the configured Solana JSON-RPC methods needed to verify genesis and the pinned LaunchLab/CPMM program accounts; it is not a general RPC proxy. The endpoint accepts devnet or mainnet-beta. HTTP 200 means network and program verification passed; it does not authorize mainnet activation. HTTP 503 means that read verification failed. Responses use no-store and private RPC URLs and upstream details are never returned. Mainnet activation fails closed until activationEligible is true.
const response = await fetch('/network/solana?cluster=mainnet-beta');
const body = await response.json();
const readiness = body.readiness;
// readiness.connected: boolean
// readiness.networkReady: boolean
// readiness.activationEligible: boolean
// readiness.activation: "eligible" | "not-eligible"
// readiness.blockers: string[]
// readiness.quoteAsset: { native: "SOL", wrapped: "WSOL", ... }
// HTTP success proves network reads only; activation requires the explicit gate
if (!response.ok || !readiness.activationEligible) throw new Error(readiness.blockers[0]);Returns the current health status of the API server.
curl https://api.example.com/api/healthz{
"status": "ok"
}Fetches combined commodity reference quotes from external free-tier public providers. These feeds, including priceUSD, are informational references only and do not replace native SOL/WSOL as the launch quote asset or provide backing, collateral, or a price guarantee. Upstream providers are not guaranteed and some catalogue symbols may return an "unavailable" status. Results are cached in-process for 30 seconds (even failures are cached to prevent flooding). HTTP responses use Cache-Control: no-store. Provider failures are represented in a 200 response with an unavailable quote status. Use /market-data/quotes on this app’s origin, not /api/market-data/quotes; health and storage use the /api prefix.
| Field | Type | Description |
|---|---|---|
| symbol | string | The catalogue identifier (e.g. GLD, WTI) |
| priceUSD | number | null | Current unit price in USD, if available. |
| changePercent | number | null | Percentage change, if available. |
| changePeriod | "previous business day" | null | The timeline for the change percent. |
| status | "current" | "daily" | "reference" | "unavailable" | The freshness and availability state of the feed. |
| source | string | null | Human-readable provider name (e.g. Gold API). |
| sourceUrl | string | null | The URL to the data provider. |
| updatedAt | string | null | ISO-8601 or YYYY-MM-DD timestamp from the provider. |
| message | string | Contextual message or warning regarding the data. |
curl https://app.example.com/market-data/quotes{
"quotes": {
"GLD": {
"symbol": "GLD",
"priceUSD": 2345.60,
"changePercent": null,
"changePeriod": null,
"status": "current",
"source": "Gold API",
"sourceUrl": "https://gold-api.com/",
"updatedAt": "2024-05-20T12:00:00Z",
"message": "Latest indicative provider quote. Precious metals: USD per troy oz..."
},
"EUR": {
"symbol": "EUR",
"priceUSD": 1.085,
"changePercent": -0.12,
"changePeriod": "previous business day",
"status": "daily",
"source": "Frankfurter / ECB",
"sourceUrl": "https://frankfurter.dev/",
"updatedAt": "2024-05-19",
"message": "Daily reference rate dated 2024-05-19, not a real-time FX quote."
},
"CORN": {
"symbol": "CORN",
"priceUSD": null,
"changePercent": null,
"changePeriod": null,
"status": "unavailable",
"source": null,
"sourceUrl": null,
"updatedAt": null,
"message": "Feed not connected"
}
},
"fetchedAt": "2024-05-20T12:00:05.000Z",
"refreshAfterMs": 30000
}Uploads a raw binary image for a token market. Required to be a direct file upload (no multipart wrapper). It employs a shared rate limit budget of 60 uploads per 15 minutes, shared by all callers only per process (does not use IP headers). Maximum size is 4 MiB.
// Example browser same-origin fetch
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
const response = await fetch('/api/storage/token-images', {
method: 'POST',
headers: {
'Content-Type': file.type // 'image/png', 'image/jpeg', or 'image/webp'
},
body: file // Raw bytes sent directly
});
const data = await response.json();
console.log(data.imageURL); // "/api/storage/token-images/<uuid>"{
"imageURL": "/api/storage/token-images/123e4567-e89b-12d3-a456-426614174000"
}{ "error": "Token image upload is empty." } or invalid magic bytes mismatch.{ "error": "Token image uploads require the same origin." }{ "error": "Token image must be 4 MB or smaller." }{ "error": "Token image must be PNG, JPEG, or WebP." }{ "error": "The shared token image upload budget is exhausted. Please try again later." } (Includes a Retry-After header in seconds).{ "error": "Failed to save token image." }Retrieves previously uploaded raw image bytes by their UUID. The server streams the image directly, applies the correct Content-Type (PNG/JPEG/WebP) based on object metadata, and attaches a rigid X-Content-Type-Options: nosniff security header.
Caching: Image responses use public, max-age=31536000 (1 year). No authentication is required to view images.
curl -O -J https://api.example.com/api/storage/token-images/123e4567-e89b-12d3-a456-426614174000{ "error": "Token image not found." } — returned for invalid UUID strings or missing objects.{ "error": "Failed to serve token image." }The current environment emphasizes local data testing and strict network separation.
localStorage mechanism (e.g., cmc_curve_markets, cmc_curve_wallet). There is no server/database persistence. Clearing browsing data results in immediate, irreversible loss of all local preview progress.localStorage quota limits, launch workflows perform manual rollback snapshots.By design, the homepage shows an empty list of active markets until the Solana/Raydium release gates pass and a real onchain deployment exists. The markets you create are intentionally sequestered to your local browser and display only in the portfolio and local commodities lists.
The token image upload route strictly enforces the Same-Origin Policy. If your browser sends an Origin header, it must perfectly match the Host of the API server.
The local buy calculates the exact output using the SOL-denominated constant-product formula. The guardrails reject any trade that attempts to output tokens pushing the distributed supply past the 800,000,000 token limit. Graduation is not enabled; you cannot bypass this cap.
No. The target is Raydium LaunchLab on Solana, but the current interface is browser-local only. It does not construct or sign transactions, mint liquidity, perform graduation, or move SOL. Mainnet activation remains fail-closed behind the Solana readiness gates.
Read-only Solana/Raydium readiness is being checked.
Server-side RPC access only. No wallet signing, transaction construction, contract deployment, or fund movement. Mainnet activation fails closed until every readiness gate passes. Refreshes every minute.
The browser-local preview is not an onchain deployment. Solana mainnet activation is fail-closed: the product must remain inactive unless the readiness endpoint verifies the exact mainnet-beta cluster, finalized Raydium program accounts, and every release-gate configuration.
Future GLD launches retain the 8 GLDx net target and GLDx route. Newly admitted commodity references use the common native-SOL/WSOL policy: 30.361538483 SOL net and 30.590970764 SOL gross at the fixed 0.75% fee. The native target exceeds the finalized 24 SOL configuration minimum. The separate 16 SOL devnet template is unchanged. Existing mainnet pools keep their actual immutable on-chain targets for trading, display, and recovery; changing the CREATE default does not retarget them.
The native target was fixed from the finalized Orca GLDx/WSOL observation at slot 448085028, block time 2026-09-18T12:34:59Z, at 3.795192310333775942 SOL per GLDx. It is not dynamically fetched from commodity quotes. Network and GLDx conversion costs float independently. There are no holder rewards, automatic buybacks, or creator fee.
GET /network/solana?cluster=mainnet-beta returns readiness data without exposing private RPC configuration. A non-ready response is HTTP 503 and must not be treated as permission to trade. Activation remains blocked until all of the following are resolved:
mainnet-beta cluster are required.