@openocean.finance/widget-types
Version:
Types for the OpenOcean Widget
843 lines (715 loc) • 20.4 kB
text/typescript
import type {
Address,
Hash,
Hex,
TypedDataDomain,
TypedDataParameter,
} from 'viem'
import type { BridgeDefinition } from './bridges.js'
import type { Chain, ChainId, ChainKey, ChainType } from './chains/index.js'
import type { ExchangeDefinition } from './exchanges.js'
import type { Action, FeeCost, OpenOceanStep, StepToolDetails } from './step.js'
import type { Token } from './tokens/index.js'
/**
* Used as a bigint replacement for TransactionRequest because bigint is not serializable
*/
export type BigIntish = string
/**
* Pagination options for the API
*/
export interface PaginationQuery {
limit?: number
next?: string
previous?: string
}
/**
* API response for paginated requests
*/
export interface PaginatedResponse<T> {
hasNext?: boolean
hasPrevious?: boolean
next?: string
previous?: string
total?: number
data: T[]
}
export type TransactionRequest = {
to?: string
from?: string
nonce?: number
gasLimit?: BigIntish
gasPrice?: BigIntish
data?: string
value?: BigIntish
chainId?: number
type?: number
accessList?: { address: string; storageKeys: string[] }[]
maxPriorityFeePerGas?: BigIntish
maxFeePerGas?: BigIntish
customData?: Record<string, any>
ccipReadEnabled?: boolean
}
/**
* Timing options
*/
export interface TimingStrategyMinWaitTime {
strategy: 'minWaitTime'
minWaitTimeMs: number
startingExpectedResults: number
reduceEveryMs: number
}
export type TimingStrategyMinWaitTimeString =
`minWaitTime-${number}-${number}-${number}`
export type TimingStrategy = TimingStrategyMinWaitTime
export type TimingStrategyString = TimingStrategyMinWaitTimeString
export interface Timing {
swapStepTimingStrategies?: TimingStrategy[]
routeTimingStrategies?: TimingStrategy[]
}
export interface TimingStrings {
swapStepTimingStrategies?: TimingStrategyString[]
routeTimingStrategies?: TimingStrategyString[]
}
export const Orders = ['RECOMMENDED', 'FASTEST', 'CHEAPEST', 'SAFEST'] as const
export type Order = (typeof Orders)[number]
export interface RoutesRequest {
fromChainId: number
fromAmount: string
fromTokenAddress: string
fromAddress?: string
toChainId: number
toTokenAddress: string
toAddress?: string
options?: RouteOptions
fromAmountForGas?: string
}
export interface RouteOptions {
integrator?: string // Should contain the identifier of the integrator. Usually, it's dApp/company name.
fee?: number // 0.03 = take 3% integrator fee (requires verified integrator to be set)
maxPriceImpact?: number // Hide routes with price impact greater than or equal to this value
order?: Order // (default: CHEAPEST) 'FASTEST' | 'CHEAPEST'
slippage?: number // (default: 0.03) Expressed as decimal proportion, 0.03 represents 3%
referrer?: string // Integrators can set a wallet address as a referrer to track them
allowSwitchChain?: boolean // (default: false) Whether chain switches should be allowed in the routes
allowDestinationCall?: boolean // (default: true) destination calls are enabled by default
bridges?: AllowDenyPrefer
exchanges?: AllowDenyPrefer
timing?: Timing
/**
* @deprecated This property is deprecated and will be removed in future versions.
*/
insurance?: boolean // Whether the user wants to insure their tx
}
export type ToolsResponse = {
exchanges: {
key: string
name: string
logoURI: string
supportedChains: ChainId[]
}[]
bridges: {
key: string
name: string
logoURI: string
supportedChains: {
fromChainId: ChainId
toChainId: ChainId
}[]
}[]
}
export interface AllowDenyPrefer {
allow?: string[] // (default: [all])
deny?: string[] // (default: [])
prefer?: string[] // (default: []) // eg. ['1inch'] to use 1inch if available and fall back to others if not
}
/**
* @deprecated _InsuranceState is deprecated and will be removed in future versions.
*/
export const _InsuranceState = [
'INSURED',
'INSURABLE',
'NOT_INSURABLE',
] as const
/**
* @deprecated InsuranceState is deprecated and will be removed in future versions.
*/
export type InsuranceState = (typeof _InsuranceState)[number]
/**
* @deprecated InsuranceState is deprecated and will be removed in future versions.
*/
export interface Insurance {
state: InsuranceState
feeAmountUsd: string
}
export interface Route {
id: string
insurance: Insurance
fromChainId: number
fromAmountUSD: string
fromAmount: string
fromToken: Token
fromAddress?: string
toChainId: number
toAmountUSD: string
toAmount: string
toAmountMin: string
toToken: Token
toAddress?: string
gasCostUSD?: string // Aggregation of underlying gas costs in usd
containsSwitchChain?: boolean // Features required for route execution
steps: OpenOceanStep[]
tags?: Order[]
// Add data property for extended route information
data?: {
prependedOperatingExpenseCost?: string
estimatedGas?: number
}
}
export type ToolErrorType = 'NO_QUOTE'
export interface ToolError {
errorType: ToolErrorType
code: string
action: Action
tool: string
message: string
}
export type ErroredPaths = { [subpath: string]: ToolError[] }
export type ErroredRoute = {
overallPath: string
subpaths: ErroredPaths
}
export type FilteredResult = {
overallPath: string
reason: string
}
export type UnavailableRoutes = {
filteredOut: FilteredResult[]
failed: ErroredRoute[]
}
export interface RoutesResponse {
routes: Route[]
unavailableRoutes: UnavailableRoutes
}
export type PossibilityTopic = 'chains' | 'tokens' | 'bridges' | 'exchanges'
/**
* We don't want to support this endpoint anymore in the future. /chains, /tools, /connections, and /tokens should be used instead
* @deprecated
*/
export interface PossibilitiesRequest {
chains?: number[] // (default: [all]) // eg. [1, 56, 100]
bridges?: AllowDenyPrefer
exchanges?: AllowDenyPrefer
include?: PossibilityTopic[]
}
/**
* Should not be accessed via the types package anymore
* @deprecated
*/
export interface PossibilitiesResponse {
chains?: Chain[]
tokens?: Token[]
bridges?: BridgeDefinition[]
exchanges?: ExchangeDefinition[]
}
export interface GetTokenRequest {
chain: number | string
token: string
}
export enum TokenHistoricGranularity {
THIRTY_MIN = '30min',
HOUR = 'hour',
DAY = 'day',
OVER_DAY = '>day',
}
export interface GetTokenHistoricRequest {
chain: number | string
token: string
timestamp: number
granularity?: TokenHistoricGranularity
}
export interface TokenPriceHistoricResponse {
chainId: number
tokenAddress: string
isNativeToken: boolean
priceUSD: string
timestamp: number
granularity: TokenHistoricGranularity
}
export interface ToolConfiguration {
allowBridges?: string[]
denyBridges?: string[]
preferBridges?: string[]
allowExchanges?: string[]
denyExchanges?: string[]
preferExchanges?: string[]
}
export interface QuoteRequest extends ToolConfiguration, TimingStrings {
fromChain: number | string
fromToken: string
fromAddress: string
fromAmount: string
toChain: number | string
toToken: string
toAddress?: string
order?: Order
slippage?: number | string
integrator?: string
referrer?: string
fee?: number | string
allowDestinationCall?: boolean // (default : true) // destination calls are enabled by default
fromAmountForGas?: string // the amount of token to convert to gas
maxPriceImpact?: number // hide routes with price impact greater than or equal to this value
skipSimulation?: boolean
/**
* @deprecated This property is deprecated and will be removed in future versions.
*/
insurance?: boolean // indicates whether the user wants a quote with bridge insurance
}
export interface QuoteToAmountRequest
extends Omit<QuoteRequest, 'fromAmount' | 'fromAmountForGas' | 'insurance'> {
toAmount: string
}
export interface ContractCall {
fromAmount: string
fromTokenAddress: string
toContractAddress: string
toContractCallData: string
toContractGasLimit: string
toApprovalAddress?: string
toTokenAddress?: string
}
type PartialContractCallsQuoteRequest = ToolConfiguration & {
fromChain: number | string
fromToken: string
fromAddress: string
toChain: number | string
toToken: string
toFallbackAddress?: string
contractOutputsToken?: string
contractCalls: ContractCall[]
slippage?: number | string
integrator?: string
referrer?: string
fee?: number | string
allowDestinationCall?: boolean // (default : true) // destination calls are enabled by default
}
export type ContractCallsQuoteRequestToAmount =
PartialContractCallsQuoteRequest & {
toAmount: string
}
export type ContractCallsQuoteRequestFromAmount =
PartialContractCallsQuoteRequest & {
fromAmount: string
}
export type ContractCallsQuoteRequest =
| ContractCallsQuoteRequestFromAmount
| ContractCallsQuoteRequestToAmount
export const isContractCallsRequestWithFromAmount = (
r: ContractCallsQuoteRequestFromAmount | ContractCallsQuoteRequestToAmount
): r is ContractCallsQuoteRequestFromAmount => 'fromAmount' in r
export const isContractCallsRequestWithToAmount = (
r: ContractCallsQuoteRequestFromAmount | ContractCallsQuoteRequestToAmount
): r is ContractCallsQuoteRequestToAmount => 'toAmount' in r
/* @deprecated */
export interface ContractCallQuoteRequest extends ToolConfiguration {
fromChain: number | string
fromToken: string
fromAddress: string
toChain: number | string
toToken: string
toAmount: string
toContractAddress: string
toContractCallData: string
toContractGasLimit: string
toApprovalAddress?: string
toFallbackAddress?: string
contractOutputsToken?: string
slippage?: number | string
integrator?: string
referrer?: string
fee?: number | string
allowDestinationCall?: boolean
}
export interface ConnectionsRequest extends ToolConfiguration {
fromChain?: number | string
fromToken?: string
toChain?: number | string
toToken?: string
allowSwitchChain?: boolean // (default: true) the connections that require chain switch (multiple signatures) are included by default
allowDestinationCall?: boolean // (default: true) the connections that includes destination calls are included by default
chainTypes?: ChainType[]
}
export interface Connection {
fromChainId: number
toChainId: number
fromTokens: Token[]
toTokens: Token[]
}
export interface ConnectionsResponse {
connections: Connection[]
}
export interface GetStatusRequest {
txHash: string
bridge?: string
fromChain?: number | string
toChain?: number | string
}
export interface BaseTransactionInfo {
txHash: string
chainId: ChainId
txLink: string
}
export interface ExtendedTransactionInfo extends BaseTransactionInfo {
amount?: string
amountUSD?: string
token?: Token
gasPrice: string
gasUsed: string
gasToken: Token
gasAmount: string
gasAmountUSD: string
timestamp?: number
value?: string
includedSteps?: IncludedStep[]
}
export interface PendingReceivingInfo {
chainId: ChainId
}
const _StatusMessage = [
// The transaction was not found -- likely not mined yet
'NOT_FOUND',
// A third party service is not available
'INVALID',
// The transfer is pending
'PENDING',
// The transfer is done
'DONE',
// The transfer failed
'FAILED',
] as const
export type StatusMessage = (typeof _StatusMessage)[number]
const _SubstatusPending = [
// The bridge is waiting for additional confirmations
'WAIT_SOURCE_CONFIRMATIONS',
// The off-chain logic is in progress, waiting for the destination tx to be mined
'WAIT_DESTINATION_TRANSACTION',
// The bridge API / subgraph is temporarily unavailable
'BRIDGE_NOT_AVAILABLE',
// The RPC for source/destination chain is temporarily unavailable
'CHAIN_NOT_AVAILABLE',
// A refund has been requested and is in progress
'REFUND_IN_PROGRESS',
// We cannot determine the status of the transfer
'UNKNOWN_ERROR',
] as const
export type SubstatusPending = (typeof _SubstatusPending)[number]
const _SubstatusDone = [
// The transfer was successful
'COMPLETED',
// The transfer was partially successful
// This can happen for specific bridges like Across
// which may provide alternative tokens in case of low liquidity
'PARTIAL',
// The transfer was not successful but it has been refunded
'REFUNDED',
] as const
export type SubstatusDone = (typeof _SubstatusDone)[number]
const _SubstatusFailed = [
// The amount in the request exceeds the allowance
'INSUFFICIENT_ALLOWANCE',
// The token amount is not enough to execute the transfer
'INSUFFICIENT_BALANCE',
// The gas limit is lower than tx would consume
'OUT_OF_GAS',
// The requested quote is expired and can’t be processed anymore
'EXPIRED',
// Slippage conditions were not met
'SLIPPAGE_EXCEEDED',
// We cannot determine the cause of the failure
'UNKNOWN_FAILED_ERROR',
] as const
export type SubstatusFailed = (typeof _SubstatusFailed)[number]
export type Substatus = SubstatusPending | SubstatusDone | SubstatusFailed
export const isSubstatusPending = (
substatus: Substatus
): substatus is SubstatusPending =>
_SubstatusPending.includes(substatus as SubstatusPending)
export const isSubstatusDone = (
substatus: Substatus
): substatus is SubstatusDone =>
_SubstatusDone.includes(substatus as SubstatusDone)
export const isSubstatusFailed = (
substatus: Substatus
): substatus is SubstatusFailed =>
_SubstatusFailed.includes(substatus as SubstatusFailed)
export interface BaseStatusData {
status: StatusMessage
substatus?: Substatus
substatusMessage?: string
}
export interface StatusData extends BaseStatusData {
tool: string
sending: BaseTransactionInfo
receiving: PendingReceivingInfo
}
export interface FailedStatusData extends BaseStatusData {
status: 'FAILED'
sending: BaseTransactionInfo
}
export type StatusResponse = FullStatusData | StatusData | FailedStatusData
interface TransferMetadata {
integrator: string
}
export type IncludedStep = {
fromAmount: string
fromToken: Token
toAmount: string
toToken: Token
bridgedAmount?: string
tool: string
toolDetails: StepToolDetails
}
export interface FullStatusData extends StatusData {
transactionId: string
sending: ExtendedTransactionInfo
receiving: PendingReceivingInfo | ExtendedTransactionInfo
feeCosts: FeeCost[]
openoceanExplorerLink: string
fromAddress: string
toAddress: string
metadata: TransferMetadata
bridgeExplorerLink?: string
}
export interface ExtendedChain extends Chain {
nativeToken: Token
diamondAddress?: string
permit2?: string
permit2Proxy?: string
}
export interface ChainsResponse {
code: number
data: ExtendedChain[]
}
export interface ChainsRequest {
chainTypes?: ChainType[]
}
export interface ToolsRequest {
chains?: (ChainKey | ChainId)[]
}
export type TokensRequest = {
chains?: (ChainId | ChainKey)[]
chainTypes?: ChainType[]
minPriceUSD?: number
}
export type TokensResponse = {
tokens: { [chainId: number]: Token[] }
}
export type RequestOptions = {
signal?: AbortSignal
}
export interface Integrator {
integratorId: string
feeBalances: FeeBalance[]
}
export type FeeBalance = {
chainId: ChainId
tokenBalances: TokenBalance[]
}
export type TokenBalance = {
token: Token
amount: string
amountUsd: string
}
export interface IntegratorWithdrawalRequest {
integratorId: string
chainId: ChainId
tokens?: string[]
}
export interface IntegratorWithdrawalTransactionResponse {
transactionRequest: TransactionRequest
}
const _LIFuelState = ['PENDING', 'DONE', 'NOT_FOUND'] as const
type LIFuelState = (typeof _LIFuelState)[number]
// Response to the status API for trusted gas
export type LIFuelStatusResponse = {
status: LIFuelState
sending?: ExtendedTransactionInfo
receiving?: PendingReceivingInfo | ExtendedTransactionInfo
}
export type GasRecommendationRequest = {
chainId: ChainId
fromChain?: ChainId
fromToken?: string
}
export type RefetchSourceLIFuelRequest = {
txHash: string
chainId: ChainId
}
export type LIFuelStatusRequest = {
txHash: string
}
export type RefetchLIFuelRequest = {
txHash: string
chainId: ChainId
}
export type GasRecommendationResponse = {
// whether we can support that
available: boolean
// reason why the gas feature is not available (e.g. missing liquidity)
message?: string
recommended?: TokenBalance
limit?: TokenBalance // Maximum of gas the user can transfer
serviceFee?: TokenBalance // OpenOcean fee for providing the service
// information about what the user has to pay to get the recommended gas amount
fromToken?: Token
fromAmount?: string
}
export interface TransactionAnalyticsResponse {
transfers: StatusResponse[]
}
export type TransactionAnalyticsStatus =
| Exclude<StatusMessage, 'NOT_FOUND' | 'INVALID'>
| 'ALL'
export interface TransactionAnalyticsRequest {
wallet: string
fromTimestamp?: number
toTimestamp?: number
status?: TransactionAnalyticsStatus
}
export interface CreateIntegratorRequest {
name: string
integratorId: string
fee?: number
feeType?: IntegratorFeeType
defaultWallet?: string
chainWallets?: ChainWalletConfiguration
}
export interface UpdateIntegratorRequest {
name?: string
fee?: number
feeType?: IntegratorFeeType
defaultWallet?: string
chainWallets?: ChainWalletConfiguration
}
export type IntegratorResult = {
name: string
integratorId: string
fee: number
feeType: IntegratorFeeType
defaultWallet?: string
chainWallets?: ChainWalletConfiguration
}
export type ChainWalletConfiguration = {
[key in ChainId]?: string
}
export enum IntegratorFeeType {
FIXED = 'FIXED',
SHARED = 'SHARED',
}
export type TransferSummary = {
id: {
toAddress: string
sendingChainId?: number
}
totalReceivedAmount: number
}
export interface TransferSummariesResponse
extends PaginatedResponse<TransferSummary> {}
export interface GetStepRequest {
stepId: string
}
export interface GetTokenApprovalRequest {
tokenContractAddress: string
chainId: string
userWalletAddress: string
requiredAmount: string
}
export interface GetTokenApprovalResponse {
isApproved: boolean
approvedAmount: string
approvalTransaction: {
to?: string
from?: string
nonce?: string
gasLimit?: string
gasPrice?: string
data?: string
value?: string
chainId?: number
type?: number
accessList?: { address: string; storageKeys: string[] }[]
maxPriorityFeePerGas?: string
maxFeePerGas?: string
customData?: string
ccipReadEnabled?: boolean
}
}
export type PermitBase<T extends bigint | string> = {
spender: Address
nonce: T
deadline: T
}
export type PermitMessage<T extends bigint | string> = PermitBase<T> & {
owner: Address
value: T
}
export type TokenPermissions<T extends bigint | string> = {
token: Address
amount: T
}
export type PermitWitnessTransferFromMessage<T extends bigint | string> =
PermitBase<T> & {
permitted: TokenPermissions<T>
}
export type TypedDataPrimaryType =
| 'Permit'
| 'PermitTransferFrom'
| 'PermitBatchTransferFrom'
| 'PermitWitnessTransferFrom'
| 'PermitBatchWitnessTransferFrom'
| 'Order'
/**
* EIP-712 Typed Data
* @link https://eips.ethereum.org/EIPS/eip-712
*/
export type TypedData = {
primaryType: TypedDataPrimaryType
domain: TypedDataDomain
types: Record<string, readonly TypedDataParameter[]>
message: Record<string, any>
}
/**
* EIP-712 Typed Data with signature
*/
export interface SignedTypedData extends TypedData {
signature: Hex
}
export type RelayerErrorResponse = {
status: 'error'
data: {
code: number
message: string
}
}
export type RelayerResponse<T> =
| { status: 'ok'; data: T }
| RelayerErrorResponse
export type RelayerQuoteResponse = RelayerResponse<OpenOceanStep>
export type RelayRequest = OpenOceanStep
export type RelayResponseData = {
taskId: string
}
export type RelayResponse = RelayerResponse<RelayResponseData>
export type RelayStatusRequest = {
taskId: Hash
bridge?: string
fromChain?: number
toChain?: number
}
export type RelayStatusResponseData = {
status: 'DONE' | 'PENDING' | 'FAILED'
message?: string
metadata: { chainId: number; txHash?: Hash }
transactionStatus?: StatusResponse
}
export type RelayStatusResponse = RelayerResponse<RelayStatusResponseData>