Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ import {
DEFAULT_BRIDGE_CONTROLLER_STATE,
} from './constants/bridge';
import * as selectors from './selectors';
import { ChainId, RequestStatus, FeatureId } from './types';
import { ChainId, RequestStatus } from './types';
import type { BridgeControllerMessenger } from './types';
import * as balanceUtils from './utils/balance';
import * as featureFlagUtils from './utils/feature-flags';
import * as fetchUtils from './utils/fetch';
import { FeatureId } from './validators/feature-flags';

type RootMessenger = Messenger<
MockAnyNamespace,
Expand Down
12 changes: 6 additions & 6 deletions packages/bridge-controller/src/bridge-controller.sse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ import {
DEFAULT_BRIDGE_CONTROLLER_STATE,
ETH_USDT_ADDRESS,
} from './constants/bridge';
import { ChainId, RequestStatus, FeatureId } from './types';
import type { BridgeControllerMessenger, TxData } from './types';
import { ChainId, RequestStatus } from './types';
import type { BridgeControllerMessenger } from './types';
import * as balanceUtils from './utils/balance';
import { formatChainIdToDec } from './utils/caip-formatters';
import * as featureFlagUtils from './utils/feature-flags';
import * as fetchUtils from './utils/fetch';
import {
TokenFeatureType,
QuoteStreamCompleteReason,
} from './utils/validators';
import { QuoteStreamCompleteReason } from './validators/quote-stream-complete';
import { TokenFeatureType } from './validators/token-feature';
import { FeatureId } from './validators/feature-flags';
import type { TxData } from './validators/trade';

