Skip to content

Response drift: suibets — isOnchain field absent from live API, on-chain routing broken #2015

Description

@realfishsam

Exchange

suibets

Severity

MEDIUM

What Our Normalizer Expects

core/src/exchanges/suibets/normalizer.ts reads raw.isOnchain to determine whether an offer is backed by an on-chain contract, and conditionally surfaces raw.onchainOfferId:

// normalizer.ts
isOnchain: raw.isOnchain,
onchainOfferId: raw.onchainOfferId,

SuibetsRawOffer (fetcher.ts) declares both as optional fields:

isOnchain?: boolean;
onchainOfferId?: string;

What The Live API Returns

The live GET https://www.suibets.com/api/p2p/offers response does not include isOnchain:

[].isOnchain   ← ABSENT (field no longer in response)

Endpoint tested: GET https://www.suibets.com/api/p2p/offers?status=all

Note: onchainOfferId and onchainState sub-object are still present for on-chain offers.

Impact

MEDIUM: raw.isOnchain is always undefined (falsy) for every offer, regardless of whether the offer is actually on-chain. Any downstream logic that gates behavior on isOnchain === true silently treats all offers as off-chain:

  • On-chain routing and settlement paths are never triggered
  • UI elements that distinguish on-chain vs off-chain offers (e.g. chain explorer links) are suppressed for all offers including those with on-chain contracts
  • The presence of onchainState or a non-null onchainOfferId can serve as a proxy, but is not used

Suggested Fix

Replace the isOnchain field access with a derived check based on the still-present onchainState or onchainOfferId:

// normalizer.ts — derive isOnchain from surviving fields
isOnchain: raw.onchainOfferId != null || raw.onchainState != null,
onchainOfferId: raw.onchainOfferId,

Also remove isOnchain?: boolean from SuibetsRawOffer to reflect the actual API response shape.


Found by automated response shape drift audit

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions