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
3 changes: 3 additions & 0 deletions packages/bridge-controller/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ export type {
BridgeAsset,
GenericQuoteRequest,
Protocol,
BatchSimulationResponse,
GaslessProperties,
SimulatedGasFeeLimits,
TokenAmountValues,
Step,
RefuelData,
Expand Down
13 changes: 13 additions & 0 deletions packages/bridge-controller/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ import type {
QuoteStreamCompleteSchema,
TronTradeDataSchema,
TxDataSchema,
BatchSimulationResponseSchema,
GaslessPropertiesSchema,
SimulatedGasFeeLimitsSchema,
} from './utils/validators';

export type FetchFunction = (
Expand Down Expand Up @@ -310,6 +313,16 @@ export type QuoteResponse<
quoteRequestIndex?: number;
};

/**
* This is the bridge-api response for the obtainGaslessBatch method
*/
export type BatchSimulationResponse = Infer<
typeof BatchSimulationResponseSchema
>;

export type SimulatedGasFeeLimits = Infer<typeof SimulatedGasFeeLimitsSchema>;
export type GaslessProperties = Infer<typeof GaslessPropertiesSchema>;

export enum ChainId {
ETH = 1,
OPTIMISM = 10,
Expand Down
122 changes: 74 additions & 48 deletions packages/bridge-controller/src/utils/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
assert,
pattern,
intersection,
pick,
} from '@metamask/superstruct';
import {
CaipAssetTypeStruct,
Expand Down Expand Up @@ -369,65 +370,70 @@ export const IntentSchema = type({
}),
});

export const QuoteSchema = type({
requestId: string(),
srcChainId: ChainIdSchema,
srcAsset: BridgeAssetSchema,
/**
* The amount sent, in atomic amount: amount sent - fees
* Some tokens have a fee of 0, so sometimes it's equal to amount sent
*/
srcTokenAmount: string(),
destChainId: ChainIdSchema,
destAsset: BridgeAssetSchema,
/**
* The amount received, in atomic amount
*/
destTokenAmount: string(),
/**
* The minimum amount that will be received, in atomic amount
*/
minDestTokenAmount: string(),
feeData: type({
[FeeType.METABRIDGE]: FeeDataSchema,
/**
* This is the fee for the swap transaction taken from either the
* src or dest token if the quote has gas fees included or "gasless"
*/
[FeeType.TX_FEE]: optional(
intersection([
FeeDataSchema,
type({
maxFeePerGas: string(),
maxPriorityFeePerGas: string(),
}),
]),
),
}),
export const SimulatedGasFeeLimitsSchema = type({
maxFeePerGas: string(),
maxPriorityFeePerGas: string(),
});

export const GaslessPropertiesSchema = type({
gasIncluded: optional(boolean()),
/**
* Whether the quote can use EIP-7702 delegated gasless execution
*/
gasIncluded7702: optional(boolean()),
bridgeId: string(),
bridges: array(string()),
steps: array(StepSchema),
refuel: optional(RefuelDataSchema),
priceData: optional(
type({
totalFromAmountUsd: optional(string()),
totalToAmountUsd: optional(string()),
priceImpact: optional(string()),
totalFeeAmountUsd: optional(string()),
}),
),
intent: optional(IntentSchema),
/**
* A third party sponsors the gas. If true, then gasIncluded7702 is also true.
*/
gasSponsored: optional(boolean()),
});

export const QuoteSchema = intersection([
GaslessPropertiesSchema,
type({
requestId: string(),
srcChainId: ChainIdSchema,
srcAsset: BridgeAssetSchema,
/**
* The amount sent, in atomic amount: amount sent - fees
* Some tokens have a fee of 0, so sometimes it's equal to amount sent
*/
srcTokenAmount: string(),
destChainId: ChainIdSchema,
destAsset: BridgeAssetSchema,
/**
* The amount received, in atomic amount
*/
destTokenAmount: string(),
/**
* The minimum amount that will be received, in atomic amount
*/
minDestTokenAmount: string(),
feeData: type({
[FeeType.METABRIDGE]: FeeDataSchema,
/**
* This is the fee for the swap transaction taken from either the
* src or dest token if the quote has gas fees included or "gasless"
*/
[FeeType.TX_FEE]: optional(
intersection([FeeDataSchema, SimulatedGasFeeLimitsSchema]),
),
}),
bridgeId: string(),
bridges: array(string()),
steps: array(StepSchema),
refuel: optional(RefuelDataSchema),
priceData: optional(
type({
totalFromAmountUsd: optional(string()),
totalToAmountUsd: optional(string()),
priceImpact: optional(string()),
totalFeeAmountUsd: optional(string()),
}),
),
intent: optional(IntentSchema),
}),
]);

export const TxDataSchema = type({
chainId: number(),
to: HexAddressSchema,
Expand Down Expand Up @@ -526,3 +532,23 @@ export const validateQuoteStreamComplete = (
assert(data, QuoteStreamCompleteSchema);
return true;
};

// TODO should this be here or in the bridge-status-controller?
export const BatchSimulationResponseSchema = type({
transactions: array(
intersection([
TxDataSchema,
SimulatedGasFeeLimitsSchema,
/**
* The assetId of the srcToken, used to match the simulation response with the quote response
*/
pick(BridgeAssetSchema, ['assetId']),
// updateTransactions won't work for these because we won't know the tx type
type({ type: enums(['swap', 'approval', 'bridge']) }),
]),
),
fee: type({
asset: BridgeAssetSchema,
amount: string(),
}),
});
Loading
Loading