@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.
175 lines • 7.58 kB
JavaScript
export class OpenOceanService {
// Get OpenOcean supported chain name
static getChainName(chainId) {
return this.CHAIN_ID_MAP[chainId] || chainId.toString();
}
// Get API URL based on chain ID
static getApiUrl(chainId) {
// If chainId exists in CHAIN_ID_MAP, use V1 API
const chainName = this.getChainName(chainId);
return Object.keys(this.CHAIN_ID_MAP).includes(chainId.toString())
? `${this.API_V4_URL}/${chainName}`
: `${this.API_V4_URL}/${chainId}`;
}
static getSolanaAddress(chain, tokenAddress) {
if (chain === '1151111081099710' && tokenAddress === 'So11111111111111111111111111111111111111112') {
return '11111111111111111111111111111111';
}
else if (chain === '1151111081099710' && tokenAddress === '11111111111111111111111111111111') {
return 'So11111111111111111111111111111111111111112';
}
return tokenAddress;
}
static async getQuote(params) {
const apiUrl = this.getApiUrl(params.chain);
const slippage = (Number(params.slippage || 0.01)).toString();
const queryParams = new URLSearchParams({
quoteType: 'quote',
inTokenSymbol: params.inTokenSymbol,
inTokenAddress: params.inTokenAddress,
outTokenSymbol: params.outTokenSymbol,
outTokenAddress: params.outTokenAddress,
amountDecimals: params.amount,
slippage,
gasPriceDecimals: params.gasPrice || '',
disabledDexIds: params.disabledDexIds || '',
enabledDexIds: params.enabledDexIds || '',
referrer: params.referrer || '0x3487ef9f9b36547e43268b8f0e2349a226c70b53',
});
const response = await fetch(`${apiUrl}/quote?${queryParams.toString()}`);
return response.json();
}
static async getSwapQuote(params) {
const apiUrl = this.getApiUrl(params.chain);
const slippage = (Number(params.slippage || 0.01)).toString();
const referrer = {
referrer: params.referrer || '0x3487ef9f9b36547e43268b8f0e2349a226c70b53',
};
if (params.referrerFee) {
referrer.referrerFee = Number(params.referrerFee);
// referrer.referrerFeeShare = params.referrerFeeShare || '1500';
}
const queryParams = new URLSearchParams({
quoteType: 'swap',
inTokenSymbol: params.inTokenSymbol,
inTokenAddress: this.getSolanaAddress(params.chain, params.inTokenAddress),
outTokenSymbol: params.outTokenSymbol,
outTokenAddress: this.getSolanaAddress(params.chain, params.outTokenAddress),
amountDecimals: params.amount,
account: params.account,
slippage,
gasPriceDecimals: params.gasPrice || '',
disabledDexIds: params.disabledDexIds || '',
enabledDexIds: params.enabledDexIds || '',
...referrer,
});
// const isV1Api = Object.keys(this.CHAIN_ID_MAP).includes(params.chain.toString())
// const swapEndpoint = isV1Api ? 'swap-quote' : 'swap'
const response = await fetch(`${apiUrl}/swap?${queryParams.toString()}`);
return response.json();
}
static async getTokenList(chain) {
const chainName = this.getChainName(chain);
const response = await fetch(`${this.API_V4_URL}/${chainName}/tokenList`);
const data = await response.json();
if (data.code !== 200) {
throw new Error('Failed to fetch token list');
}
return data.data.map((token) => {
let address = token.address;
// Convert Solana native token address
if (chain === '1151111081099710' && address === 'So11111111111111111111111111111111111111112') {
address = '11111111111111111111111111111111';
}
// Convert Base chain native token address
if (address === '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE') {
address = '0x0000000000000000000000000000000000000000';
}
return {
address,
symbol: token.symbol,
decimals: token.decimals,
name: token.name,
logoURI: token.icon,
priceUSD: token.usd,
chainId: Number(chain),
amount: 0n,
featured: false,
popular: false
};
});
}
static async getDexList(chain) {
const apiUrl = this.getApiUrl(chain);
const response = await fetch(`${apiUrl}/dexList`);
return response.json();
}
static async getGasPrice(chain) {
if (!chain || chain === '1151111081099710') {
return {
data: {
gasPrice: '1000000000000000000',
},
};
}
// const apiUrl = this.getApiUrl(chain)
const response = await fetch(`${this.API_V4_URL}/${chain}/gasPrice`);
const { data } = await response.json();
return data;
}
static async getTokenInfo(chain, tokenAddress) {
const chainName = this.getChainName(chain);
// Check if the address is valid
if (!tokenAddress || (!/^0x[a-fA-F0-9]{40}$/.test(tokenAddress) && !/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(tokenAddress))) {
throw new Error('Invalid token address');
}
const response = await fetch(`${this.API_V4_URL}/${chainName}/getTokenInfo?tokenAddress=${tokenAddress}`);
const data = await response.json();
if (!data || !data.address || !data.symbol || !data.decimals) {
throw new Error('Failed to fetch token info');
}
return {
address: data.address,
symbol: data.symbol,
decimals: data.decimals,
name: data.name,
logoURI: data.icon,
priceUSD: data.usd,
chainId: Number(chain),
amount: 0n,
featured: false,
popular: false
};
}
/**
* Get prices for specified tokens
* @param chain chain name, e.g. 'arbitrum'
* @param tokenAddresses array of token addresses
* @returns Promise<Record<string, string>> returns an object where key is token address and value is price
*/
static async getTokensPrice(chain, tokenAddresses) {
const chainName = this.getChainName(chain);
const tokenAddressesStr = tokenAddresses.join(',');
const response = await fetch(`${this.API_V3_URL}/${chainName}/designated_tokenList?tokens=${tokenAddressesStr}`);
const data = await response.json();
if (data.code !== 200) {
throw new Error('Failed to fetch token prices');
}
const prices = data.data.reduce((acc, token) => {
if (token.address && token.usd) {
acc[token.address.toLowerCase()] = token.usd;
}
return acc;
}, {});
return prices;
}
}
// private static readonly API_V1_URL = 'https://ethapi.openocean.finance/v1'
//private static readonly API_V2_URL = 'https://ethapi.openocean.finance/v2'
OpenOceanService.API_V3_URL = 'https://open-api.openocean.finance/v3';
OpenOceanService.API_V4_URL = 'https://open-api.openocean.finance/v4';
// Chain ID to OpenOcean chain name mapping
OpenOceanService.CHAIN_ID_MAP = {
1151111081099710: 'solana', // Solana mainnet
};
//# sourceMappingURL=OpenOceanService.js.map