rwa_market program. Per-asset state lives in
PDAs keyed by the SPL mint — the mint address is effectively the “token id”, and you
derive every account you need from it. Tokens are Token-2022 mints.
Program IDs (same on every cluster)
A program id equals its deploy keypair’s pubkey, so the same id is used on devnet/testnet/mainnet.Per-cluster addresses
Only the RPC endpoint and the payment-token mints differ per cluster.Which payment mint applies is per-asset — read
payout_token from the token’s
TokenMeta before trading.Getting cNGN on Solana
Most assets are naira-denominated and settle in cNGN, so you need cNGN on Solana before you can buy. Third-party services, listed for convenience — GetEquity does not operate them.
The Orca pool is a Whirlpool at
DdYMJgiucDr2VuTrYceYDDgGsUAtihvAkUdPjFjYm6ZS, holding
cNGN as token A and USDC as token B.
Fiat on-ramps sell cNGN too, but they settle it on whichever chain that service uses — not
necessarily Solana. The issuer keeps a fuller list at cngn.co/merchants.
Tradeable RWA tokens (mainnet)
Token-2022 mints, 6 decimals, transfer hook enabled. Read on chain 2026-09-24 — re-check rather than trusting this table, and note that a mint existing does not mean it trades.is_active lives on the Asset PDA (["asset", mint] under rwa_market), not on the mint
or the token metadata. An inactive asset still has a mint, still has holders and still shows a
price, so the only reliable check is that field — buys and sells revert without it.These are mainnet mints and do not exist on devnet. Point your connection at the
cluster that matches the mints you are using — a mainnet mint queried on devnet simply
reads as a missing account, which is easy to mistake for an empty balance.
Tradeable RWA tokens (devnet)
Only assets with a Solana mint can be traded here.DPRI is currently the only asset
live on Solana — the others are EVM-only, so they have no mint on this cluster.
Deriving the accounts you need
Every per-asset account is a PDA of a constant seed + the SPL mint pubkey.round_idx is a little-endian u64, not a string — new BN(idx).toArrayLike(Buffer, "le", 8).
The program-level Config
One per program, not per asset, and seeded only by a constant:
It holds that program’s
authority (the Squads vault) and operator. You do not pass it to
buy/sell, but every account-creating instruction takes it, and it is what makes per-asset
admin fields non-forgeable: they are written from Config.authority rather than from whoever
calls first. If you build an instruction from an older IDL that has no config account, the
program rejects it.
