Developers

Schemas

The relational model behind every Pair Market: the token’s internet market on one side, the financial Pair and its ledger on the other, and the status enums that govern both.

Two histories per Pair Market

PairStreet stores each Pair MarketPair MarketThe canonical pairing of an internet asset with a financial Pair: TOKEN × PAIR INSTRUMENT, plus the Pair Vault, configuration and accounting that connect them. as two separate histories. The internet market (the coin, its Pump curve, trades, candles and holders) lives in tokens, token_markets, trades and holder_balances. The financial Pair (the instrument, the vault, settlements, purchases and rewards) lives in pair_markets and the ledger tables beneath it. The two never share a row. Market cap describes the first history; Pair ValuePair ValueThe current tracked value of Pair Assets associated with a Pair Market according to PairStreet accounting: Σ quantity × reference price. Independent of the token's market cap. describes the second.

The schema is Postgres, defined with Drizzle. Three conventions hold across every table:

*_raw
Integer base-unit amounts as numeric(40,0), read as decimal strings. No floating-point drift in balances or allocations.
*_usd
numeric(24,6) read as numbers. Display and aggregation values, never the source of truth for a balance.
ledger_mode
Every financial row carries live or dev_simulated. Production reads and writes live rows only. See Ledger modeLedger modeEvery financial ledger row carries live or development. Production reads and writes live rows only..
The Pair ledger, table by tableARCHITECTURE
  1. pair_vault_fundingsIN

    Economic value credited to a market’s Pair Vault, by source.

  2. pair_settlementsPLAN

    One row per settlement run: amount, route mode, persisted plan, status.

  3. pair_purchasesACQUIRE

    Each acquisition: input mint and amount, output amount, execution price, signature.

  4. reward_epochsEPOCH

    The pool, methodology, total weight and Merkle root for one epoch.

  5. reward_allocationsALLOCATE

    One row per eligible wallet per epoch: weight and amount.

  6. reward_claimsOUT

    Claims paid to holders, linked back to the allocations they settle.

pair_markets and pair_vaults hold aggregates. The engine can rebuild both purely from the ledger rows; tests prove the read model equals the ledger.

Figure summary: Value enters through pair_vault_fundings, is converted in pair_settlements and pair_purchases, is divided in reward_epochs and reward_allocations, and leaves through reward_claims. pair_markets and pair_vaults are read models rebuilt from these rows.

Pair Market

Table pair_markets. One row per token (token_id is unique): the canonical TOKEN × PAIR INSTRUMENTPair InstrumentThe financial exposure a Pair Market is paired with, such as Tokyo Residential or Swiss Government Debt. A catalog object with a provider, an eligibility policy and a status. relationship. The aggregate columns are a read model maintained by the Pair engine from the ledger tables.

pair_markets columns
ColumnTypeMeaning
iduuidPrimary key. The pairMarketId used across the API.
tokenIduuid → tokensThe launched coin. Unique: a token has exactly one Pair Market.
pairInstrumentIduuid → pair_instrumentsThe Pair Instrument this market is PAIRED WITH.
creatorWallettext → walletsThe creator’s wallet.
pumpLaunchAddresstextThe Pump bonding curve account.
pumpMarketAddresstext, nullableThe PumpSwap pool once the coin graduates.
pairVaultAddresstext, nullableThe market’s Pair Vault. Set when vault custody activates for the instrument’s route.
statuspair_market_statuspending, active, paused, settlement_disabled, closed. Default active.
ledgerModeledger_modelive on mainnet.
configurationjsonbPairMarketConfiguration: economic sources, reward rules, fee split. See below.
pairValueUsdnumeric(24,6)Tracked value of Pair Assets held for this market.
pairAssetBalanceRawnumeric(40,0)Pair Asset currently held, in the instrument’s base units.
pairAssetAcquiredLifetimeUsdnumeric(24,6)USD value of all Pair Asset acquired.
pairAssetAcquiredLifetimeRawnumeric(40,0)Base units of all Pair Asset acquired.
holderRewardsLifetimeUsdnumeric(24,6)Value allocated to holders across all epochs.
holderRewardsClaimableUsdnumeric(24,6)Allocated and not yet claimed.
holderRewardsClaimedUsdnumeric(24,6)Claimed by holders.
eligibleHoldersintegerEligible holders in the latest epoch.
settlementsCountintegerCompleted settlements.
nextSettlementAttimestamptz, nullableNext scheduled settlement. Null while settlement is disabled.
lastSettlementAttimestamptz, nullableMost recent settlement.
createdAttimestamptzRegistration time.
graduatedAttimestamptz, nullableWhen the coin graduated from the curve.

Live markets register with status settlement_disabled (shown as “Settlement pending”) and nextSettlementAt null. Each instrument’s settlement route and vault custody activate the status change to active. See Pair Markets for the lifecycle.

PairMarketConfiguration

The configuration column holds the rules that turn trading activity into Pair Asset for holders. New markets get PairStreet’s default configuration; the feeSplit block is written from the chain by the fee-split sync after launch.

PairMarketConfiguration fields
FieldTypeMeaning
economicSources{ source, bps? }[]Streams that fund the Pair VaultPair VaultThe account that receives settlement value allocated to one Pair Market, holds it until conversion, and holds the acquired Pair Asset until it is allocated to holders.. Sources: creator_fees, launch_economics, protocol_fees, other. bps appears only when explicitly configured.
rewardMethodologyenumtime_weighted_balance (default), average_balance or snapshot_min_hold.
epochReleaseBpsnumber, optionalShare of unallocated Pair Asset released to holders each epoch. Absent means not configured.
settlementCadenceSecnumberSeconds between settlements. Default 3600 (hourly).
minHoldingRawstring, optionalMinimum balance for eligibility, in token base units.
excludeCreatorbooleanCreator wallet excluded from rewards. Default true.
excludeLiquidityAccountsbooleanCurve and pool accounts excluded. Default true.
excludedWalletsstring[]Further wallets excluded from rewards.
feeSplitobject, optionalThe creator-fee split as read from chain. Fields below.
feeSplit fields
feeSplit fieldTypeMeaning
creatorBpsnumber5000: creator share of creator fees.
protocolBpsnumber2500: PairStreet protocol share.
pairVaultBpsnumber2500: Pair Vault reserve share.
treasurystringThe PairStreet treasury wallet that receives the 50% on-chain share (protocol plus reserve).
statuslocked | pending | mismatchlocked: Pump reports creator 50%, treasury 50% with admin revoked. pending: no split yet. mismatch: a different split.
sharingConfigstring, optionalThe Pump fee-sharing config account for this mint.
shareholders{ address, shareBps }[], optionalShareholders exactly as stored on-chain.
checkedAtISO timestampWhen the chain was last read.
pair_markets.configurationlive market, placeholders in angle brackets
{
  "economicSources": [
    { "source": "creator_fees", "bps": 2500 },
    { "source": "launch_economics" }
  ],
  "rewardMethodology": "time_weighted_balance",
  "settlementCadenceSec": 3600,
  "excludeCreator": true,
  "excludeLiquidityAccounts": true,
  "excludedWallets": [],
  "feeSplit": {
    "creatorBps": 5000,
    "protocolBps": 2500,
    "pairVaultBps": 2500,
    "treasury": "5XAwPtXHkA2F68tEj5ZAZePJfJWH4tzGkeQiqK5ggfRg",
    "status": "locked",
    "sharingConfig": "<sharing-config-pda>",
    "shareholders": [
      { "address": "<creator-wallet>", "shareBps": 5000 },
      { "address": "5XAwPtXHkA2F68tEj5ZAZePJfJWH4tzGkeQiqK5ggfRg", "shareBps": 5000 }
    ],
    "checkedAt": "<timestamp>"
  }
}

On-chain there are two shareholders. The 50/25/25 split is the accounting view: the treasury’s 50% is protocol revenue (25%) plus the market’s Pair Vault reservePair Vault reserveThe 25% share of a Pair Market's creator fees earmarked for its Pair Vault. Held by the PairStreet treasury until the market's settlement route activates. (25%). That is why economicSources lists creator_fees at 2,500 bps. See Protocol Economics.

