import {z} from 'zod' export type Asset = {denom: string, chain_id: string, origin_denom: string, origin_chain_id: string, trace: string, is_cw20: boolean, is_evm: boolean, is_svm: boolean, symbol?: (string | null) | undefined, name?: (string | null) | undefined, logo_uri?: (string | null) | undefined, decimals?: (number | null) | undefined, token_contract?: (string | null) | undefined, description?: (string | null) | undefined, coingecko_id?: (string | null) | undefined, recommended_symbol?: (string | null) | undefined}; export type BridgeType = 'IBC' | 'AXELAR' | 'CCTP' | 'HYPERLANE' | 'OPINIT' | 'GO_FAST' | 'STARGATE' | 'LAYER_ZERO' | 'EUREKA'; export type Transfer = {port?: string | undefined, channel?: string | undefined, from_chain_id?: string | undefined, to_chain_id?: string | undefined, pfm_enabled?: boolean | undefined, supports_memo?: boolean | undefined, denom_in?: string | undefined, denom_out?: string | undefined, fee_amount?: (string | null) | undefined, usd_fee_amount?: (string | null) | undefined, fee_asset?: Asset | undefined, bridge_id?: BridgeType | undefined, smart_relay?: boolean | undefined, to_chain_entry_contract_address?: (string | null) | undefined, to_chain_callback_contract_address?: (string | null) | undefined, dest_denom?: string | undefined}; export type SwapVenue = {chain_id?: string | undefined, name?: string | undefined, logo_uri?: (string | null) | undefined}; export type SwapOperation = {denom_in?: string | undefined, denom_out?: string | undefined, pool?: string | undefined, interface?: (string | null) | undefined}; export type SwapExactCoinIn = {swap_venue?: SwapVenue | undefined, swap_operations?: Array | undefined, swap_amount_in?: (string | null) | undefined, price_impact_percent?: (string | null) | undefined, estimated_amount_out?: (string | null) | undefined}; export type SwapExactCoinOut = {swap_venue?: SwapVenue | undefined, swap_operations?: Array | undefined, swap_amount_out?: string | undefined, price_impact_percent?: (string | null) | undefined}; export type SwapRoute = {swap_amount_in?: string | undefined, denom_in?: string | undefined, swap_operations?: Array | undefined}; export type SmartSwapExactCoinIn = {swap_venue?: SwapVenue | undefined, swap_routes?: Array | undefined, estimated_amount_out?: (string | null) | undefined}; export type Swap = {swap_in?: SwapExactCoinIn | undefined, estimated_affiliate_fee?: string | undefined, from_chain_id?: string | undefined, chain_id?: string | undefined, denom_in?: string | undefined, denom_out?: string | undefined, swap_venues?: Array | undefined} | {swap_out?: SwapExactCoinOut | undefined, estimated_affiliate_fee?: string | undefined, from_chain_id?: string | undefined, chain_id?: string | undefined, denom_in?: string | undefined, denom_out?: string | undefined, swap_venues?: Array | undefined} | {smart_swap_in?: SmartSwapExactCoinIn | undefined, estimated_affiliate_fee?: string | undefined, from_chain_id?: string | undefined, chain_id?: string | undefined, denom_in?: string | undefined, denom_out?: string | undefined, swap_venues?: Array | undefined}; export type AxelarTransfer = {from_chain_id?: string | undefined, to_chain_id?: string | undefined, asset?: string | undefined, should_unwrap?: boolean | undefined, denom_in?: string | undefined, denom_out?: string | undefined, fee_amount?: string | undefined, usd_fee_amount?: string | undefined, fee_asset?: Asset | undefined, is_testnet?: boolean | undefined, ibc_transfer_to_axelar?: Transfer | undefined, bridge_id?: BridgeType | undefined, smart_relay?: boolean | undefined, from_chain?: string | undefined, to_chain?: string | undefined}; export type BankSend = {chain_id?: string | undefined, denom?: string | undefined}; export type SmartRelayFeeQuote = {fee_amount?: string | undefined, relayer_address?: string | undefined, expiration?: string | undefined, fee_denom?: string | undefined, fee_payment_address?: (string | null) | undefined}; export type CCTPTransfer = {from_chain_id?: string | undefined, to_chain_id?: string | undefined, burn_token?: string | undefined, denom_in?: string | undefined, denom_out?: string | undefined, bridge_id?: BridgeType | undefined, smart_relay?: boolean | undefined, smart_relay_fee_quote?: (SmartRelayFeeQuote | null) | undefined}; export type HyperlaneTransfer = {from_chain_id?: string | undefined, to_chain_id?: string | undefined, denom_in?: string | undefined, denom_out?: string | undefined, hyperlane_contract_address?: string | undefined, fee_amount?: string | undefined, usd_fee_amount?: string | undefined, fee_asset?: Asset | undefined, bridge_id?: BridgeType | undefined, smart_relay?: boolean | undefined}; export type EvmSwap = {input_token?: string | undefined, amount_in?: string | undefined, swap_calldata?: string | undefined, amount_out?: string | undefined, from_chain_id?: string | undefined, denom_in?: string | undefined, denom_out?: string | undefined, swap_venues?: Array | undefined}; export type OPInitTransfer = {from_chain_id?: string | undefined, to_chain_id?: string | undefined, denom_in?: string | undefined, denom_out?: string | undefined, op_init_bridge_id: unknown, bridge_id?: BridgeType | undefined, smart_relay?: boolean | undefined}; export type GoFastFee = {fee_asset?: Asset | undefined, bps_fee?: string | undefined, bps_fee_amount?: string | undefined, bps_fee_usd?: string | undefined, source_chain_fee_amount?: string | undefined, source_chain_fee_usd?: string | undefined, destination_chain_fee_amount?: string | undefined, destination_chain_fee_usd?: string | undefined}; export type GoFastTransfer = {from_chain_id?: string | undefined, to_chain_id?: string | undefined, fee?: GoFastFee | undefined, bridge_id?: BridgeType | undefined, denom_in?: string | undefined, denom_out?: string | undefined, source_domain?: string | undefined, destination_domain?: string | undefined}; export type StargateTransfer = {from_chain_id?: string | undefined, to_chain_id?: string | undefined, denom_in?: string | undefined, denom_out?: string | undefined, pool_address?: string | undefined, destination_endpoint_id?: number | undefined, oft_fee_asset?: Asset | undefined, oft_fee_amount?: string | undefined, oft_fee_amount_usd?: string | undefined, messaging_fee_asset?: Asset | undefined, messaging_fee_amount?: string | undefined, messaging_fee_amount_usd?: string | undefined, bridge_id?: BridgeType | undefined}; export type LayerZeroTransfer = {from_chain_id: string, to_chain_id: string, denom_in: string, denom_out: string, source_oft_contract_address: string, destination_endpoint_id: number, messaging_fee_asset: Asset, messaging_fee_amount: string, messaging_fee_amount_usd: string, bridge_id: BridgeType}; export type EurekaTransfer = {destination_port?: string | undefined, source_client?: string | undefined, from_chain_id?: string | undefined, to_chain_id?: string | undefined, pfm_enabled?: boolean | undefined, supports_memo?: boolean | undefined, denom_in?: string | undefined, denom_out?: string | undefined, entry_contract_address?: string | undefined, callback_adapter_contract_address?: (string | null) | undefined, bridge_id?: BridgeType | undefined, smart_relay?: boolean | undefined, smart_relay_fee_quote?: (SmartRelayFeeQuote | null) | undefined, to_chain_callback_contract_address?: (string | null) | undefined, to_chain_entry_contract_address?: (string | null) | undefined}; export type Operation = {transfer?: Transfer | undefined, tx_index: number, amount_in: string, amount_out: string} | {swap?: Swap | undefined, tx_index: number, amount_in: string, amount_out: string} | {axelar_transfer?: AxelarTransfer | undefined, tx_index: number, amount_in: string, amount_out: string} | {bank_send?: BankSend | undefined, tx_index: number, amount_in: string, amount_out: string} | {cctp_transfer?: CCTPTransfer | undefined, tx_index: number, amount_in: string, amount_out: string} | {hyperlane_transfer?: HyperlaneTransfer | undefined, tx_index: number, amount_in: string, amount_out: string} | {evm_swap?: EvmSwap | undefined, tx_index: number, amount_in: string, amount_out: string} | {op_init_transfer?: OPInitTransfer | undefined, tx_index: number, amount_in: string, amount_out: string} | {go_fast_transfer?: GoFastTransfer | undefined, tx_index: number, amount_in: string, amount_out: string} | {stargate_transfer?: StargateTransfer | undefined, tx_index: number, amount_in: string, amount_out: string} | {layer_zero_transfer?: LayerZeroTransfer | undefined, tx_index: number, amount_in: string, amount_out: string} | {eureka_transfer?: EurekaTransfer | undefined, tx_index: number, amount_in: string, amount_out: string}; export type Affiliate = {address?: string | undefined, basis_points_fee?: string | undefined}; export type ChainAffiliates = {affiliates?: Array | undefined}; export type CosmWasmContractMsg = {contract_address?: string | undefined, msg?: string | undefined}; export type CosmWasmContractMsgWrapper = {wasm_msg?: CosmWasmContractMsg | undefined}; export type AutopilotAction = 'LIQUID_STAKE' | 'CLAIM'; export type AutopilotMsg = {action?: AutopilotAction | undefined, receiver?: string | undefined}; export type AutopilotMsgWrapper = {autpilot_msg?: AutopilotMsg | undefined}; export type PostHandler = CosmWasmContractMsgWrapper | AutopilotMsgWrapper; export type MsgsRequest = {source_asset_denom?: string | undefined, source_asset_chain_id?: string | undefined, dest_asset_denom?: string | undefined, dest_asset_chain_id?: string | undefined, amount_in?: string | undefined, amount_out?: string | undefined, address_list?: Array | undefined, operations?: Array | undefined, estimated_amount_out?: string | undefined, slippage_tolerance_percent?: string | undefined, chain_ids_to_affiliates?: {[key: string]: ChainAffiliates} | undefined, post_route_handler?: PostHandler | undefined, timeout_seconds?: string | undefined, enable_gas_warnings?: boolean | undefined, fee_payer_address?: string | undefined}; export type CreateApiV2FungibleMsgsArgs = {body: MsgsRequest}; export type CreateApiV2FungibleMsgsOptions = {baseUrl?: string | undefined, fetch?: typeof fetch | undefined}; export const multiChainMsg = z.object({chain_id: z.string().optional(), msg: z.string().optional(), msg_type_url: z.string().optional(), path: z.array(z.string()).optional()}); export const multiChainMsgWrapper = z.object({multi_chain_msg: multiChainMsg.optional()}); export const erc20Approval = z.object({amount: z.string(), spender: z.string(), token_contract: z.string()}); export const evmTx = z.object({chain_id: z.string(), data: z.string().optional(), required_erc20_approvals: z.array(erc20Approval).optional(), signer_address: z.string().optional(), to: z.string().optional(), value: z.string().optional()}); export const evmTxWrapper = z.object({evm_tx: evmTx}); export const svmTx = z.object({chain_id: z.string(), signer_address: z.string().optional(), tx: z.string().optional()}); export const svmTxWrapper = z.object({svm_tx: svmTx}); export const msg = z.union([multiChainMsgWrapper, evmTxWrapper, svmTxWrapper]); export const cosmosMsg = z.object({msg: z.string().optional(), msg_type_url: z.string().optional()}); export const cosmosTx = z.object({chain_id: z.string(), path: z.array(z.string()).optional(), signer_address: z.string().optional(), msgs: z.array(cosmosMsg).optional()}); export const tx = z.union([z.object({cosmos_tx: cosmosTx, operations_indices: z.array(z.number().int()).optional()}), z.object({evm_tx: evmTx, operations_indices: z.array(z.number().int()).optional()}), z.object({svm_tx: svmTx, operations_indices: z.array(z.number().int()).optional()})]); export const feeType = z.literal("SMART_RELAY"); export const bridgeType = z.enum(["IBC", "AXELAR", "CCTP", "HYPERLANE", "OPINIT", "GO_FAST", "STARGATE", "LAYER_ZERO", "EUREKA"]); export const asset = z.object({denom: z.string(), chain_id: z.string(), origin_denom: z.string(), origin_chain_id: z.string(), trace: z.string(), is_cw20: z.boolean(), is_evm: z.boolean(), is_svm: z.boolean(), symbol: z.string().nullable().optional(), name: z.string().nullable().optional(), logo_uri: z.string().nullable().optional(), decimals: z.number().nullable().optional(), token_contract: z.string().nullable().optional(), description: z.string().nullable().optional(), coingecko_id: z.string().nullable().optional(), recommended_symbol: z.string().nullable().optional()}); export const feeBehavior = z.enum(["FEE_BEHAVIOR_DEDUCTED", "FEE_BEHAVIOR_ADDITIONAL"]); export const fee = z.object({fee_type: feeType.optional(), bridge_id: bridgeType.optional(), amount: z.string().optional(), usd_amount: z.string().optional(), origin_asset: asset.optional(), chain_id: z.string().optional(), tx_index: z.number().int().optional(), operation_index: z.number().int().nullable().optional(), fee_behavior: feeBehavior.optional()}); export const createApiV2FungibleMsgsResponse = z.object({msgs: z.array(msg).optional(), txs: z.array(tx).optional(), min_amount_out: z.string().optional(), estimated_fees: z.array(fee).optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * This supports cross-chain actions among EVM chains, Cosmos chains, and between them. Returns minimal number of messages required to execute a multi-chain swap or transfer. Input consists of the output of route with additional information required for message construction (e.g. destination addresses for each chain) * * POST /v2/fungible/msgs */ export const createApiV2FungibleMsgs = async (args: CreateApiV2FungibleMsgsArgs, options?: CreateApiV2FungibleMsgsOptions) => { const {baseUrl = "https://api.skip.build", fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") const url = `${baseUrl.replace(/\/+$/, '')}/v2/fungible/msgs${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(createApiV2FungibleMsgsResponse, await res.json()) };