Superbridge
Start typing to search...

Reference

Type Guards

Type guard helpers for working with discriminated unions

The SDK includes type guard helpers for working with the various discriminated unions returned by the API.

import { guards } from '@superbridge/sdk';

Route Guards

getRoutes() resolves to either a RouteResponse (success) or a RouteError (top-level error such as the entire route being paused or exceeding the global USD cap). Use guards.routes to narrow.

const response = await sb.getRoutes({ /* ... */ });

if (guards.routes.isError(response)) {
  // RouteError - discriminate on `type`
  if (response.type === 'Paused') {
    // PausedRouteErrorDto
  }
  if (response.type === 'Disabled') {
    // DisabledRouteErrorDto
  }
  if (response.type === 'UsdAmountTooLarge') {
    // UsdAmountTooLargeRouteErrorDto - has amountUsd, maximumUsd
  }
  return;
}

// guards.routes.isResponse(response) - has `results`
const { results } = response;

Quote Guards

Each entry in RouteResponse.results[] has a result field that is either a QuoteDto5 (a usable quote with an initiatingTransaction) or a QuoteError (a per-provider error such as AmountTooSmall). Use guards.quotes to narrow.

for (const route of response.results) {
  if (guards.quotes.isQuote(route.result)) {
    // QuoteDto5 - has initiatingTransaction, fees, steps, receive
  }

  if (guards.quotes.isError(route.result)) {
    // QuoteError - discriminate on `type`
  }
}

Once narrowed to an error, discriminate on type directly — TypeScript will narrow to the specific error DTO.

for (const route of response.results) {
  if (!guards.quotes.isError(route.result)) continue;

  const error = route.result;

  if (error.type === 'AmountTooLarge') {
    // AmountTooLargeQuoteErrorDto - has maximum
  }

  if (error.type === 'AmountTooSmall') {
    // AmountTooSmallQuoteErrorDto - has minimum
  }

  if (error.type === 'PriceImpactTooHigh') {
    // PriceImpactTooHighQuoteErrorDto - has priceImpactPercent, maximumPriceImpactPercent
  }

  if (error.type === 'GenericError') {
    // GenericQuoteErrorDto - has error
  }

  // 'Paused' | 'Disabled' | 'EscapeHatchNotSupported' | 'ERC777MintToSmartContract'
}

Gas Estimate Guards

TransactionStepNotReadyDto.estimatedGas is shaped per chain family. Use guards.gasEstimate to narrow.

for (const step of bridge.steps) {
  if (step.type !== 'transaction' || step.transactionType !== 'not-ready') {
    continue;
  }

  const gas = step.estimatedGas;

  if (guards.gasEstimate.isEvm(gas)) {
    // EvmGasEstimateDto - has gasLimit
  }

  if (guards.gasEstimate.isSvm(gas)) {
    // SvmGasEstimateDto - has computeUnitLimit
  }
}

Narrowing transactions and steps

Initiating transactions and activity steps don't have dedicated guards — narrow on the discriminating property directly.

// Initiating transaction - discriminated by `type`
const { initiatingTransaction } = quote;

if (initiatingTransaction.type === 'evm') {
  // InitiatingTransactionEvmDto5 - has to, data, value
}
if (initiatingTransaction.type === 'evm-gasless') {
  // InitiatingTransactionEvmGaslessDto5 - has typedData
}
if (initiatingTransaction.type === 'svm') {
  // InitiatingTransactionSvmDto5 - has data (base64)
}
if (initiatingTransaction.type === 'starknet') {
  // InitiatingTransactionStarkDto5 - has calls
}

Steps narrow on type, then on transactionType / waitType.

for (const step of bridge.steps) {
  if (step.type === 'transaction') {
    if (step.transactionType === 'ready') {
      // TransactionStepReadyDto - fetch via getStepTransaction
    }
    if (step.transactionType === 'done') {
      // TransactionStepDoneDto - has confirmation
    }
    if (step.transactionType === 'not-ready') {
      // TransactionStepNotReadyDto - has estimatedGas
    }
    if (step.transactionType === 'auto') {
      // TransactionStepAutoDto - executed automatically
    }
  }

  if (step.type === 'wait') {
    if (step.waitType === 'not-started') {
      // WaitStepNotStartedDto
    }
    if (step.waitType === 'in-progress') {
      // WaitStepInProgressDto - has startedAt, label
    }
    if (step.waitType === 'done') {
      // WaitStepDoneDto - has actualDuration
    }
  }

  if (step.type === 'info') {
    // InfoStepDto - has text, link
  }
}