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
}
}