UNPKG

@openocean.finance/widget

Version:

Openocean Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.

196 lines (170 loc) 5.12 kB
import type { useWalletSelector } from '@near-wallet-selector/react-hook' import { ChainId } from '@openocean.finance/widget-sdk' // import type { AdaptedWallet } from '@relayprotocol/relay-sdk' import type { WalletAdapterProps } from '@solana/wallet-adapter-base' import type { Connection } from '@solana/web3.js' import type { WalletClient } from 'viem' import type { Currency as EvmCurrency, NearToken, SolanaToken, } from '../constants/index.js' import type { Quote } from '../registry.js' export enum NonEvmChain { Near = 20000000000006, Bitcoin = 20000000000001, Solana = 1151111081099710, } export enum NewEvmChain { Plasma = 9745, Monad = 143, } export const BitcoinToken = { name: 'Bitcoin', symbol: 'BTC', decimals: 8, logo: 'https://storage.googleapis.com/ks-setting-1d682dca/285205e7-a16d-421c-a794-67439cd6b54f1751515894455.png', } export type Chain = ChainId | NonEvmChain | NewEvmChain export type Currency = | EvmCurrency | NearToken | typeof BitcoinToken | SolanaToken export const NonEvmChainInfo: { [key in NonEvmChain]: { name: string; icon: string } } = { [NonEvmChain.Near]: { name: 'NEAR', icon: 'https://storage.googleapis.com/ks-setting-1d682dca/000c677f-2ebc-44cc-8d76-e4c6d07627631744962669170.png', }, [NonEvmChain.Bitcoin]: { name: 'Bitcoin', icon: 'https://storage.googleapis.com/ks-setting-1d682dca/285205e7-a16d-421c-a794-67439cd6b54f1751515894455.png', }, [NonEvmChain.Solana]: { name: 'Solana', icon: 'https://solana.com/favicon.png', }, } export const NewEvmChainInfo: { [key in NewEvmChain]: { name: string; icon: string } } = { [NewEvmChain.Plasma]: { name: 'Plasma', icon: 'https://storage.googleapis.com/ks-setting-1d682dca/285205e7-a16d-421c-a794-67439cd6b54f1751515894455.png', }, [NewEvmChain.Monad]: { name: 'Monad', icon: 'https://storage.googleapis.com/ks-setting-1d682dca/285205e7-a16d-421c-a794-67439cd6b54f1751515894455.png', }, } export const NOT_SUPPORTED_CHAINS_PRICE_SERVICE = [ ChainId.FTM, ChainId.SCL, ChainId.BLS, // ChainId.ZKSYNC, // ChainId.HYPEREVM, NonEvmChain.Solana, NonEvmChain.Bitcoin, NonEvmChain.Near, NewEvmChain.Plasma, NewEvmChain.Monad, ] export interface QuoteParams { feeBps: number fromChain: Chain toChain: Chain fromToken: Currency toToken: Currency amount: string slippage: number walletClient?: WalletClient tokenInUsd: number tokenOutUsd: number sender: string recipient: string publicKey?: string isNative: boolean } export interface EvmQuoteParams extends QuoteParams { fromToken: EvmCurrency toToken: EvmCurrency } export interface NearQuoteParams extends QuoteParams { // nearTokens: NearToken[] } export interface NormalizedQuote { quoteParams: QuoteParams outputAmount: bigint formattedOutputAmount: string inputUsd: number outputUsd: number rate: number timeEstimate: number // in seconds priceImpact: number // percent gasFeeUsd: number contractAddress: string rawQuote: any protocolFee: string | number protocolFeeString?: string platformFeePercent: number } export interface NormalizedTxResponse { id: string // specific id for each provider sourceTxHash: string sender: string adapter: string sourceChain: Chain targetChain: Chain inputAmount: string outputAmount: string sourceToken: Currency targetToken: Currency targetTxHash?: string timestamp: number status?: 'Processing' | 'Success' | 'Failed' | 'Refunded' } export interface SwapStatus { txHash: string status: 'Processing' | 'Success' | 'Failed' | 'Refunded' } // Define a common interface for all swap providers export interface SwapProvider { getName(): string getIcon(): string getSupportedChains(): Chain[] getSupportedTokens(sourceChain: Chain, destChain: Chain): Currency[] getQuote(params: QuoteParams): Promise<NormalizedQuote> executeSwap( quote: Quote, walletClient: WalletClient, nearWallet?: ReturnType<typeof useWalletSelector>, sendBtcFn?: (params: { recipient: string amount: string | number }) => Promise<string>, sendSolanaTransaction?: WalletAdapterProps['sendTransaction'], connection?: Connection ): Promise<NormalizedTxResponse> getTransactionStatus(p: NormalizedTxResponse): Promise<SwapStatus> } export abstract class BaseSwapAdapter implements SwapProvider { abstract getName(): string abstract getIcon(): string abstract getSupportedChains(): Chain[] abstract getSupportedTokens(sourceChain: Chain, destChain: Chain): Currency[] abstract getQuote(params: QuoteParams): Promise<NormalizedQuote> abstract executeSwap( params: Quote, walletClient: WalletClient, nearWallet?: ReturnType<typeof useWalletSelector> ): Promise<NormalizedTxResponse> abstract getTransactionStatus(p: NormalizedTxResponse): Promise<SwapStatus> protected handleError(error: any): never { console.error(`[${this.getName()}] Error:`, error) throw new Error( `${this.getName()} provider error: ${error.message || 'Unknown error'}` ) } }