type RootMessenger = Messenger<
MockAnyNamespace,
Expand Down
9 changes: 2 additions & 7 deletions packages/bridge-controller/src/bridge-controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,7 @@ import {
} from './constants/bridge';
import { SWAPS_API_V2_BASE_URL } from './constants/swaps';
import * as selectors from './selectors';
import {
ChainId,
RequestStatus,
SortOrder,
StatusTypes,
FeatureId,
} from './types';
import { ChainId, RequestStatus, SortOrder, StatusTypes } from './types';
import type {
BridgeControllerMessenger,
QuoteResponseV1,
Expand All @@ -58,6 +52,7 @@ import {
MetricsSwapType,
UnifiedSwapBridgeEventName,
} from './utils/metrics/constants';
import { FeatureId } from './validators/feature-flags';

const EMPTY_INIT_STATE = DEFAULT_BRIDGE_CONTROLLER_STATE;

Expand Down
3 changes: 2 additions & 1 deletion packages/bridge-controller/src/bridge-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
ExchangeRateSourcesForLookup,
selectIsAssetExchangeRateInState,
} from './selectors';
import { FeatureId, RequestStatus } from './types';
import { RequestStatus } from './types';
import type {
L1GasFees,
GenericQuoteRequest,
Expand Down Expand Up @@ -88,6 +88,7 @@ import {
} from './utils/quote';
import { appendFeesToQuotes } from './utils/quote-fees';
import { getMinimumBalanceForRentExemptionInLamports } from './utils/snaps';
import type { FeatureId } from './validators/feature-flags';

const metadata: StateMetadata<BridgeControllerState> = {
quoteRequest: {
Expand Down
31 changes: 14 additions & 17 deletions packages/bridge-controller/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,8 @@ export type {
Quote,
QuoteResponseV1 as QuoteResponse,
FeeData,
TxData,
Intent,
IntentOrderLike,
BitcoinTradeData,
TronTradeData,
BridgeControllerState,
BridgeControllerAction,
BridgeControllerActions,
Expand Down Expand Up @@ -83,22 +80,28 @@ export {
SortOrder,
ChainId,
RequestStatus,
FeatureId,
type TokenFeature,
type QuoteStreamCompleteData,
type BridgeControllerGetStateAction,
type BridgeControllerStateChangeEvent,
} from './types';

export type {
TxData,
BitcoinTradeData,
TronTradeData,
Trade,
} from './validators/trade';
export { isBitcoinTrade, isTronTrade, isEvmTxData } from './validators/trade';
export { FeeType, ActionTypes } from './validators/quote-response';
export {
FeeType,
ActionTypes,
BridgeAssetSchema,
TokenFeatureType,
validateQuoteStreamComplete,
QuoteStreamCompleteReason,
BatchSellTransactionType,
} from './utils/validators';
} from './validators/quote-stream-complete';
export { BatchSellTransactionType } from './validators/batch-sell';
export { TokenFeatureType } from './validators/token-feature';
export { BridgeAssetSchema } from './validators/bridge-asset';
export { FeatureId } from './validators/feature-flags';

export {
ALLOWED_BRIDGE_CHAIN_IDS,
Expand Down Expand Up @@ -168,13 +171,7 @@ export {
formatAddressToAssetId,
} from './utils/caip-formatters';

export {
extractTradeData,
isBitcoinTrade,
isTronTrade,
isEvmTxData,
type Trade,
} from './utils/trade-utils';
export { extractTradeData } from './utils/trade-utils';

export {
selectBridgeQuotes,
Expand Down
4 changes: 2 additions & 2 deletions packages/bridge-controller/src/selectors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ import {
formatChainIdToDec,
formatChainIdToHex,
} from './utils/caip-formatters';
import { validateQuoteResponseV1 } from './utils/validators';
import { BatchSellTransactionType } from './utils/validators';
import { validateQuoteResponseV1 } from './validators/quote-response';
import { BatchSellTransactionType } from './validators/batch-sell';

const MOCK_USDC_ADDRESS = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
const MOCK_MUSD_ADDRESS = '0x12345A7890123456789012345678901234567890';
Expand Down
40 changes: 15 additions & 25 deletions packages/bridge-controller/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,32 @@ import type {
import type { BridgeController } from './bridge-controller';
import type { BridgeControllerMethodActions } from './bridge-controller-method-action-types';
import type { BRIDGE_CONTROLLER_NAME } from './constants/bridge';
import type { SimulatedGasFeeLimitsSchema } from './validators/batch-sell';
import type { BatchSellTradesResponseSchema } from './validators/batch-sell';
import type { BridgeAssetSchema } from './validators/bridge-asset';
import type { FeatureId } from './validators/feature-flags';
import type {
BitcoinTradeDataSchema,
BridgeAssetSchema,
ChainConfigurationSchema,
ChainRankingSchema,
PlatformConfigSchema,
} from './validators/feature-flags';
import type {
FeeDataSchema,
IntentSchema,
PlatformConfigSchema,
ProtocolSchema,
QuoteResponseSchema,
QuoteSchema,
StepSchema,
TokenFeatureSchema,
QuoteStreamCompleteSchema,
TronTradeDataSchema,
TxDataSchema,
BatchSellTradesResponseSchema,
GaslessPropertiesSchema,
SimulatedGasFeeLimitsSchema,
TxFeeGasLimitsSchema,
} from './utils/validators';
} from './validators/quote-response';
import type { QuoteStreamCompleteSchema } from './validators/quote-stream-complete';
import type { TokenFeatureSchema } from './validators/token-feature';
import type {
BitcoinTradeData,
TronTradeData,
TxData,
} from './validators/trade';

export type FetchFunction = (
input: RequestInfo | URL | string,
Expand Down Expand Up @@ -258,16 +263,6 @@ export enum StatusTypes {
COMPLETE = 'COMPLETE',
}

export enum FeatureId {
UNKNOWN = 'unknown',
PERPS = 'perps',
QUICK_BUY_FOLLOW_TRADING = 'quick_buy_follow_trading',
QUICK_BUY_TOKEN_DETAILS = 'quick_buy_token_details',
DAPP_SWAP = 'dapp_swap',
BATCH_SELL = 'batch_sell',
UNIFIED_SWAP_BRIDGE = 'unified_swap_bridge',
}

/**
* These are types that components pass in. Since data is a mix of types when coming from the redux store, we need to use a generic type that can cover all the types.
* Payloads with this type are transformed into QuoteRequest by fetchBridgeQuotes right before fetching quotes
Expand All @@ -288,14 +283,9 @@ export type FeeData = Infer<typeof FeeDataSchema>;

export type Quote = Infer<typeof QuoteSchema>;

export type TxData = Infer<typeof TxDataSchema>;

export type Intent = Infer<typeof IntentSchema>;
export type IntentOrderLike = Intent['order'];

export type BitcoinTradeData = Infer<typeof BitcoinTradeDataSchema>;

export type TronTradeData = Infer<typeof TronTradeDataSchema>;
/**
* This is the type for the quote response from the bridge-api
* TxDataType can be overriden to be a string when the quote is non-evm
Expand Down
2 changes: 1 addition & 1 deletion packages/bridge-controller/src/utils/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import type {
BridgeControllerState,
GenericQuoteRequest,
QuoteResponseV1,
TxData,
} from '../types';
import { ChainId } from '../types';
import type { TxData } from '../validators/trade';
import {
formatChainIdToCaip,
formatChainIdToDec,
Expand Down
2 changes: 1 addition & 1 deletion packages/bridge-controller/src/utils/feature-flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {
DEFAULT_FEATURE_FLAG_CONFIG,
} from '../constants/bridge';
import type { FeatureFlagsPlatformConfig, ChainConfiguration } from '../types';
import { validateFeatureFlagsResponse } from '../validators/feature-flags';
import { formatChainIdToCaip } from './caip-formatters';
import { validateFeatureFlagsResponse } from './validators';

export const formatFeatureFlags = (
bridgeFeatureFlags: FeatureFlagsPlatformConfig,
Expand Down
31 changes: 26 additions & 5 deletions packages/bridge-controller/src/utils/fetch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import type { CaipAssetType } from '@metamask/utils';
import { mockBridgeQuotesErc20Erc20V1 } from '../../tests/mock-quotes-erc20-erc20';
import { mockBridgeQuotesNativeErc20V1 } from '../../tests/mock-quotes-native-erc20';
import { BridgeClientId, BRIDGE_PROD_API_BASE_URL } from '../constants/bridge';
import { FeatureId } from '../types';
import { BatchSellTransactionType } from '../validators/batch-sell';
import { FeatureId } from '../validators/feature-flags';
import {
fetchBridgeQuotes,
fetchBridgeTokens,
fetchAssetPrices,
fetchBatchSellTrades,
formatBatchSellTradesRequest,
} from './fetch';
import { BatchSellTransactionType } from './validators';

const mockFetchFn = jest.fn();

Expand Down Expand Up @@ -887,6 +887,27 @@ describe('fetch', () => {
),
),
);
expect(
// @ts-expect-error - reason is not in type
result.map((error) => ({ ...error, reason: error.reason?.message })),
).toMatchInlineSnapshot(`
[
{
"reason": "Invalid batch simulation response. StructError: At path: transactions.0.maxFeePerGas -- Expected a string, but received: 1000",
"status": "rejected",
},
{
"reason": "Invalid batch simulation response. StructError: At path: transactions.0.maxFeePerGas -- Expected a string matching \`/^0x[0-9a-f]+$/\` but received "1000"",
"status": "rejected",
},
{
"reason": "Invalid batch simulation response. StructError: At path: transactions.0.maxFeePerGas -- Expected a string, but received: 291",
"status": "rejected",
},
]
`);
expect(mockConsoleWarn).not.toHaveBeenCalled();
mockConsoleWarn.mockRestore();

expect(mockFetchFn).toHaveBeenCalledTimes(4);
expect(mockFetchFn).toHaveBeenCalledWith(
Expand All @@ -900,15 +921,15 @@ describe('fetch', () => {
).toMatchInlineSnapshot(`
[
{
"reason": "Invalid batch simulation response. StructError: At path: transactions.0.maxFeePerGas -- Expected a value of type \`HexString\`, but received: \`1000\`",
"reason": "Invalid batch simulation response. StructError: At path: transactions.0.maxFeePerGas -- Expected a string, but received: 1000",
"status": "rejected",
},
{
"reason": "Invalid batch simulation response. StructError: At path: transactions.0.maxFeePerGas -- Expected a value of type \`HexString\`, but received: \`"1000"\`",
"reason": "Invalid batch simulation response. StructError: At path: transactions.0.maxFeePerGas -- Expected a string matching \`/^0x[0-9a-f]+$/\` but received "1000"",
"status": "rejected",
},
{
"reason": "Invalid batch simulation response. StructError: At path: transactions.0.maxFeePerGas -- Expected a value of type \`HexString\`, but received: \`291\`",
"reason": "Invalid batch simulation response. StructError: At path: transactions.0.maxFeePerGas -- Expected a string, but received: 291",
"status": "rejected",
},
]
Expand Down
18 changes: 8 additions & 10 deletions packages/bridge-controller/src/utils/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,21 @@ import type {
QuoteStreamCompleteData,
BatchSellTradesRequest,
BatchSellTradesResponse,
FeatureId,
} from '../types';
import { validateBatchSellTradesResponse } from '../validators/batch-sell';
import { validateBridgeAsset } from '../validators/bridge-asset';
import type { FeatureId } from '../validators/feature-flags';
import { validateQuoteResponseV1 } from '../validators/quote-response';
import { validateQuoteStreamComplete } from '../validators/quote-stream-complete';
import { validateTokenFeature } from '../validators/token-feature';
import { isEvmTxData } from '../validators/trade';
import { getEthUsdtResetData } from './bridge';
import {
formatAddressToAssetId,
formatAddressToCaipReference,
formatChainIdToDec,
} from './caip-formatters';
import { fetchServerEvents } from './fetch-server-events';
import { isEvmTxData } from './trade-utils';
import {
validateQuoteResponseV1,
validateSwapsTokenObject,
validateTokenFeature,
validateQuoteStreamComplete,
validateBatchSellTradesResponse,
} from './validators';

export const getClientHeaders = ({
clientId,
Expand Down Expand Up @@ -76,7 +74,7 @@ export async function fetchBridgeTokens(

const transformedTokens: Record<string, BridgeAsset> = {};
tokens.forEach((token: unknown) => {
if (validateSwapsTokenObject(token)) {
if (validateBridgeAsset(token)) {
transformedTokens[token.address] = token;
}
});
Expand Down
4 changes: 2 additions & 2 deletions packages/bridge-controller/src/utils/metrics/properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import type {
QuoteMetadata,
QuoteRequest,
QuoteResponseV1,
TxData,
} from '../../types';
import { FeatureId } from '../../types';
import type { TxData } from '../../validators/trade';
import { getNativeAssetForChainId, isCrossChain } from '../bridge';
import {
formatAddressToAssetId,
Expand All @@ -23,6 +22,7 @@ import type {
QuoteWarning,
RequestParams,
} from './types';
import { FeatureId } from '../../validators/feature-flags';

export const toInputChangedPropertyKey: Partial<
Record<keyof QuoteRequest, InputKeys>
Expand Down
5 changes: 3 additions & 2 deletions packages/bridge-controller/src/utils/quote-fees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ import type {
QuoteResponseV1,
L1GasFees,
NonEvmFees,
TxData,
BridgeControllerMessenger,
} from '../types';
import { isTronTrade } from '../validators/trade';
import type { TxData } from '../validators/trade';
import { isNonEvmChainId, sumHexes } from './bridge';
import { formatChainIdToCaip } from './caip-formatters';
import { computeFeeRequest } from './snaps';
import { extractTradeData, isTronTrade } from './trade-utils';
import { extractTradeData } from './trade-utils';

/**
* Appends transaction fees for EVM chains to quotes
Expand Down
2 changes: 1 addition & 1 deletion packages/bridge-controller/src/utils/quote.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import type {
Quote,
NonEvmFees,
L1GasFees,
TxData,
} from '../types';
import type { TxData } from '../validators/trade';
import {
isValidQuoteRequest,
getQuoteIdentifier,
Expand Down
Loading
Loading