Infrastructure

Pair Requests

The demand layer. A search that finds no Pair becomes a request, requests aggregate into ranked demand, and ranked demand decides which instruments PairStreet integrates next.

Live

The demand layer

The catalog lists 44 Pair Instruments across bonds, housing, real estate, credit, equities, sectors, commodities, rates and funds. The world has thousands more. When a creator or holder searches for one that is not listed, PairStreet records the search as a Pair RequestPair RequestA user's request for a Pair Instrument the catalog does not list yet. Requests aggregate into measurable demand that drives provider integration. instead of a dead end.

That turns unsupported markets into measurable demand. Each request is a named instrument, optionally a country and a category, a count of distinct people asking for it, and a count of how many of them would launch a coin paired with it. Ranked, those counts tell PairStreet and its providers where integration work pays off.

From search to listingLIVE
  1. Search“Manhattan Residential”

    A creator searches the instrument picker, or a visitor searches Pair Markets.

  2. No supported PairEMPTY STATE

    “No Pair currently available for Manhattan Residential.” The search term carries into the request form.

  3. Request PairPOST /api/pair-requests

    Title, optional country, category and reason, and whether the requester would launch a coin with this Pair.

  4. Demand aggregatedONE COUNT PER VOTER

    Requests merge on a normalized title. Each wallet or visitor counts once per request.

  5. PairStreet sees demandGET /api/pair-requests

    Most Requested Pairs, ranked by request count, on /pairs and in the API.

  6. Provider integration opportunityPROVIDER INTERFACE

    A provider route is identified for the instrument: onchain venue, issuer, RFQ desk or broker route.

  7. Instrument addedPAIR INSTRUMENT

    The instrument enters the catalog with its provider, eligibility rules and status.

Search, request and aggregation run in the application today. Integration and listing follow PairStreet’s provider review for each instrument.

Figure summary: A user searches for Manhattan Residential. No supported Pair is found. The user requests the Pair. Demand is aggregated, one count per voter. PairStreet sees ranked demand. That becomes a provider integration opportunity. The instrument is added to the catalog.

Where requests start

Three surfaces in the application open the same request form.

  • ·The instrument picker in the create flow. A search with no match shows “No Pair currently available for” the search term, with a “Request” button prefilled with it.
  • ·Most Requested Pairs on the Pairs page (/pairs#requests). Each row has its own request button, so adding a voice to an existing request is one click.
  • ·Market explorer empty states, and the “Request a Pair” link in the site navigation.

The form asks for the market or instrument (3 to 80 characters), an optional country and category, an optional reason (“What exposure should this Pair give holders?”), and a checkbox: “I’d launch a coin with this Pair”.

How demand is counted

A request count is only useful if it cannot be inflated by one person pressing a button. The counting rules are strict and tested.

  1. Step 01normalized_key
    Normalize the title

    The title is lowercased, every run of non-alphanumeric characters becomes a single hyphen, and leading or trailing separators are dropped. “Manhattan Residential”, “manhattan residential” and “MANHATTAN-RESIDENTIAL!” all resolve to manhattan-residential, so they count toward one request.

  2. Step 02voter_key
    Identify the voter

    A connected wallet votes as wallet:<address>. Without a wallet, the voter is an anonymous visitor id stored in an HTTP-only cookie for one year.

  3. Step 03UNIQUE (request_id, voter_key)
    Count once

    The vote insert is guarded by a unique index. A repeat submission from the same voter adds nothing and returns the current counts with counted: false. Only a new vote increments request_count, and, when the box is ticked, creator_interest_count.

  4. Step 04PAIR_REQUESTED
    Record the event

    Every counted vote writes a PAIR_REQUESTED activity event with the request title and its new count. It is one of the events emitted on mainnet today; see Events.

Insert, vote and increment run in one database transaction. Writes are rate-limited to 10 requests per minute per IP address; past that the API answers 429 with the standard error envelope.

Ranked demand

The output of the demand layer is a ranking. The chart below shows its shape. Production request data is still accumulating, so the numbers are an example; the live ranking is on the Pairs page and at GET /api/pair-requests.

Most Requested Pairs, exampleILLUSTRATIVE
Manhattan ResidentialReal estate · US4,281
German BundsBonds · DE3,722
Toronto ResidentialHousing · CA2,981
Korean Government BondsBonds · KR2,102
Example counts. They illustrate how the ranking reads, not recorded production demand.

Figure summary: Example ranking of Pair Requests: Manhattan Residential 4,281 requests, German Bunds 3,722, Toronto Residential 2,981, Korean Government Bonds 2,102.

The example also shows how listings follow demand. Three of its four markets are in the catalog today: German Bunds, Toronto Housing and Korea Treasury Bonds are Pair Instruments a creator can pair with now. Manhattan Residential remains a request. That is the loop the demand layer exists to run: a request names a market, the count proves interest, and the listing makes it pairable.

From request to listing

Each request carries a status that follows it through review.

Pair Request status values
StatusMeaning
openCollecting demand. The default for every new request.
under_reviewPairStreet is evaluating instruments and provider routes for the request.
plannedA provider route is identified and the listing is scheduled.
liveThe instrument is in the catalog. The request links to it through matchedInstrumentId.
declinedNo suitable instrument or provider route; the request stays visible with its count.

A listing is a Pair Instrument record: a provider behind the provider interface, eligibility rules, a status and a settlement asset. Creators can pair with it as soon as it is active. Settlement into its Pair Asset activates when its provider route and Pair Vault custody activate; the event model defines PAIR_INSTRUMENT_ADDED for the moment a new instrument enters the catalog.

What providers see

For an issuer or a tokenized-asset provider, the demand layer answers the question that usually comes last: is anyone asking for this on Solana? Ranked requests, with country, category and creator intent, show demand before an integration is built. The Providers chapter covers what an integration involves.

API

Both endpoints are application endpoints used by pairstreet.xyz. They return JSON and use the standard error envelope.

GET /api/pair-requests

Returns the top 20 requests, ordered by request count.

HTTPExample response
GET /api/pair-requests

200 OK
[
  {
    "id": "<request-uuid>",
    "title": "Manhattan Residential",
    "country": "US",
    "category": "real_estate",
    "description": "Condos and co-ops below 96th Street.",
    "requestCount": 4281,
    "creatorInterestCount": 0,
    "status": "open",
    "createdAt": "<iso-timestamp>"
  }
]

POST /api/pair-requests

Creates a request, or adds a vote to an existing one with the same normalized title.

title
string, 3 to 80 characters. Required.
country
ISO 3166 alpha-2 code, uppercased. Optional.
category
One of the instrument categories (bonds, housing, real_estate, credit, equities, sectors, commodities, rates, funds, crypto, countries, other). Optional.
description
string, up to 500 characters. Optional.
creatorIntent
boolean, default false. True when the requester would launch a coin with this Pair.
wallet
Solana address. Optional; when present, the vote is keyed to the wallet.
HTTPExample request and response
POST /api/pair-requests
Content-Type: application/json

{
  "title": "Manhattan Residential",
  "country": "US",
  "category": "real_estate",
  "description": "Condos and co-ops below 96th Street.",
  "creatorIntent": true,
  "wallet": "<solana-address>"
}

201 Created            (first request from this voter)
200 OK                 (repeat: counts returned, nothing added)
{
  "request": { "id": "<request-uuid>", "title": "Manhattan Residential", "requestCount": 4282, "creatorInterestCount": 1, "status": "open", ... },
  "counted": true
}

Invalid input returns 400 with code INVALID_INPUT. The full endpoint list is in API, and the stored fields in Schemas.