Pair Instrument

Table pair_instruments. The catalog of financial exposures a creator can pair with. 44 instruments today. The slug is the stable human key used in URLs and the API; the id is a UUID.

pair_instruments columns
ColumnTypeMeaning
iduuidPrimary key.
slugtext, uniqueStable key, for example tokyo-residential.
name, shortName, symboltextDisplay names and the instrument symbol (TKYRES).
descriptiontextWhat exposure the instrument represents.
categoryinstrument_categorycountries, bonds, housing, real_estate, credit, equities, sectors, commodities, rates, funds, crypto, other.
subcategorytext, nullableFree-form, for example Sovereign or Residential.
countrytextISO-3166 alpha-2; XX for global.
regionregionamericas, europe, asia, middle_east, africa, global.
providerIdtext → pair_providersThe provider that lists or delivers the instrument.
issuertext, nullableIssuer of the onchain asset, when one exists.
networktextsolana.
mintAddresstext, nullableThe Pair Asset mint. Null for registry-listed instruments until their route connects.
decimalsintegerPair Asset decimals. Default 6.
assetTypeasset_typesovereign_bond, municipal_bond, corporate_credit, treasury_note, real_estate, housing_index, equity_index, sector_basket, commodity, fund, rate, other.
settlementAssettextThe settlement assetSettlement assetThe asset a Pair Vault accumulates before conversion. USDC by default. mint the router spends: USDC.
statusinstrument_statusactive, paused, coming_soon, provider_unavailable, deprecated.
verificationinstrument_verificationHow the onchain asset is verified. Enum below.
isMockbooleanTrue only for development-network instruments. False across the mainnet catalog.
transferRestrictionsjsonb, nullable{ summary, tokenProgram? }: how the asset transfers.
priceSourcetext, nullableReference source: jupiter for onchain assets, index-reference for registry listings.
providerReferencetext, nullableThe provider’s key: spl:<mint> or registry:<slug>.
documentationUrltext, nullableIssuer documentation.
icon, heroImagetext, nullableUI glyph key and optional hero image.
referencePriceUsd, referencePriceAtnumeric(24,6), timestamptzLast reference price and when it was taken.
searchTermstextSpace-separated synonyms used by search.
metadatajsonbAdditional instrument metadata. Default {}.
createdAt, updatedAttimestamptzRow timestamps.

Example record

The Tokyo Residential record as the catalog stores it. Tokyo Residential is a Pair Instrument representing the target financial exposure configured for the Pair Market. It is listed by the PairStreet Pair Registry, so mintAddress is null and verification is listed: settlement into a Pair Asset activates when its provider route connects.

pair_instrumentstokyo-residential, placeholders in angle brackets
{
  "id": "<instrument-uuid>",
  "slug": "tokyo-residential",
  "name": "Tokyo Residential",
  "shortName": "Tokyo Residential",
  "symbol": "TKYRES",
  "description": "Exposure to Tokyo's residential property market: condominiums and rental housing across the 23 wards, tracked as a residential real-estate basket.",
  "category": "real_estate",
  "subcategory": "Residential",
  "country": "JP",
  "region": "asia",
  "providerId": "pairstreet-registry",
  "issuer": "PairStreet Pair Registry",
  "network": "solana",
  "mintAddress": null,
  "decimals": 6,
  "assetType": "housing_index",
  "settlementAsset": "<usdc-mint>",
  "status": "active",
  "verification": "listed",
  "isMock": false,
  "transferRestrictions": { "summary": "Onchain settlement asset connects when this Pair's provider route goes live." },
  "priceSource": "index-reference",
  "providerReference": "registry:tokyo-residential",
  "documentationUrl": null,
  "icon": "home",
  "heroImage": null,
  "referencePriceUsd": 100,
  "referencePriceAt": "<timestamp>",
  "searchTerms": "tokyo housing homes residential property real estate japan condo apartments rent japan",
  "metadata": {},
  "createdAt": "<timestamp>",
  "updatedAt": "<timestamp>"
}

Spec fields and where they live

provider
providerId, joined to pair_providers for name, kind and adapter.
restrictions
transferRestrictions on the instrument, plus eligibility rules in instrument_eligibility.
reference source
priceSource, with referencePriceUsd and referencePriceAt.
documentation
documentationUrl; the provider interface also returns issuer documents.

instrument_eligibility

instrument_eligibility columns
ColumnTypeMeaning
iduuidPrimary key.
instrumentIduuid → pair_instrumentsThe instrument the rule applies to. Cascades on delete.
ruleeligibility_ruleallow_countries, block_countries, allow_regions, block_regions, kyc_required, accredited_only.
countriestext[]ISO alpha-2 codes the rule names.
regionstext[]Regions the rule names.
notetext, nullableWhy the rule exists, for example issuer terms.

pair_providers

id (stable slug, also the adapter registry key), name, kind (provider_kind), adapterKey (registry or spl-onchain today), website, description, isMock, status and createdAt. See Providers.

Pair Vault

Table pair_vaults. One vault per Pair Market. A vault row is written when the market’s vault custody activates; until then a live market’s Pair Vault reserve accrues to the treasuryPairStreet treasuryThe protocol wallet that receives the protocol share and Pair Vault reserve of creator fees plus the 0.5% trading fee., earmarked per market, and the market detail API reports custodyModel: "pending". See Pair Vault.

pair_vaults columns
ColumnTypeMeaning
iduuidPrimary key.
pairMarketIduuid → pair_markets, uniqueThe market this vault serves.
addresstextVault address.
custodyModelcustody_modeldev_simulated, program_pda, multisig, provider_custody.
settlementAssetMinttextMint of the asset the vault accumulates before conversion.
settlementBalanceRaw / UsdnumericSettlement asset awaiting conversion.
pairAssetBalanceRawnumeric(40,0)Pair Asset held, acquired and not yet claimed.
totalDepositedUsdnumeric(24,6)Lifetime value credited.
totalConvertedUsdnumeric(24,6)Lifetime value converted into Pair Asset.
totalAllocatedUsdnumeric(24,6)Lifetime value allocated to holders.
totalClaimedUsdnumeric(24,6)Lifetime value claimed by holders.
ledgerMode, updatedAtledger_mode, timestamptzLedger mode and last update.

pair_vault_fundings

pair_vault_fundings columns
ColumnTypeMeaning
iduuidPrimary key.
vaultIduuid → pair_vaultsVault credited.
pairMarketIduuid → pair_marketsMarket credited.
sourceeconomic_sourcecreator_fees, launch_economics, protocol_fees, other.
amountRawnumeric(40,0)Amount in settlement-asset base units.
usdValuenumeric(24,6)USD value at funding time.
txSignaturetext, nullableThe funding transaction.
ledgerMode, createdAtledger_mode, timestamptzLedger mode and time.

Settlement and purchase

A settlementSettlementOne turn of a Pair Market's flywheel: the Pair Vault balance is routed, the Pair Asset acquired, accounting finalized and a reward epoch funded. converts a vault’s settlement balance into the Pair Asset through the Pair RouterPair RouterThe execution layer that converts a Pair Vault's settlement balance into an acquisition plan for the Pair Asset and hands it to the right executor.. The plan is persisted for audit, and each acquisition is its own row. See Settlement.

pair_settlements columns
ColumnTypeMeaning
iduuidPrimary key.
pairMarketId, vaultIduuidMarket and vault settled.
sequenceintegerPer-market sequence number. Unique with pairMarketId.
statussettlement_statusscheduled, planning, executing, completed, failed, cancelled.
routeModeroute_modeONCHAIN_SWAP, PROVIDER_API, RFQ, ISSUER_MINT, BROKER_ROUTE, DEV_SIMULATED.
settlementAmountRaw / UsdnumericValue settled.
planjsonbThe Pair Router acquisition plan, persisted for audit.
errortext, nullableFailure reason.
ledgerModeledger_modeLedger mode.
startedAt, completedAttimestamptzStart and finish.
pair_purchases columns
ColumnTypeMeaning
iduuidPrimary key.
settlementIduuid → pair_settlementsThe settlement this acquisition belongs to.
pairMarketId, instrumentIduuidMarket and instrument.
providerIdtext → pair_providersProvider that executed.
routeModeroute_modeRoute used.
inputMint, inputAmountRaw, inputUsdtext, numericWhat was spent.
outputAmountRaw, outputUsdnumericPair Asset received.
executionPriceUsddoubleEffective price per Pair Asset unit.
txSignaturetext, nullableExecution transaction.
statuspurchase_statusplanned, submitted, confirmed, failed.
ledgerMode, executedAtledger_mode, timestamptzLedger mode and time.

Reward epoch, allocation and claim

A reward epochReward EpochA window over which acquired Pair Asset is allocated to eligible holders by their holder weight. Produces exact integer allocations and a Merkle root. divides the Pair Asset acquired in a settlement across eligible holders by holder weightHolder WeightA holder's share basis inside a reward epoch. Under the time-weighted method: the integral of balance over time held inside the epoch (token-seconds).. Allocations sum exactly to the pool, and the epoch stores a Merkle root over (wallet, amountRaw) leaves for an onchain distributor. See Holder Rewards.

reward_epochs columns
ColumnTypeMeaning
iduuidPrimary key.
pairMarketIduuid → pair_marketsMarket.
epochNumberintegerUnique per market.
startAt, endAttimestamptzEpoch window.
methodologyreward_methodologytime_weighted_balance, average_balance, snapshot_min_hold.
rewardInstrumentIduuid → pair_instrumentsThe instrument REWARDS PAID IN.
totalPoolRaw / UsdnumericPair Asset distributed in this epoch.
eligibleHolderCountintegerHolders with non-zero weight.
totalWeightnumeric(60,0)Sum of holder weights.
allocationRoottext, nullableMerkle root over allocation leaves.
statusepoch_statusopen, calculating, allocated, finalized.
ledgerModeledger_modeLedger mode.
reward_allocations columns
ColumnTypeMeaning
iduuidPrimary key.
epochIduuid → reward_epochsEpoch. Unique with wallet.
pairMarketIduuid → pair_marketsMarket.
wallettextHolder wallet.
weightnumeric(60,0)The holder’s weight under the epoch methodology.
amountRaw, usdValuenumericPair Asset allocated.
statusallocation_statusclaimable, claimed, expired. Default claimable.
claimIduuid → reward_claims, nullableThe claim that settled this allocation.
ledgerMode, createdAtledger_mode, timestamptzLedger mode and time.
reward_claims columns
ColumnTypeMeaning
iduuidPrimary key.
wallettextClaiming wallet.
pairMarketId, instrumentIduuidMarket and the instrument paid.
amountRaw, usdValuenumericAmount claimed.
txSignaturetext, nullableClaim transaction.
statusclaim_statuspending, confirmed, failed.
ledgerMode, createdAtledger_mode, timestamptzLedger mode and time.

Pair Request

Demand for instruments not yet in the catalog. Requests aggregate by a normalized key, and each voter counts once. See Pair Requests.

pair_requests columns
ColumnTypeMeaning
iduuidPrimary key.
normalizedKeytext, uniqueNormalized title used to merge duplicate requests.
title, descriptiontextWhat was requested.
countrytext, nullableISO alpha-2.
categoryinstrument_category, nullableRequested category.
requestCountintegerDistinct voters.
creatorInterestCountintegerVoters who intend to launch a market on it.
statuspair_request_statusopen, under_review, planned, live, declined.
matchedInstrumentIduuid → pair_instruments, nullableThe instrument added for this request.
createdAt, updatedAttimestamptzRow timestamps.

pair_request_votes holds one row per voter per request (requestId, voterKey, wallet, creatorIntent, note), unique on request and voter. The voter key is the wallet when one is connected, otherwise an anonymous visitor id.

Token and token market

The internet-market side, summarized. These tables are written by launch and kept current by the indexer.

tokens
id, mint (unique), name, symbol, description, imageUrl, website, twitter, telegram, creatorWallet, launchVenue (pump), decimals (6), totalSupplyRaw, metadataUri, launchTxSignature, ledgerMode, createdAt.
token_markets
Latest venue state, one row per token: bondingCurveAddress, ammPoolAddress, reserves (reserveQuoteRaw, reserveTokenRaw, realQuoteRaw), priceUsd, priceSol, marketCapUsd, liquidityUsd, volume24hUsd, volumeLifetimeUsd, change24hPct, holders, txns24h, bondingProgressPct, graduationStatus, graduatedAt, trendingScore, lastTradeAt, updatedAt.
trades
One row per trade: side, token and quote (lamport) amounts, USD value, price, signature, block time.
holder_balances
Balance per token and wallet, firstHeldAt, and excludedReason for accounts excluded from Pair rewards (creator, vault, curve or pool, configured).
supporting
wallets, creator_profiles, activity_events (see Events), protocol_metrics (daily snapshots for analytics), indexer_cursors, uploads and metadata_docs.

Status enums

Every enum is defined once in the shared domain module and generated into Postgres. The API returns these exact strings.

Pair Market and token

Pair Market and graduation enums
EnumValueMeaning
pair_market_statuspendingRegistration not yet complete.
activeSettlement runs on the configured cadence.
pausedPair activity paused by the protocol.
settlement_disabledTrading and fee accrual live; settlement activates with the instrument’s route and vault custody. Shown as “Settlement pending”.
closedPair Market closed.
graduation_statusbondingTrading on the Pump bonding curve.
graduatingBonding progress at or above 75%.
graduatedCurve complete; the coin trades on PumpSwap.

Instrument and provider

Instrument enums
EnumValueMeaning
instrument_statusactiveAccepting new Pair Markets.
pausedTemporarily closed to new markets.
coming_soonAnnounced, not yet selectable.
provider_unavailableThe provider route is unavailable; selection reopens when it returns.
deprecatedRetired; closed to new Pair Markets.
instrument_verificationdev_mockDevelopment network only.
listedListed for pairing; the onchain settlement asset connects with the provider route.
issuer_listedMint published by the issuer and routable.
aggregator_verifiedVerified by a token-list aggregator such as Jupiter.
pairstreet_verifiedReviewed by PairStreet.
provider_kindtokenized_bonds, tokenized_securities, tokenized_fund, real_estate, commodity, onchain_dex_route, pair_registry, dev_mockThe kind of provider behind an instrument.
eligibility_ruleallow_countries, block_countries, allow_regions, block_regions, kyc_required, accredited_onlyRule types evaluated by the Eligibility Engine.

Settlement, rewards and ledger

Ledger enums
EnumValuesUsed by
route_modeONCHAIN_SWAP, PROVIDER_API, RFQ, ISSUER_MINT, BROKER_ROUTE, DEV_SIMULATEDpair_settlements, pair_purchases
settlement_statusscheduled, planning, executing, completed, failed, cancelledpair_settlements
purchase_statusplanned, submitted, confirmed, failedpair_purchases
custody_modeldev_simulated, program_pda, multisig, provider_custodypair_vaults
economic_sourcecreator_fees, launch_economics, protocol_fees, otherpair_vault_fundings, configuration
reward_methodologytime_weighted_balance, average_balance, snapshot_min_holdreward_epochs, configuration
epoch_statusopen, calculating, allocated, finalizedreward_epochs
allocation_statusclaimable, claimed, expiredreward_allocations
claim_statuspending, confirmed, failedreward_claims
ledger_modelive, dev_simulatedEvery financial row
pair_request_statusopen, under_review, planned, live, declinedpair_requests
activity_typeTOKEN_CREATED, TOKEN_TRADE, GRADUATED, PAIR_SELECTED, PAIR_VAULT_FUNDED, PAIR_ASSET_PURCHASED, PAIR_SETTLEMENT, PAIR_REWARD_ALLOCATED, PAIR_REWARD_CLAIMED, PAIR_REQUESTED, PAIR_INSTRUMENT_ADDED, PAIR_INSTRUMENT_PAUSEDactivity_events

Categories, regions and asset types are listed with the Pair Instrument columns above. The HTTP shapes built from these tables are documented in API.