From ea31ff29d7567c3916dd492a584e4f4da3b3f676 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 12 Jul 2024 12:30:57 +0300 Subject: [PATCH 01/18] add router cross chain provider --- .../models/cross-chain-trade-type.ts | 3 +- .../router-cross-chain-blockchains-id.ts | 30 ++++++++++++++++++ .../router-cross-chain-supported-chains.ts | 31 +++++++++++++++++++ .../router-cross-chain-provider.ts | 29 +++++++++++++++++ .../router-cross-chain-trade.ts | 6 ++++ 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-blockchains-id.ts create mode 100644 src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts create mode 100644 src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts create mode 100644 src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts diff --git a/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts b/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts index 6a3ad75f3a6..73e886dea25 100644 --- a/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts +++ b/src/features/cross-chain/calculation-manager/models/cross-chain-trade-type.ts @@ -19,7 +19,8 @@ export const CROSS_CHAIN_TRADE_TYPE = { LAYERZERO: 'layerzero', ARCHON_BRIDGE: 'archon_bridge', MESON: 'meson', - EDDY_BRIDGE: 'eddy_bridge' + EDDY_BRIDGE: 'eddy_bridge', + ROUTER: 'router' } as const; export type CrossChainTradeType = diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-blockchains-id.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-blockchains-id.ts new file mode 100644 index 00000000000..de30ae50cd6 --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-blockchains-id.ts @@ -0,0 +1,30 @@ +import { BLOCKCHAIN_NAME } from "src/core/blockchain/models/blockchain-name"; +import { RouterCrossChainSupportedBlockchains } from "./router-cross-chain-supported-chains"; + +export const routerChainId: Record = { + [BLOCKCHAIN_NAME.ETHEREUM]: 1, + [BLOCKCHAIN_NAME.OPTIMISM]: 10, + [BLOCKCHAIN_NAME.ROOTSTOCK]: 30, + [BLOCKCHAIN_NAME.BINANCE_SMART_CHAIN]: 56, + [BLOCKCHAIN_NAME.POLYGON]: 137, + [BLOCKCHAIN_NAME.MANTA_PACIFIC]: 169, + [BLOCKCHAIN_NAME.XLAYER]: 196, + [BLOCKCHAIN_NAME.FANTOM]: 250, + [BLOCKCHAIN_NAME.BOBA]: 288, + [BLOCKCHAIN_NAME.ZK_SYNC]: 324, + [BLOCKCHAIN_NAME.METIS]: 1088, + // [BLOCKCHAIN_NAME.POLYGON_ZKEVM], + // [BLOCKCHAIN_NAME.DOGECOIN], + // [BLOCKCHAIN_NAME.MANTLE], + // [BLOCKCHAIN_NAME.BASE], + // [BLOCKCHAIN_NAME.OASIS], + // [BLOCKCHAIN_NAME.MODE], + // [BLOCKCHAIN_NAME.ARBITRUM], + // [BLOCKCHAIN_NAME.AVALANCHE], + // [BLOCKCHAIN_NAME.LINEA], + // [BLOCKCHAIN_NAME.BLAST], + // [BLOCKCHAIN_NAME.TAIKO], + // [BLOCKCHAIN_NAME.SCROLL], + // [BLOCKCHAIN_NAME.TRON], + // [BLOCKCHAIN_NAME.AURORA], +} \ No newline at end of file diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts new file mode 100644 index 00000000000..85083662c86 --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts @@ -0,0 +1,31 @@ +import { BLOCKCHAIN_NAME } from "src/core/blockchain/models/blockchain-name"; + +export const routerCrossChainSupportedChains = [ + BLOCKCHAIN_NAME.ETHEREUM, + BLOCKCHAIN_NAME.OPTIMISM, + BLOCKCHAIN_NAME.ROOTSTOCK, + BLOCKCHAIN_NAME.BINANCE_SMART_CHAIN, + BLOCKCHAIN_NAME.POLYGON, + BLOCKCHAIN_NAME.MANTA_PACIFIC, + BLOCKCHAIN_NAME.XLAYER, + BLOCKCHAIN_NAME.FANTOM, + BLOCKCHAIN_NAME.BOBA, + BLOCKCHAIN_NAME.ZK_SYNC, + BLOCKCHAIN_NAME.METIS, + BLOCKCHAIN_NAME.POLYGON_ZKEVM, + BLOCKCHAIN_NAME.DOGECOIN, + BLOCKCHAIN_NAME.MANTLE, + BLOCKCHAIN_NAME.BASE, + BLOCKCHAIN_NAME.OASIS, + BLOCKCHAIN_NAME.MODE, + BLOCKCHAIN_NAME.ARBITRUM, + BLOCKCHAIN_NAME.AVALANCHE, + BLOCKCHAIN_NAME.LINEA, + BLOCKCHAIN_NAME.BLAST, + BLOCKCHAIN_NAME.TAIKO, + BLOCKCHAIN_NAME.SCROLL, + BLOCKCHAIN_NAME.TRON, + BLOCKCHAIN_NAME.AURORA, +] + +export type RouterCrossChainSupportedBlockchains = (typeof routerCrossChainSupportedChains)[number]; \ No newline at end of file diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts new file mode 100644 index 00000000000..5576b18ee22 --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts @@ -0,0 +1,29 @@ +import { PriceTokenAmount, PriceToken } from "src/common/tokens"; +import { BlockchainName } from "src/core/blockchain/models/blockchain-name"; +import { EvmEncodeConfig } from "src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/models/evm-encode-config"; +import { TronTransactionConfig } from "src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config"; +import { CrossChainOptions, RequiredCrossChainOptions } from "../../models/cross-chain-options"; +import { CROSS_CHAIN_TRADE_TYPE } from "../../models/cross-chain-trade-type"; +import { CrossChainProvider } from "../common/cross-chain-provider"; +import { CalculationResult } from "../common/models/calculation-result"; +import { routerCrossChainSupportedChains } from "./constants/router-cross-chain-supported-chains"; + +export class RouterCrossChainProvider extends CrossChainProvider { + public readonly type = CROSS_CHAIN_TRADE_TYPE.ROUTER; + + public isSupportedBlockchain( + fromBlockchain: BlockchainName + ): boolean { + return routerCrossChainSupportedChains.some( + chain => chain === fromBlockchain + ) + } + + public async calculate( + from: PriceTokenAmount, + toToken: PriceToken, + options: RequiredCrossChainOptions + ): Promise { + + } +} \ No newline at end of file diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts new file mode 100644 index 00000000000..72003153c74 --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -0,0 +1,6 @@ +import { EvmCrossChainTrade } from "../common/emv-cross-chain-trade/evm-cross-chain-trade"; + + +export class RouterCrossChainTrade extends EvmCrossChainTrade{ + +} \ No newline at end of file From 3e16c549ed3f2e0ecfdfd29acf5907dac0a31dd9 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 17 Jul 2024 12:42:31 +0300 Subject: [PATCH 02/18] add router api service --- .../models/router-quote-response-config.ts | 43 ++++++++ .../router/models/router-quote-send-params.ts | 9 ++ .../models/router-send-transaction-params.ts | 15 +++ .../router/services/router-api-service.ts | 28 +++++ .../router-cross-chain-provider.ts | 101 +++++++++++++++++- .../router-cross-chain-trade.ts | 78 +++++++++++++- 6 files changed, 271 insertions(+), 3 deletions(-) create mode 100644 src/features/common/providers/router/models/router-quote-response-config.ts create mode 100644 src/features/common/providers/router/models/router-quote-send-params.ts create mode 100644 src/features/common/providers/router/models/router-send-transaction-params.ts create mode 100644 src/features/common/providers/router/services/router-api-service.ts diff --git a/src/features/common/providers/router/models/router-quote-response-config.ts b/src/features/common/providers/router/models/router-quote-response-config.ts new file mode 100644 index 00000000000..d8568990350 --- /dev/null +++ b/src/features/common/providers/router/models/router-quote-response-config.ts @@ -0,0 +1,43 @@ + + +type RouterFlowType = 'trustless' | 'mint-burn' | 'circle' | 'gateway' | 'none'; + +interface RouterAsset { + decimals: number; + symbol: string; + name: string; + chainId: string; + address: string; + resourceID: string; + isMintable: boolean; + isWrappedAsset: boolean; +} + +interface RouterSwapTokenInfo { + chainId: string; + asset: RouterAsset; + stableReserveAsset: RouterAsset; + tokenAmount: string; + stableReserveAmount: string; + path: unknown[]; + flags: unknown[]; + priceImpact: string; + tokenPath: string; + dataTx: unknown[] +} + +export interface RouterQuoteResponseConfig { + flowType: RouterFlowType; + isTransfer: boolean; + isWrappedToken: boolean; + allowanceTo: string; + fromTokenAddress: string; + toTokenAddress: string; + source: RouterSwapTokenInfo & { + bridgeFeeAmount: string + }; + destination: RouterSwapTokenInfo; + partnerId: number; + estimatedTime: number; + slippageTolerance: number; +} diff --git a/src/features/common/providers/router/models/router-quote-send-params.ts b/src/features/common/providers/router/models/router-quote-send-params.ts new file mode 100644 index 00000000000..b865f34af44 --- /dev/null +++ b/src/features/common/providers/router/models/router-quote-send-params.ts @@ -0,0 +1,9 @@ + +export interface RouterQuoteSendParams { + amount: string; + fromTokenAddress: string; + fromTokenChainId: string; + toTokenAddress: string; + toTokenChainId: string; + slippageTolerance?: number; +} \ No newline at end of file diff --git a/src/features/common/providers/router/models/router-send-transaction-params.ts b/src/features/common/providers/router/models/router-send-transaction-params.ts new file mode 100644 index 00000000000..ec7c66967ff --- /dev/null +++ b/src/features/common/providers/router/models/router-send-transaction-params.ts @@ -0,0 +1,15 @@ +import { RouterQuoteResponseConfig } from './router-quote-response-config'; + +export interface RouterSendTransactionParams extends RouterQuoteResponseConfig { + senderAddress: string; + receiverAddress: string; + refundAddress: string; +} + +export interface RouterSendTransactionResponse extends RouterSendTransactionParams { + txn: { + value: string; + to: string; + data: string; + } +} \ No newline at end of file diff --git a/src/features/common/providers/router/services/router-api-service.ts b/src/features/common/providers/router/services/router-api-service.ts new file mode 100644 index 00000000000..03423623df0 --- /dev/null +++ b/src/features/common/providers/router/services/router-api-service.ts @@ -0,0 +1,28 @@ +import { Injector } from "src/core/injector/injector"; +import { RouterQuoteResponseConfig } from "../models/router-quote-response-config"; +import { RouterQuoteSendParams } from "../models/router-quote-send-params"; +import { RouterSendTransactionParams, RouterSendTransactionResponse } from "../models/router-send-transaction-params"; + + +export class RouterApiService { + private static readonly ROUTER_ENDPOINT = 'https://api-beta.pathfinder.routerprotocol.com/api/v2'; + private static readonly partnerId = 0; + + public static async getQuote( + params: RouterQuoteSendParams + ): Promise { + return Injector.httpClient.get( + `${this.ROUTER_ENDPOINT}/quote`, { + params: { ...params, partnerId: this.partnerId } + }) + } + + public static async getSwapTx( + params: RouterSendTransactionParams + ): Promise { + return Injector.httpClient.post( + `${this.ROUTER_ENDPOINT}/transaction`, + params + ) + } +} \ No newline at end of file diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts index 5576b18ee22..781a4de1722 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts @@ -1,12 +1,20 @@ +import { NotSupportedTokensError } from "src/common/errors"; import { PriceTokenAmount, PriceToken } from "src/common/tokens"; import { BlockchainName } from "src/core/blockchain/models/blockchain-name"; +import { blockchainId } from "src/core/blockchain/utils/blockchains-info/constants/blockchain-id"; import { EvmEncodeConfig } from "src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/models/evm-encode-config"; import { TronTransactionConfig } from "src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config"; +import { Web3Pure } from "src/core/blockchain/web3-pure/web3-pure"; +import { RouterApiService } from "src/features/common/providers/router/services/router-api-service"; +import { getFromWithoutFee } from "src/features/common/utils/get-from-without-fee"; import { CrossChainOptions, RequiredCrossChainOptions } from "../../models/cross-chain-options"; import { CROSS_CHAIN_TRADE_TYPE } from "../../models/cross-chain-trade-type"; import { CrossChainProvider } from "../common/cross-chain-provider"; import { CalculationResult } from "../common/models/calculation-result"; -import { routerCrossChainSupportedChains } from "./constants/router-cross-chain-supported-chains"; +import { FeeInfo } from "../common/models/fee-info"; +import { ProxyCrossChainEvmTrade } from "../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade"; +import { RouterCrossChainSupportedBlockchains, routerCrossChainSupportedChains } from "./constants/router-cross-chain-supported-chains"; +import { RouterCrossChainTrade } from "./router-cross-chain-trade"; export class RouterCrossChainProvider extends CrossChainProvider { public readonly type = CROSS_CHAIN_TRADE_TYPE.ROUTER; @@ -24,6 +32,95 @@ export class RouterCrossChainProvider extends CrossChainProvider { toToken: PriceToken, options: RequiredCrossChainOptions ): Promise { + if (!this.areSupportedBlockchains(from.blockchain, toToken.blockchain)) { + return { + trade: null, + error: new NotSupportedTokensError(), + tradeType: this.type + } + } + const useProxy = options?.useProxy?.[this.type] ?? true; + const fromBlockchain = from.blockchain as RouterCrossChainSupportedBlockchains; + + try { + const srcChainId = blockchainId[from.blockchain]; + const dstChainId = blockchainId[toToken.blockchain]; + const NATIVE_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; + const srcTokenAddress = from.isNative ? NATIVE_TOKEN_ADDRESS : from.address; + const dstTokenAddress = toToken.isNative ? NATIVE_TOKEN_ADDRESS : toToken.address; + const feeInfo = this.getFeeInfo( + fromBlockchain, + options.providerAddress, + from, + useProxy + ); + + const fromWithoutFee = getFromWithoutFee( + from, + feeInfo?.rubicProxy?.platformFee?.percent + ); + + const routerQuoteConfig = await RouterApiService.getQuote({ + amount: fromWithoutFee.stringWeiAmount, + fromTokenAddress: srcTokenAddress, + fromTokenChainId: srcChainId, + toTokenAddress: dstTokenAddress, + toTokenChainId: dstChainId, + slippageTolerance: options.slippageTolerance * 100 + }); + const dstTokenAmount = routerQuoteConfig.destination.tokenAmount; + const to = new PriceTokenAmount({ + ...toToken.asStruct, + tokenAmount: Web3Pure.fromWei( + dstTokenAmount, + routerQuoteConfig.destination.asset.decimals + ) + }); + + const gasData = + options.gasCalculation === 'enabled' + ? RouterCrossChainTrade.getGasData( + from, + to, + feeInfo, + options.providerAddress, + options?.receiverAddress + ) : null; + return { + trade: new RouterCrossChainTrade({ + from, + to, + feeInfo, + gasData, + priceImpact: from.calculatePriceImpactPercent(to), + }, + options.providerAddress, + [] + ), + tradeType: this.type + } + } catch (err) { + return { + trade: null, + error: err, + tradeType: this.type + } + } + } + + + private async getFeeInfo( + fromBlockchain: RouterCrossChainSupportedBlockchains, + providerAddress: string, + percentFeeToken: PriceTokenAmount, + useProxy: boolean + ): Promise { + return ProxyCrossChainEvmTrade.getFeeInfo( + fromBlockchain, + providerAddress, + percentFeeToken, + useProxy + ) } -} \ No newline at end of file +} diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts index 72003153c74..204f231575a 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -1,6 +1,82 @@ +import BigNumber from "bignumber.js"; +import { PriceTokenAmount } from "src/common/tokens"; +import { EvmBlockchainName } from "src/core/blockchain/models/blockchain-name"; +import { EvmWeb3Pure } from "src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/evm-web3-pure"; +import { RouterQuoteResponseConfig } from "src/features/common/providers/router/models/router-quote-response-config"; +import { CrossChainTradeType, CROSS_CHAIN_TRADE_TYPE } from "../../models/cross-chain-trade-type"; +import { getCrossChainGasData } from "../../utils/get-cross-chain-gas-data"; import { EvmCrossChainTrade } from "../common/emv-cross-chain-trade/evm-cross-chain-trade"; +import { GasData } from "../common/emv-cross-chain-trade/models/gas-data"; +import { BridgeType, BRIDGE_TYPE } from "../common/models/bridge-type"; +import { FeeInfo } from "../common/models/fee-info"; +import { OnChainSubtype } from "../common/models/on-chain-subtype"; +import { RubicStep } from "../common/models/rubicStep"; -export class RouterCrossChainTrade extends EvmCrossChainTrade{ +export class RouterCrossChainTrade extends EvmCrossChainTrade { + + public static async getGasData( + from: PriceTokenAmount, + to: PriceTokenAmount, + feeInfo: FeeInfo, + providerAddress: string, + receiverAddress?: string + ): Promise { + const trade = new RouterCrossChainTrade( + { + from, + to, + feeInfo, + gasData: null, + priceImpact: 0 + }, + providerAddress: providerAddress || EvmWeb3Pure.EMPTY_ADDRESS, + [] + ); + return getCrossChainGasData(trade, receiverAddress) + } + + public readonly type: CrossChainTradeType = CROSS_CHAIN_TRADE_TYPE.ROUTER; + + public readonly to: PriceTokenAmount; + + public readonly from: PriceTokenAmount; + + public readonly toTokenAmountMin: BigNumber; + + public readonly feeInfo: FeeInfo; + + public readonly onChainSubtype: OnChainSubtype = { from: undefined, to: undefined }; + + public readonly bridgeType: BridgeType = BRIDGE_TYPE.ROUTER; + + public readonly gasData: GasData | null; + + public readonly priceImpact: number | null; + + private readonly slippage: number; + + private readonly routerQuoteConfig: RouterQuoteResponseConfig; + + constructor( + crossChainTrade: { + from: PriceTokenAmount, + to: PriceTokenAmount, + feeInfo: FeeInfo, + gasData: GasData | null, + priceImpact: number | null, + routerQuoteConfig: RouterQuoteResponseConfig + }, + providerAddress: string, + routePath: RubicStep[] + ) { + super(providerAddress, routePath); + this.from = crossChainTrade.from; + this.to = crossChainTrade.to; + this.feeInfo = crossChainTrade.feeInfo; + this.gasData = crossChainTrade.gasData; + this.priceImpact = crossChainTrade.priceImpact; + this.routerQuoteConfig = crossChainTrade.routerQuoteConfig; + } } \ No newline at end of file From cb116598e814aef2408590119dd0281b2b1ad2d5 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 17 Jul 2024 16:18:52 +0300 Subject: [PATCH 03/18] add provider methods --- .../router-cross-chain-blockchains-id.ts | 30 ----------- .../router-cross-chain-provider.ts | 42 ++++++++++----- .../router-cross-chain-trade.ts | 53 +++++++++++++++++-- .../cross-chain-status-manager.ts | 3 +- 4 files changed, 80 insertions(+), 48 deletions(-) delete mode 100644 src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-blockchains-id.ts diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-blockchains-id.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-blockchains-id.ts deleted file mode 100644 index de30ae50cd6..00000000000 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-blockchains-id.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { BLOCKCHAIN_NAME } from "src/core/blockchain/models/blockchain-name"; -import { RouterCrossChainSupportedBlockchains } from "./router-cross-chain-supported-chains"; - -export const routerChainId: Record = { - [BLOCKCHAIN_NAME.ETHEREUM]: 1, - [BLOCKCHAIN_NAME.OPTIMISM]: 10, - [BLOCKCHAIN_NAME.ROOTSTOCK]: 30, - [BLOCKCHAIN_NAME.BINANCE_SMART_CHAIN]: 56, - [BLOCKCHAIN_NAME.POLYGON]: 137, - [BLOCKCHAIN_NAME.MANTA_PACIFIC]: 169, - [BLOCKCHAIN_NAME.XLAYER]: 196, - [BLOCKCHAIN_NAME.FANTOM]: 250, - [BLOCKCHAIN_NAME.BOBA]: 288, - [BLOCKCHAIN_NAME.ZK_SYNC]: 324, - [BLOCKCHAIN_NAME.METIS]: 1088, - // [BLOCKCHAIN_NAME.POLYGON_ZKEVM], - // [BLOCKCHAIN_NAME.DOGECOIN], - // [BLOCKCHAIN_NAME.MANTLE], - // [BLOCKCHAIN_NAME.BASE], - // [BLOCKCHAIN_NAME.OASIS], - // [BLOCKCHAIN_NAME.MODE], - // [BLOCKCHAIN_NAME.ARBITRUM], - // [BLOCKCHAIN_NAME.AVALANCHE], - // [BLOCKCHAIN_NAME.LINEA], - // [BLOCKCHAIN_NAME.BLAST], - // [BLOCKCHAIN_NAME.TAIKO], - // [BLOCKCHAIN_NAME.SCROLL], - // [BLOCKCHAIN_NAME.TRON], - // [BLOCKCHAIN_NAME.AURORA], -} \ No newline at end of file diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts index 781a4de1722..cc06871a4df 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts @@ -1,6 +1,6 @@ import { NotSupportedTokensError } from "src/common/errors"; import { PriceTokenAmount, PriceToken } from "src/common/tokens"; -import { BlockchainName } from "src/core/blockchain/models/blockchain-name"; +import { BlockchainName, EvmBlockchainName } from "src/core/blockchain/models/blockchain-name"; import { blockchainId } from "src/core/blockchain/utils/blockchains-info/constants/blockchain-id"; import { EvmEncodeConfig } from "src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/models/evm-encode-config"; import { TronTransactionConfig } from "src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config"; @@ -12,6 +12,7 @@ import { CROSS_CHAIN_TRADE_TYPE } from "../../models/cross-chain-trade-type"; import { CrossChainProvider } from "../common/cross-chain-provider"; import { CalculationResult } from "../common/models/calculation-result"; import { FeeInfo } from "../common/models/fee-info"; +import { RubicStep } from "../common/models/rubicStep"; import { ProxyCrossChainEvmTrade } from "../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade"; import { RouterCrossChainSupportedBlockchains, routerCrossChainSupportedChains } from "./constants/router-cross-chain-supported-chains"; import { RouterCrossChainTrade } from "./router-cross-chain-trade"; @@ -28,8 +29,8 @@ export class RouterCrossChainProvider extends CrossChainProvider { } public async calculate( - from: PriceTokenAmount, - toToken: PriceToken, + from: PriceTokenAmount, + toToken: PriceToken, options: RequiredCrossChainOptions ): Promise { if (!this.areSupportedBlockchains(from.blockchain, toToken.blockchain)) { @@ -41,7 +42,6 @@ export class RouterCrossChainProvider extends CrossChainProvider { } const useProxy = options?.useProxy?.[this.type] ?? true; - const fromBlockchain = from.blockchain as RouterCrossChainSupportedBlockchains; try { const srcChainId = blockchainId[from.blockchain]; @@ -49,8 +49,8 @@ export class RouterCrossChainProvider extends CrossChainProvider { const NATIVE_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; const srcTokenAddress = from.isNative ? NATIVE_TOKEN_ADDRESS : from.address; const dstTokenAddress = toToken.isNative ? NATIVE_TOKEN_ADDRESS : toToken.address; - const feeInfo = this.getFeeInfo( - fromBlockchain, + const feeInfo = await this.getFeeInfo( + from.blockchain, options.providerAddress, from, useProxy @@ -64,9 +64,9 @@ export class RouterCrossChainProvider extends CrossChainProvider { const routerQuoteConfig = await RouterApiService.getQuote({ amount: fromWithoutFee.stringWeiAmount, fromTokenAddress: srcTokenAddress, - fromTokenChainId: srcChainId, + fromTokenChainId: srcChainId.toString(), toTokenAddress: dstTokenAddress, - toTokenChainId: dstChainId, + toTokenChainId: dstChainId.toString(), slippageTolerance: options.slippageTolerance * 100 }); const dstTokenAmount = routerQuoteConfig.destination.tokenAmount; @@ -78,13 +78,16 @@ export class RouterCrossChainProvider extends CrossChainProvider { ) }); + const routePath = await this.getRoutePath(from, to); + const gasData = options.gasCalculation === 'enabled' - ? RouterCrossChainTrade.getGasData( + ? await RouterCrossChainTrade.getGasData( from, to, feeInfo, options.providerAddress, + routerQuoteConfig, options?.receiverAddress ) : null; return { @@ -94,9 +97,11 @@ export class RouterCrossChainProvider extends CrossChainProvider { feeInfo, gasData, priceImpact: from.calculatePriceImpactPercent(to), + routerQuoteConfig, + slippage: options.slippageTolerance }, options.providerAddress, - [] + routePath ), tradeType: this.type } @@ -109,9 +114,20 @@ export class RouterCrossChainProvider extends CrossChainProvider { } } - - private async getFeeInfo( - fromBlockchain: RouterCrossChainSupportedBlockchains, + protected async getRoutePath( + fromToken: PriceTokenAmount, + toToken: PriceTokenAmount + ): Promise { + return [ + { + type: 'cross-chain', + provider: this.type, + path: [fromToken, toToken] + } + ]; + } + public async getFeeInfo( + fromBlockchain: EvmBlockchainName, providerAddress: string, percentFeeToken: PriceTokenAmount, useProxy: boolean diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts index 204f231575a..9af0328005c 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -1,16 +1,22 @@ import BigNumber from "bignumber.js"; +import { RubicSdkError } from "src/common/errors"; import { PriceTokenAmount } from "src/common/tokens"; import { EvmBlockchainName } from "src/core/blockchain/models/blockchain-name"; import { EvmWeb3Pure } from "src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/evm-web3-pure"; +import { ContractParams } from "src/features/common/models/contract-params"; import { RouterQuoteResponseConfig } from "src/features/common/providers/router/models/router-quote-response-config"; import { CrossChainTradeType, CROSS_CHAIN_TRADE_TYPE } from "../../models/cross-chain-trade-type"; import { getCrossChainGasData } from "../../utils/get-cross-chain-gas-data"; +import { rubicProxyContractAddress } from "../common/constants/rubic-proxy-contract-address"; import { EvmCrossChainTrade } from "../common/emv-cross-chain-trade/evm-cross-chain-trade"; import { GasData } from "../common/emv-cross-chain-trade/models/gas-data"; import { BridgeType, BRIDGE_TYPE } from "../common/models/bridge-type"; import { FeeInfo } from "../common/models/fee-info"; +import { GetContractParamsOptions } from "../common/models/get-contract-params-options"; import { OnChainSubtype } from "../common/models/on-chain-subtype"; import { RubicStep } from "../common/models/rubicStep"; +import { TradeInfo } from "../common/models/trade-info"; +import { RouterCrossChainSupportedBlockchains } from "./constants/router-cross-chain-supported-chains"; export class RouterCrossChainTrade extends EvmCrossChainTrade { @@ -20,6 +26,7 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { to: PriceTokenAmount, feeInfo: FeeInfo, providerAddress: string, + routerQuoteConfig: RouterQuoteResponseConfig, receiverAddress?: string ): Promise { const trade = new RouterCrossChainTrade( @@ -28,9 +35,11 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { to, feeInfo, gasData: null, - priceImpact: 0 + priceImpact: 0, + routerQuoteConfig, + slippage: 0 }, - providerAddress: providerAddress || EvmWeb3Pure.EMPTY_ADDRESS, + providerAddress || EvmWeb3Pure.EMPTY_ADDRESS, [] ); return getCrossChainGasData(trade, receiverAddress) @@ -42,7 +51,7 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { public readonly from: PriceTokenAmount; - public readonly toTokenAmountMin: BigNumber; + public readonly toTokenAmountMin: BigNumber = new BigNumber(0); public readonly feeInfo: FeeInfo; @@ -56,8 +65,25 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { private readonly slippage: number; + public readonly isAggregator = false; + private readonly routerQuoteConfig: RouterQuoteResponseConfig; + private get fromBlockchain(): RouterCrossChainSupportedBlockchains { + return this.from.blockchain as RouterCrossChainSupportedBlockchains; + } + + + protected get fromContractAddress(): string { + return this.isProxyTrade + ? rubicProxyContractAddress[this.fromBlockchain].gateway + : ' '; + } + + protected get methodName(): string { + return 'startBridgeTokensViaGenericCrossChain'; + } + constructor( crossChainTrade: { from: PriceTokenAmount, @@ -65,7 +91,8 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { feeInfo: FeeInfo, gasData: GasData | null, priceImpact: number | null, - routerQuoteConfig: RouterQuoteResponseConfig + routerQuoteConfig: RouterQuoteResponseConfig, + slippage: number, }, providerAddress: string, routePath: RubicStep[] @@ -77,6 +104,24 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { this.gasData = crossChainTrade.gasData; this.priceImpact = crossChainTrade.priceImpact; this.routerQuoteConfig = crossChainTrade.routerQuoteConfig; + this.slippage = crossChainTrade.slippage; + } + + protected getContractParams( + options: GetContractParamsOptions, + skipAmountChangeCheck?: boolean | undefined + ): Promise { + console.log(options, skipAmountChangeCheck) + return Promise.reject(new RubicSdkError('method not implemented')); } + public getTradeInfo(): TradeInfo { + return { + estimatedGas: this.estimatedGas, + feeInfo: this.feeInfo, + priceImpact: this.priceImpact, + slippage: this.slippage, + routePath: this.routePath + } + }; } \ No newline at end of file diff --git a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts index db0b7fd8983..db59fdf7e1a 100644 --- a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts +++ b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts @@ -97,7 +97,8 @@ export class CrossChainStatusManager { [CROSS_CHAIN_TRADE_TYPE.ARCHON_BRIDGE]: this.getLayerZeroDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.MESON]: this.getMesonDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.OWL_TO_BRIDGE]: this.getOwlToDstSwapStatus, - [CROSS_CHAIN_TRADE_TYPE.EDDY_BRIDGE]: this.getEddyBridgeDstSwapStatus + [CROSS_CHAIN_TRADE_TYPE.EDDY_BRIDGE]: this.getEddyBridgeDstSwapStatus, + [CROSS_CHAIN_TRADE_TYPE.ROUTER]: this.getLayerZeroDstSwapStatus }; /** From 43e50bb8f92f8a15b20408ff222cb068ba54c314 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 17 Jul 2024 17:03:56 +0300 Subject: [PATCH 04/18] update trade class --- .../router-provider/router-cross-chain-trade.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts index 9af0328005c..e0ece62dba0 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -115,6 +115,19 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { return Promise.reject(new RubicSdkError('method not implemented')); } + protected getTransactionConfigAndAmount( + receiverAddress?: string + ): Promise<{ + config: { + value: string, + to: string, + data: string + }; amount: string + }> { + console.log(receiverAddress) + return Promise.reject(new RubicSdkError('method not implemented')); + }; + public getTradeInfo(): TradeInfo { return { estimatedGas: this.estimatedGas, From 7d270c251b8bcddbcc11f950c124c481213909d2 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 18 Jul 2024 15:37:25 +0300 Subject: [PATCH 05/18] update getRoutePath method --- .../models/router-quote-response-config.ts | 10 +- .../router/models/router-quote-send-params.ts | 3 +- .../models/router-send-transaction-params.ts | 7 +- .../router/services/router-api-service.ts | 24 +-- .../constants/cross-chain-providers.ts | 4 +- .../router-cross-chain-supported-chains.ts | 8 +- .../router-cross-chain-provider.ts | 155 ++++++++++++------ .../router-cross-chain-trade.ts | 107 ++++++------ .../common/models/on-chain-trade-type.ts | 1 + 9 files changed, 195 insertions(+), 124 deletions(-) diff --git a/src/features/common/providers/router/models/router-quote-response-config.ts b/src/features/common/providers/router/models/router-quote-response-config.ts index d8568990350..c29a4d8cc13 100644 --- a/src/features/common/providers/router/models/router-quote-response-config.ts +++ b/src/features/common/providers/router/models/router-quote-response-config.ts @@ -1,5 +1,3 @@ - - type RouterFlowType = 'trustless' | 'mint-burn' | 'circle' | 'gateway' | 'none'; interface RouterAsset { @@ -19,11 +17,11 @@ interface RouterSwapTokenInfo { stableReserveAsset: RouterAsset; tokenAmount: string; stableReserveAmount: string; - path: unknown[]; - flags: unknown[]; + path: string[]; + flags: string[]; priceImpact: string; tokenPath: string; - dataTx: unknown[] + dataTx: string[]; } export interface RouterQuoteResponseConfig { @@ -34,7 +32,7 @@ export interface RouterQuoteResponseConfig { fromTokenAddress: string; toTokenAddress: string; source: RouterSwapTokenInfo & { - bridgeFeeAmount: string + bridgeFeeAmount: string; }; destination: RouterSwapTokenInfo; partnerId: number; diff --git a/src/features/common/providers/router/models/router-quote-send-params.ts b/src/features/common/providers/router/models/router-quote-send-params.ts index b865f34af44..f74c62a16d2 100644 --- a/src/features/common/providers/router/models/router-quote-send-params.ts +++ b/src/features/common/providers/router/models/router-quote-send-params.ts @@ -1,4 +1,3 @@ - export interface RouterQuoteSendParams { amount: string; fromTokenAddress: string; @@ -6,4 +5,4 @@ export interface RouterQuoteSendParams { toTokenAddress: string; toTokenChainId: string; slippageTolerance?: number; -} \ No newline at end of file +} diff --git a/src/features/common/providers/router/models/router-send-transaction-params.ts b/src/features/common/providers/router/models/router-send-transaction-params.ts index ec7c66967ff..42a7049b47f 100644 --- a/src/features/common/providers/router/models/router-send-transaction-params.ts +++ b/src/features/common/providers/router/models/router-send-transaction-params.ts @@ -8,8 +8,11 @@ export interface RouterSendTransactionParams extends RouterQuoteResponseConfig { export interface RouterSendTransactionResponse extends RouterSendTransactionParams { txn: { + from: string; value: string; to: string; data: string; - } -} \ No newline at end of file + gasPrice: string; + gasLimit: string; + }; +} diff --git a/src/features/common/providers/router/services/router-api-service.ts b/src/features/common/providers/router/services/router-api-service.ts index 03423623df0..6b7a0138691 100644 --- a/src/features/common/providers/router/services/router-api-service.ts +++ b/src/features/common/providers/router/services/router-api-service.ts @@ -1,20 +1,24 @@ -import { Injector } from "src/core/injector/injector"; -import { RouterQuoteResponseConfig } from "../models/router-quote-response-config"; -import { RouterQuoteSendParams } from "../models/router-quote-send-params"; -import { RouterSendTransactionParams, RouterSendTransactionResponse } from "../models/router-send-transaction-params"; +import { Injector } from 'src/core/injector/injector'; +import { RouterQuoteResponseConfig } from '../models/router-quote-response-config'; +import { RouterQuoteSendParams } from '../models/router-quote-send-params'; +import { + RouterSendTransactionParams, + RouterSendTransactionResponse +} from '../models/router-send-transaction-params'; export class RouterApiService { - private static readonly ROUTER_ENDPOINT = 'https://api-beta.pathfinder.routerprotocol.com/api/v2'; + private static readonly ROUTER_ENDPOINT = + 'https://api-beta.pathfinder.routerprotocol.com/api/v2'; + private static readonly partnerId = 0; public static async getQuote( params: RouterQuoteSendParams ): Promise { - return Injector.httpClient.get( - `${this.ROUTER_ENDPOINT}/quote`, { + return Injector.httpClient.get(`${this.ROUTER_ENDPOINT}/quote`, { params: { ...params, partnerId: this.partnerId } - }) + }); } public static async getSwapTx( @@ -23,6 +27,6 @@ export class RouterApiService { return Injector.httpClient.post( `${this.ROUTER_ENDPOINT}/transaction`, params - ) + ); } -} \ No newline at end of file +} diff --git a/src/features/cross-chain/calculation-manager/constants/cross-chain-providers.ts b/src/features/cross-chain/calculation-manager/constants/cross-chain-providers.ts index 24ce2169abd..7dcb11f9b06 100644 --- a/src/features/cross-chain/calculation-manager/constants/cross-chain-providers.ts +++ b/src/features/cross-chain/calculation-manager/constants/cross-chain-providers.ts @@ -16,6 +16,7 @@ import { MesonCrossChainProvider } from '../providers/meson-provider/meson-cross import { OrbiterBridgeProvider } from '../providers/orbiter-bridge/orbiter-bridge-provider'; import { OwlToBridgeProvider } from '../providers/owl-to-bridge/owl-to-bridge-provider'; import { RangoCrossChainProvider } from '../providers/rango-provider/rango-cross-chain-provider'; +import { RouterCrossChainProvider } from '../providers/router-provider/router-cross-chain-provider'; // import { StargateCrossChainProvider } from '../providers/stargate-provider/stargate-cross-chain-provider'; import { TaikoBridgeProvider } from '../providers/taiko-bridge/taiko-bridge-provider'; @@ -33,7 +34,8 @@ const proxyProviders = [ ArchonBridgeProvider, MesonCrossChainProvider, OwlToBridgeProvider, - EddyBridgeProvider + EddyBridgeProvider, + RouterCrossChainProvider ] as const; const nonProxyProviders = [ diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts index 85083662c86..d43cbaa1ecf 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts @@ -1,4 +1,4 @@ -import { BLOCKCHAIN_NAME } from "src/core/blockchain/models/blockchain-name"; +import { BLOCKCHAIN_NAME } from 'src/core/blockchain/models/blockchain-name'; export const routerCrossChainSupportedChains = [ BLOCKCHAIN_NAME.ETHEREUM, @@ -25,7 +25,7 @@ export const routerCrossChainSupportedChains = [ BLOCKCHAIN_NAME.TAIKO, BLOCKCHAIN_NAME.SCROLL, BLOCKCHAIN_NAME.TRON, - BLOCKCHAIN_NAME.AURORA, -] + BLOCKCHAIN_NAME.AURORA +]; -export type RouterCrossChainSupportedBlockchains = (typeof routerCrossChainSupportedChains)[number]; \ No newline at end of file +export type RouterCrossChainSupportedBlockchains = (typeof routerCrossChainSupportedChains)[number]; diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts index cc06871a4df..26de8249ac2 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts @@ -1,31 +1,29 @@ -import { NotSupportedTokensError } from "src/common/errors"; -import { PriceTokenAmount, PriceToken } from "src/common/tokens"; -import { BlockchainName, EvmBlockchainName } from "src/core/blockchain/models/blockchain-name"; -import { blockchainId } from "src/core/blockchain/utils/blockchains-info/constants/blockchain-id"; -import { EvmEncodeConfig } from "src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/models/evm-encode-config"; -import { TronTransactionConfig } from "src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config"; -import { Web3Pure } from "src/core/blockchain/web3-pure/web3-pure"; -import { RouterApiService } from "src/features/common/providers/router/services/router-api-service"; -import { getFromWithoutFee } from "src/features/common/utils/get-from-without-fee"; -import { CrossChainOptions, RequiredCrossChainOptions } from "../../models/cross-chain-options"; -import { CROSS_CHAIN_TRADE_TYPE } from "../../models/cross-chain-trade-type"; -import { CrossChainProvider } from "../common/cross-chain-provider"; -import { CalculationResult } from "../common/models/calculation-result"; -import { FeeInfo } from "../common/models/fee-info"; -import { RubicStep } from "../common/models/rubicStep"; -import { ProxyCrossChainEvmTrade } from "../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade"; -import { RouterCrossChainSupportedBlockchains, routerCrossChainSupportedChains } from "./constants/router-cross-chain-supported-chains"; -import { RouterCrossChainTrade } from "./router-cross-chain-trade"; +import BigNumber from 'bignumber.js'; +import { NotSupportedTokensError } from 'src/common/errors'; +import { PriceToken, PriceTokenAmount, TokenAmount } from 'src/common/tokens'; +import { BlockchainName, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; +import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; +import { RouterQuoteResponseConfig } from 'src/features/common/providers/router/models/router-quote-response-config'; +import { RouterApiService } from 'src/features/common/providers/router/services/router-api-service'; +import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; +import { ON_CHAIN_TRADE_TYPE } from 'src/features/on-chain/calculation-manager/providers/common/models/on-chain-trade-type'; + +import { RequiredCrossChainOptions } from '../../models/cross-chain-options'; +import { CROSS_CHAIN_TRADE_TYPE } from '../../models/cross-chain-trade-type'; +import { CrossChainProvider } from '../common/cross-chain-provider'; +import { CalculationResult } from '../common/models/calculation-result'; +import { FeeInfo } from '../common/models/fee-info'; +import { RubicStep } from '../common/models/rubicStep'; +import { ProxyCrossChainEvmTrade } from '../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade'; +import { routerCrossChainSupportedChains } from './constants/router-cross-chain-supported-chains'; +import { RouterCrossChainTrade } from './router-cross-chain-trade'; export class RouterCrossChainProvider extends CrossChainProvider { public readonly type = CROSS_CHAIN_TRADE_TYPE.ROUTER; - public isSupportedBlockchain( - fromBlockchain: BlockchainName - ): boolean { - return routerCrossChainSupportedChains.some( - chain => chain === fromBlockchain - ) + public isSupportedBlockchain(fromBlockchain: BlockchainName): boolean { + return routerCrossChainSupportedChains.some(chain => chain === fromBlockchain); } public async calculate( @@ -38,7 +36,7 @@ export class RouterCrossChainProvider extends CrossChainProvider { trade: null, error: new NotSupportedTokensError(), tradeType: this.type - } + }; } const useProxy = options?.useProxy?.[this.type] ?? true; @@ -78,54 +76,111 @@ export class RouterCrossChainProvider extends CrossChainProvider { ) }); - const routePath = await this.getRoutePath(from, to); + const routePath = await this.getRoutePath(from, to, routerQuoteConfig); const gasData = options.gasCalculation === 'enabled' ? await RouterCrossChainTrade.getGasData( + from, + to, + feeInfo, + options.providerAddress, + routerQuoteConfig, + options?.receiverAddress + ) + : null; + return { + trade: new RouterCrossChainTrade( + { from, to, feeInfo, - options.providerAddress, + gasData, + priceImpact: from.calculatePriceImpactPercent(to), routerQuoteConfig, - options?.receiverAddress - ) : null; - return { - trade: new RouterCrossChainTrade({ - from, - to, - feeInfo, - gasData, - priceImpact: from.calculatePriceImpactPercent(to), - routerQuoteConfig, - slippage: options.slippageTolerance - }, + slippage: options.slippageTolerance + }, options.providerAddress, routePath ), tradeType: this.type - } + }; } catch (err) { return { trade: null, error: err, tradeType: this.type - } + }; } } protected async getRoutePath( fromToken: PriceTokenAmount, - toToken: PriceTokenAmount + toToken: PriceTokenAmount, + routerQuoteConfig: RouterQuoteResponseConfig ): Promise { - return [ - { - type: 'cross-chain', - provider: this.type, - path: [fromToken, toToken] - } - ]; + const routerSrcAsset = routerQuoteConfig.source; + const routerDstAsset = routerQuoteConfig.destination; + + if (routerSrcAsset.path.length === 0 && routerDstAsset.path.length === 0) { + return [ + { + type: 'cross-chain', + provider: this.type, + path: [fromToken, toToken] + } + ]; + } + const transitFromAddress = + fromToken.address.toLowerCase() !== + routerSrcAsset.stableReserveAsset.address.toLowerCase() + ? routerSrcAsset.stableReserveAsset.address + : null; + + const transitToAddress = + toToken.address.toLowerCase() !== + routerDstAsset.stableReserveAsset.address.toLowerCase() + ? routerDstAsset.stableReserveAsset.address + : null; + const fromTransitToken = transitFromAddress + ? await TokenAmount.createToken({ + blockchain: fromToken.blockchain, + address: transitFromAddress, + weiAmount: new BigNumber(routerSrcAsset.stableReserveAmount) + }) + : fromToken; + + const toTransitToken = transitToAddress + ? await TokenAmount.createToken({ + blockchain: toToken.blockchain, + address: transitToAddress, + weiAmount: new BigNumber(routerDstAsset.stableReserveAmount) + }) + : toToken; + const routePath: RubicStep[] = []; + + if (transitFromAddress) { + routePath.push({ + type: 'on-chain', + provider: ON_CHAIN_TRADE_TYPE.ROUTER_SWAP, + path: [fromToken, fromTransitToken] + }); + } + routePath.push({ + type: 'cross-chain', + provider: CROSS_CHAIN_TRADE_TYPE.ROUTER, + path: [fromTransitToken, toTransitToken] + }); + if (transitToAddress) { + routePath.push({ + type: 'on-chain', + provider: ON_CHAIN_TRADE_TYPE.ROUTER_SWAP, + path: [toTransitToken, toToken] + }); + } + return routePath; } + public async getFeeInfo( fromBlockchain: EvmBlockchainName, providerAddress: string, @@ -137,6 +192,6 @@ export class RouterCrossChainProvider extends CrossChainProvider { providerAddress, percentFeeToken, useProxy - ) + ); } } diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts index e0ece62dba0..b6a1c67b037 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -1,26 +1,27 @@ -import BigNumber from "bignumber.js"; -import { RubicSdkError } from "src/common/errors"; -import { PriceTokenAmount } from "src/common/tokens"; -import { EvmBlockchainName } from "src/core/blockchain/models/blockchain-name"; -import { EvmWeb3Pure } from "src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/evm-web3-pure"; -import { ContractParams } from "src/features/common/models/contract-params"; -import { RouterQuoteResponseConfig } from "src/features/common/providers/router/models/router-quote-response-config"; -import { CrossChainTradeType, CROSS_CHAIN_TRADE_TYPE } from "../../models/cross-chain-trade-type"; -import { getCrossChainGasData } from "../../utils/get-cross-chain-gas-data"; -import { rubicProxyContractAddress } from "../common/constants/rubic-proxy-contract-address"; -import { EvmCrossChainTrade } from "../common/emv-cross-chain-trade/evm-cross-chain-trade"; -import { GasData } from "../common/emv-cross-chain-trade/models/gas-data"; -import { BridgeType, BRIDGE_TYPE } from "../common/models/bridge-type"; -import { FeeInfo } from "../common/models/fee-info"; -import { GetContractParamsOptions } from "../common/models/get-contract-params-options"; -import { OnChainSubtype } from "../common/models/on-chain-subtype"; -import { RubicStep } from "../common/models/rubicStep"; -import { TradeInfo } from "../common/models/trade-info"; -import { RouterCrossChainSupportedBlockchains } from "./constants/router-cross-chain-supported-chains"; - +import BigNumber from 'bignumber.js'; +import { RubicSdkError } from 'src/common/errors'; +import { PriceTokenAmount } from 'src/common/tokens'; +import { EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { EvmWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/evm-web3-pure'; +import { EvmEncodeConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/models/evm-encode-config'; +import { ContractParams } from 'src/features/common/models/contract-params'; +import { RouterQuoteResponseConfig } from 'src/features/common/providers/router/models/router-quote-response-config'; +import { RouterApiService } from 'src/features/common/providers/router/services/router-api-service'; + +import { CROSS_CHAIN_TRADE_TYPE, CrossChainTradeType } from '../../models/cross-chain-trade-type'; +import { getCrossChainGasData } from '../../utils/get-cross-chain-gas-data'; +import { rubicProxyContractAddress } from '../common/constants/rubic-proxy-contract-address'; +import { EvmCrossChainTrade } from '../common/emv-cross-chain-trade/evm-cross-chain-trade'; +import { GasData } from '../common/emv-cross-chain-trade/models/gas-data'; +import { BRIDGE_TYPE, BridgeType } from '../common/models/bridge-type'; +import { FeeInfo } from '../common/models/fee-info'; +import { GetContractParamsOptions } from '../common/models/get-contract-params-options'; +import { OnChainSubtype } from '../common/models/on-chain-subtype'; +import { RubicStep } from '../common/models/rubicStep'; +import { TradeInfo } from '../common/models/trade-info'; +import { RouterCrossChainSupportedBlockchains } from './constants/router-cross-chain-supported-chains'; export class RouterCrossChainTrade extends EvmCrossChainTrade { - public static async getGasData( from: PriceTokenAmount, to: PriceTokenAmount, @@ -42,7 +43,7 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { providerAddress || EvmWeb3Pure.EMPTY_ADDRESS, [] ); - return getCrossChainGasData(trade, receiverAddress) + return getCrossChainGasData(trade, receiverAddress); } public readonly type: CrossChainTradeType = CROSS_CHAIN_TRADE_TYPE.ROUTER; @@ -73,11 +74,8 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { return this.from.blockchain as RouterCrossChainSupportedBlockchains; } - protected get fromContractAddress(): string { - return this.isProxyTrade - ? rubicProxyContractAddress[this.fromBlockchain].gateway - : ' '; + return this.isProxyTrade ? rubicProxyContractAddress[this.fromBlockchain].gateway : ' '; } protected get methodName(): string { @@ -86,13 +84,13 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { constructor( crossChainTrade: { - from: PriceTokenAmount, - to: PriceTokenAmount, - feeInfo: FeeInfo, - gasData: GasData | null, - priceImpact: number | null, - routerQuoteConfig: RouterQuoteResponseConfig, - slippage: number, + from: PriceTokenAmount; + to: PriceTokenAmount; + feeInfo: FeeInfo; + gasData: GasData | null; + priceImpact: number | null; + routerQuoteConfig: RouterQuoteResponseConfig; + slippage: number; }, providerAddress: string, routePath: RubicStep[] @@ -111,30 +109,41 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { options: GetContractParamsOptions, skipAmountChangeCheck?: boolean | undefined ): Promise { - console.log(options, skipAmountChangeCheck) + console.log(options, skipAmountChangeCheck); return Promise.reject(new RubicSdkError('method not implemented')); } - protected getTransactionConfigAndAmount( + protected async getTransactionConfigAndAmount( receiverAddress?: string - ): Promise<{ - config: { - value: string, - to: string, - data: string - }; amount: string - }> { - console.log(receiverAddress) - return Promise.reject(new RubicSdkError('method not implemented')); - }; + ): Promise<{ config: EvmEncodeConfig; amount: string }> { + const { txn, destination } = await RouterApiService.getSwapTx({ + ...this.routerQuoteConfig, + senderAddress: this.walletAddress, + receiverAddress: receiverAddress || this.walletAddress, + refundAddress: this.walletAddress + }); + + if (!txn) { + throw new RubicSdkError(); + } + + const config = { + data: txn.data, + value: txn.value, + to: txn.to, + gasPrice: txn.gasPrice + }; + + return { config, amount: destination.tokenAmount }; + } public getTradeInfo(): TradeInfo { return { estimatedGas: this.estimatedGas, feeInfo: this.feeInfo, priceImpact: this.priceImpact, - slippage: this.slippage, + slippage: this.slippage * 100, routePath: this.routePath - } - }; -} \ No newline at end of file + }; + } +} diff --git a/src/features/on-chain/calculation-manager/providers/common/models/on-chain-trade-type.ts b/src/features/on-chain/calculation-manager/providers/common/models/on-chain-trade-type.ts index fac1d87e9a0..04333d81aeb 100644 --- a/src/features/on-chain/calculation-manager/providers/common/models/on-chain-trade-type.ts +++ b/src/features/on-chain/calculation-manager/providers/common/models/on-chain-trade-type.ts @@ -109,6 +109,7 @@ export const ON_CHAIN_TRADE_TYPE = { RAYDIUM: 'RAYDIUM', REF_FINANCE: 'REF_FINANCE', REN_BTC: 'REN_BTC', + ROUTER_SWAP: 'ROUTER_SWAP', SABER_STABLE_SWAP: 'SABER_STABLE_SWAP', SAROS_SWAP: 'SAROS_SWAP', From b79e58341bc86f9872c1f7fd97a45755e4464507 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 19 Jul 2024 16:50:10 +0300 Subject: [PATCH 06/18] getContractParams method --- .../router-cross-chain-provider.ts | 2 +- .../router-cross-chain-trade.ts | 73 ++++++++++++++++++- 2 files changed, 70 insertions(+), 5 deletions(-) diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts index 26de8249ac2..98edb0c3e37 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts @@ -39,7 +39,7 @@ export class RouterCrossChainProvider extends CrossChainProvider { }; } - const useProxy = options?.useProxy?.[this.type] ?? true; + const useProxy = false; try { const srcChainId = blockchainId[from.blockchain]; diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts index b6a1c67b037..4f52a05949d 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -11,6 +11,8 @@ import { RouterApiService } from 'src/features/common/providers/router/services/ import { CROSS_CHAIN_TRADE_TYPE, CrossChainTradeType } from '../../models/cross-chain-trade-type'; import { getCrossChainGasData } from '../../utils/get-cross-chain-gas-data'; import { rubicProxyContractAddress } from '../common/constants/rubic-proxy-contract-address'; +import { evmCommonCrossChainAbi } from '../common/emv-cross-chain-trade/constants/evm-common-cross-chain-abi'; +import { gatewayRubicCrossChainAbi } from '../common/emv-cross-chain-trade/constants/gateway-rubic-cross-chain-abi'; import { EvmCrossChainTrade } from '../common/emv-cross-chain-trade/evm-cross-chain-trade'; import { GasData } from '../common/emv-cross-chain-trade/models/gas-data'; import { BRIDGE_TYPE, BridgeType } from '../common/models/bridge-type'; @@ -19,6 +21,7 @@ import { GetContractParamsOptions } from '../common/models/get-contract-params-o import { OnChainSubtype } from '../common/models/on-chain-subtype'; import { RubicStep } from '../common/models/rubicStep'; import { TradeInfo } from '../common/models/trade-info'; +import { ProxyCrossChainEvmTrade } from '../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade'; import { RouterCrossChainSupportedBlockchains } from './constants/router-cross-chain-supported-chains'; export class RouterCrossChainTrade extends EvmCrossChainTrade { @@ -75,7 +78,9 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { } protected get fromContractAddress(): string { - return this.isProxyTrade ? rubicProxyContractAddress[this.fromBlockchain].gateway : ' '; + return this.isProxyTrade + ? rubicProxyContractAddress[this.fromBlockchain].gateway + : this.routerQuoteConfig.allowanceTo; } protected get methodName(): string { @@ -105,12 +110,72 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { this.slippage = crossChainTrade.slippage; } - protected getContractParams( + protected async getContractParams( options: GetContractParamsOptions, skipAmountChangeCheck?: boolean | undefined ): Promise { - console.log(options, skipAmountChangeCheck); - return Promise.reject(new RubicSdkError('method not implemented')); + const { + data, + value: providerValue, + to, + gasPrice + } = await this.setTransactionConfig( + skipAmountChangeCheck || false, + options?.useCacheData || false, + options?.receiverAddress + ); + try { + const bridgeData = ProxyCrossChainEvmTrade.getBridgeData(options, { + walletAddress: this.walletAddress, + fromTokenAmount: this.from, + toTokenAmount: this.to, + srcChainTrade: null, + providerAddress: this.providerAddress, + type: `native:${this.type}`, + fromAddress: this.walletAddress + }); + const extraNativeFee = this.from.isNative + ? new BigNumber(providerValue).minus(this.from.stringWeiAmount).toFixed() + : new BigNumber(providerValue).toFixed(); + // const providerData = await ProxyCrossChainEvmTrade.getGenericProviderData( + // to!, + // data! as string, + // this.fromBlockchain as EvmBlockchainName, + // to, + // extraNativeFee + // ); + + const methodArguments = [ + bridgeData, + [to, this.routerQuoteConfig.allowanceTo, extraNativeFee, data] + ]; + + const value = this.getSwapValue(providerValue); + + const transactionConfiguration = EvmWeb3Pure.encodeMethodCall( + rubicProxyContractAddress[this.from.blockchain].router, + evmCommonCrossChainAbi, + this.methodName, + methodArguments, + value, + { + gasPrice: gasPrice + } + ); + const sendingToken = this.from.isNative ? [] : [this.from.address]; + const sendingAmount = this.from.isNative ? [] : [this.from.stringWeiAmount]; + + return { + contractAddress: rubicProxyContractAddress[this.from.blockchain].gateway, + contractAbi: gatewayRubicCrossChainAbi, + methodName: 'startViaRubic', + methodArguments: [sendingToken, sendingAmount, transactionConfiguration.data], + value + }; + } catch (err) { + console.log(err?.message); + throw new RubicSdkError(err?.message); + } } protected async getTransactionConfigAndAmount( From cd40b31269953e01e5b67b5747da1038c46ed765 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 19 Jul 2024 17:17:09 +0300 Subject: [PATCH 07/18] resolve conflicts --- .../constants/cross-chain-providers.ts | 1 + .../cross-chain-status-manager.ts | 17 +++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/features/cross-chain/calculation-manager/constants/cross-chain-providers.ts b/src/features/cross-chain/calculation-manager/constants/cross-chain-providers.ts index bbd43fc8bb6..ee859c5340f 100644 --- a/src/features/cross-chain/calculation-manager/constants/cross-chain-providers.ts +++ b/src/features/cross-chain/calculation-manager/constants/cross-chain-providers.ts @@ -17,6 +17,7 @@ import { OrbiterBridgeProvider } from '../providers/orbiter-bridge/orbiter-bridg import { OwlToBridgeProvider } from '../providers/owl-to-bridge/owl-to-bridge-provider'; import { RangoCrossChainProvider } from '../providers/rango-provider/rango-cross-chain-provider'; import { RouterCrossChainProvider } from '../providers/router-provider/router-cross-chain-provider'; +import { StargateV2CrossChainProvider } from '../providers/stargate-v2-provider/stargate-v2-cross-chain-provider'; // import { StargateCrossChainProvider } from '../providers/stargate-provider/stargate-cross-chain-provider'; import { TaikoBridgeProvider } from '../providers/taiko-bridge/taiko-bridge-provider'; diff --git a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts index d4d3c5dde2b..a7cb32f6d1c 100644 --- a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts +++ b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts @@ -88,6 +88,7 @@ export class CrossChainStatusManager { [CROSS_CHAIN_TRADE_TYPE.ARBITRUM]: this.getArbitrumBridgeDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.SQUIDROUTER]: this.getSquidrouterDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.SCROLL_BRIDGE]: this.getScrollBridgeDstSwapStatus, + [CROSS_CHAIN_TRADE_TYPE.STARGATE]: this.getLayerZeroDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.TAIKO_BRIDGE]: this.getTaikoBridgeDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.RANGO]: this.getRangoDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.PULSE_CHAIN_BRIDGE]: this.getPulseChainDstSwapStatus, @@ -97,6 +98,7 @@ export class CrossChainStatusManager { [CROSS_CHAIN_TRADE_TYPE.MESON]: this.getMesonDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.OWL_TO_BRIDGE]: this.getOwlToDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.EDDY_BRIDGE]: this.getEddyBridgeDstSwapStatus, + [CROSS_CHAIN_TRADE_TYPE.STARGATE_V2]: this.getLayerZeroDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.ROUTER]: this.getLayerZeroDstSwapStatus }; @@ -445,8 +447,7 @@ export class CrossChainStatusManager { private async getXyDstSwapStatus(data: CrossChainTradeData): Promise { try { const { success, tx } = await this.httpClient.get( - `${XY_API_ENDPOINT}/crossChainStatus?srcChainId=${ - blockchainId[data.fromBlockchain] + `${XY_API_ENDPOINT}/crossChainStatus?srcChainId=${blockchainId[data.fromBlockchain] }&srcTxHash=${data.srcTxHash}` ); @@ -495,13 +496,13 @@ export class CrossChainStatusManager { case TRANSFER_HISTORY_STATUS.TRANSFER_TO_BE_REFUNDED: return XFER_STATUS_CODE[swapData.refund_reason] === XFER_STATUS.OK_TO_RELAY ? { - status: TX_STATUS.PENDING, - hash: null - } + status: TX_STATUS.PENDING, + hash: null + } : { - status: TX_STATUS.REVERT, - hash: null - }; + status: TX_STATUS.REVERT, + hash: null + }; } } catch { return { status: TX_STATUS.PENDING, hash: null }; From f36fb448d7bc8a38b4733ac6ab6f92300d79a27a Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 22 Jul 2024 15:32:45 +0300 Subject: [PATCH 08/18] add converter for tron address, add router status method --- package.json | 2 +- .../constants/blockchain-id.ts | 4 +- .../models/router-send-transaction-params.ts | 5 ++ .../router/services/router-api-service.ts | 27 ++++++++- .../router-cross-chain-provider.ts | 58 +++++++++++++++--- .../router-cross-chain-trade.ts | 59 +++++++++++++------ .../cross-chain-status-manager.ts | 24 +++++--- 7 files changed, 142 insertions(+), 37 deletions(-) diff --git a/package.json b/package.json index 7af75de9125..a7b6e439920 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.32.1", + "version": "5.33.0-alpha-router.0", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/core/blockchain/utils/blockchains-info/constants/blockchain-id.ts b/src/core/blockchain/utils/blockchains-info/constants/blockchain-id.ts index 56a037c837c..d358cd1ca50 100644 --- a/src/core/blockchain/utils/blockchains-info/constants/blockchain-id.ts +++ b/src/core/blockchain/utils/blockchains-info/constants/blockchain-id.ts @@ -82,5 +82,7 @@ export const blockchainId: Record = { // Non EVN blockchains [BLOCKCHAIN_NAME.BITCOIN]: 5555, [BLOCKCHAIN_NAME.FILECOIN]: 314, - [BLOCKCHAIN_NAME.SOLANA]: 7565164 + [BLOCKCHAIN_NAME.SOLANA]: 7565164, + [BLOCKCHAIN_NAME.TRON]: 728126428, + [BLOCKCHAIN_NAME.DOGECOIN]: 2000 }; diff --git a/src/features/common/providers/router/models/router-send-transaction-params.ts b/src/features/common/providers/router/models/router-send-transaction-params.ts index 42a7049b47f..80fdaad059c 100644 --- a/src/features/common/providers/router/models/router-send-transaction-params.ts +++ b/src/features/common/providers/router/models/router-send-transaction-params.ts @@ -16,3 +16,8 @@ export interface RouterSendTransactionResponse extends RouterSendTransactionPara gasLimit: string; }; } + +export interface RouterTxStatusResponse { + status: 'completed' | 'pending'; + dest_tx_hash: string; +} diff --git a/src/features/common/providers/router/services/router-api-service.ts b/src/features/common/providers/router/services/router-api-service.ts index 6b7a0138691..ebf51591aff 100644 --- a/src/features/common/providers/router/services/router-api-service.ts +++ b/src/features/common/providers/router/services/router-api-service.ts @@ -1,10 +1,14 @@ +import { TX_STATUS } from 'src/core/blockchain/web3-public-service/web3-public/models/tx-status'; import { Injector } from 'src/core/injector/injector'; +import { TxStatusData } from 'src/features/common/status-manager/models/tx-status-data'; +import { CrossChainTradeData } from 'src/features/cross-chain/status-manager/models/cross-chain-trade-data'; import { RouterQuoteResponseConfig } from '../models/router-quote-response-config'; import { RouterQuoteSendParams } from '../models/router-quote-send-params'; import { RouterSendTransactionParams, - RouterSendTransactionResponse + RouterSendTransactionResponse, + RouterTxStatusResponse } from '../models/router-send-transaction-params'; export class RouterApiService { @@ -29,4 +33,25 @@ export class RouterApiService { params ); } + + public static async getTxStatus(data: CrossChainTradeData): Promise { + const txData = await Injector.httpClient.get( + `${this.ROUTER_ENDPOINT}/status`, + { + params: { + srcTxHash: data.srcTxHash + } + } + ); + if (txData.status === 'completed') { + return { + hash: txData.dest_tx_hash, + status: TX_STATUS.SUCCESS + }; + } + return { + hash: null, + status: TX_STATUS.PENDING + }; + } } diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts index 98edb0c3e37..8c9c7e8ae1d 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts @@ -1,9 +1,15 @@ import BigNumber from 'bignumber.js'; import { NotSupportedTokensError } from 'src/common/errors'; import { PriceToken, PriceTokenAmount, TokenAmount } from 'src/common/tokens'; -import { BlockchainName, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { + BLOCKCHAIN_NAME, + BlockchainName, + EvmBlockchainName +} from 'src/core/blockchain/models/blockchain-name'; import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; +import { TronWeb3Public } from 'src/core/blockchain/web3-public-service/web3-public/tron-web3-public/tron-web3-public'; import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; +import { Injector } from 'src/core/injector/injector'; import { RouterQuoteResponseConfig } from 'src/features/common/providers/router/models/router-quote-response-config'; import { RouterApiService } from 'src/features/common/providers/router/services/router-api-service'; import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; @@ -16,12 +22,19 @@ import { CalculationResult } from '../common/models/calculation-result'; import { FeeInfo } from '../common/models/fee-info'; import { RubicStep } from '../common/models/rubicStep'; import { ProxyCrossChainEvmTrade } from '../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade'; -import { routerCrossChainSupportedChains } from './constants/router-cross-chain-supported-chains'; +import { + RouterCrossChainSupportedBlockchains, + routerCrossChainSupportedChains +} from './constants/router-cross-chain-supported-chains'; import { RouterCrossChainTrade } from './router-cross-chain-trade'; export class RouterCrossChainProvider extends CrossChainProvider { public readonly type = CROSS_CHAIN_TRADE_TYPE.ROUTER; + private get tronWeb3Public(): TronWeb3Public { + return Injector.web3PublicService.getWeb3Public(BLOCKCHAIN_NAME.TRON); + } + public isSupportedBlockchain(fromBlockchain: BlockchainName): boolean { return routerCrossChainSupportedChains.some(chain => chain === fromBlockchain); } @@ -44,9 +57,29 @@ export class RouterCrossChainProvider extends CrossChainProvider { try { const srcChainId = blockchainId[from.blockchain]; const dstChainId = blockchainId[toToken.blockchain]; + const fromBlockchain = from.blockchain as RouterCrossChainSupportedBlockchains; + const toBlockchain = toToken.blockchain as RouterCrossChainSupportedBlockchains; + const NATIVE_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; - const srcTokenAddress = from.isNative ? NATIVE_TOKEN_ADDRESS : from.address; - const dstTokenAddress = toToken.isNative ? NATIVE_TOKEN_ADDRESS : toToken.address; + let srcTronAddress = ''; + let dstTronAddress = ''; + + if (fromBlockchain === BLOCKCHAIN_NAME.TRON) { + const srcTronHexAddress = await this.tronWeb3Public.convertTronAddressToHex( + from.address + ); + srcTronAddress = `0x${srcTronHexAddress.slice(2)}`; + } else if (toBlockchain === BLOCKCHAIN_NAME.TRON) { + const dstTronHexAddress = await this.tronWeb3Public.convertTronAddressToHex( + toToken.address + ); + dstTronAddress = `0x${dstTronHexAddress.slice(2)}`; + } + const srcTokenAddress = + fromBlockchain === BLOCKCHAIN_NAME.TRON ? srcTronAddress : from.address; + const dstTokenAddress = + toBlockchain === BLOCKCHAIN_NAME.TRON ? dstTronAddress : toToken.address; + const feeInfo = await this.getFeeInfo( from.blockchain, options.providerAddress, @@ -61,13 +94,14 @@ export class RouterCrossChainProvider extends CrossChainProvider { const routerQuoteConfig = await RouterApiService.getQuote({ amount: fromWithoutFee.stringWeiAmount, - fromTokenAddress: srcTokenAddress, + fromTokenAddress: from.isNative ? NATIVE_TOKEN_ADDRESS : srcTokenAddress, fromTokenChainId: srcChainId.toString(), - toTokenAddress: dstTokenAddress, + toTokenAddress: toToken.isNative ? NATIVE_TOKEN_ADDRESS : dstTokenAddress, toTokenChainId: dstChainId.toString(), slippageTolerance: options.slippageTolerance * 100 }); - const dstTokenAmount = routerQuoteConfig.destination.tokenAmount; + const dstTokenAmount = new BigNumber(routerQuoteConfig.destination.tokenAmount); + const to = new PriceTokenAmount({ ...toToken.asStruct, tokenAmount: Web3Pure.fromWei( @@ -78,6 +112,10 @@ export class RouterCrossChainProvider extends CrossChainProvider { const routePath = await this.getRoutePath(from, to, routerQuoteConfig); + const slippageAmount = dstTokenAmount.multipliedBy(options.slippageTolerance); + + const toTokenAmountMin = dstTokenAmount.minus(slippageAmount); + const gasData = options.gasCalculation === 'enabled' ? await RouterCrossChainTrade.getGasData( @@ -98,7 +136,11 @@ export class RouterCrossChainProvider extends CrossChainProvider { gasData, priceImpact: from.calculatePriceImpactPercent(to), routerQuoteConfig, - slippage: options.slippageTolerance + slippage: options.slippageTolerance, + toTokenAmountMin: Web3Pure.fromWei( + toTokenAmountMin, + routerQuoteConfig.destination.asset.decimals + ) }, options.providerAddress, routePath diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts index 4f52a05949d..b1acb4ba9e3 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -1,9 +1,11 @@ import BigNumber from 'bignumber.js'; import { RubicSdkError } from 'src/common/errors'; import { PriceTokenAmount } from 'src/common/tokens'; -import { EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { BLOCKCHAIN_NAME, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { TronWeb3Public } from 'src/core/blockchain/web3-public-service/web3-public/tron-web3-public/tron-web3-public'; import { EvmWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/evm-web3-pure'; import { EvmEncodeConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/models/evm-encode-config'; +import { Injector } from 'src/core/injector/injector'; import { ContractParams } from 'src/features/common/models/contract-params'; import { RouterQuoteResponseConfig } from 'src/features/common/providers/router/models/router-quote-response-config'; import { RouterApiService } from 'src/features/common/providers/router/services/router-api-service'; @@ -41,7 +43,8 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { gasData: null, priceImpact: 0, routerQuoteConfig, - slippage: 0 + slippage: 0, + toTokenAmountMin: new BigNumber(0) }, providerAddress || EvmWeb3Pure.EMPTY_ADDRESS, [] @@ -49,13 +52,17 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { return getCrossChainGasData(trade, receiverAddress); } + private get tronWeb3Public(): TronWeb3Public { + return Injector.web3PublicService.getWeb3Public(BLOCKCHAIN_NAME.TRON); + } + public readonly type: CrossChainTradeType = CROSS_CHAIN_TRADE_TYPE.ROUTER; public readonly to: PriceTokenAmount; public readonly from: PriceTokenAmount; - public readonly toTokenAmountMin: BigNumber = new BigNumber(0); + public readonly toTokenAmountMin: BigNumber; public readonly feeInfo: FeeInfo; @@ -96,6 +103,7 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { priceImpact: number | null; routerQuoteConfig: RouterQuoteResponseConfig; slippage: number; + toTokenAmountMin: BigNumber; }, providerAddress: string, routePath: RubicStep[] @@ -108,6 +116,7 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { this.priceImpact = crossChainTrade.priceImpact; this.routerQuoteConfig = crossChainTrade.routerQuoteConfig; this.slippage = crossChainTrade.slippage; + this.toTokenAmountMin = crossChainTrade.toTokenAmountMin; } protected async getContractParams( @@ -137,18 +146,15 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { const extraNativeFee = this.from.isNative ? new BigNumber(providerValue).minus(this.from.stringWeiAmount).toFixed() : new BigNumber(providerValue).toFixed(); - // const providerData = await ProxyCrossChainEvmTrade.getGenericProviderData( - // to!, - // data! as string, - // this.fromBlockchain as EvmBlockchainName, - // to, - // extraNativeFee - // ); - - const methodArguments = [ - bridgeData, - [to, this.routerQuoteConfig.allowanceTo, extraNativeFee, data] - ]; + const providerData = await ProxyCrossChainEvmTrade.getGenericProviderData( + to!, + data! as string, + this.fromBlockchain as EvmBlockchainName, + to, + extraNativeFee + ); + + const methodArguments = [bridgeData, providerData]; const value = this.getSwapValue(providerValue); @@ -181,11 +187,28 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { protected async getTransactionConfigAndAmount( receiverAddress?: string ): Promise<{ config: EvmEncodeConfig; amount: string }> { + let toAddress = receiverAddress; + let senderAddress = this.walletAddress; + + const toBlockchain = this.to.blockchain as RouterCrossChainSupportedBlockchains; + + if (toBlockchain === BLOCKCHAIN_NAME.TRON && receiverAddress) { + const toTronHexAddress = await this.tronWeb3Public.convertTronAddressToHex( + receiverAddress + ); + toAddress = `0x${toTronHexAddress.slice(2)}`; + } + if (this.fromBlockchain === BLOCKCHAIN_NAME.TRON) { + const senderTronHexAddress = await this.tronWeb3Public.convertTronAddressToHex( + this.walletAddress + ); + senderAddress = `0x${senderTronHexAddress.slice(2)}`; + } const { txn, destination } = await RouterApiService.getSwapTx({ ...this.routerQuoteConfig, - senderAddress: this.walletAddress, - receiverAddress: receiverAddress || this.walletAddress, - refundAddress: this.walletAddress + senderAddress, + receiverAddress: toAddress || this.walletAddress, + refundAddress: senderAddress }); if (!txn) { diff --git a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts index a7cb32f6d1c..062caaee814 100644 --- a/src/features/cross-chain/status-manager/cross-chain-status-manager.ts +++ b/src/features/cross-chain/status-manager/cross-chain-status-manager.ts @@ -21,6 +21,7 @@ import { Injector } from 'src/core/injector/injector'; import { DlnApiService } from 'src/features/common/providers/dln/dln-api-service'; import { RANGO_SWAP_STATUS } from 'src/features/common/providers/rango/models/rango-api-status-types'; import { RangoCommonParser } from 'src/features/common/providers/rango/services/rango-parser'; +import { RouterApiService } from 'src/features/common/providers/router/services/router-api-service'; import { XY_API_ENDPOINT } from 'src/features/common/providers/xy/constants/xy-api-params'; import { TxStatusData } from 'src/features/common/status-manager/models/tx-status-data'; import { getBridgersTradeStatus } from 'src/features/common/status-manager/utils/get-bridgers-trade-status'; @@ -99,7 +100,7 @@ export class CrossChainStatusManager { [CROSS_CHAIN_TRADE_TYPE.OWL_TO_BRIDGE]: this.getOwlToDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.EDDY_BRIDGE]: this.getEddyBridgeDstSwapStatus, [CROSS_CHAIN_TRADE_TYPE.STARGATE_V2]: this.getLayerZeroDstSwapStatus, - [CROSS_CHAIN_TRADE_TYPE.ROUTER]: this.getLayerZeroDstSwapStatus + [CROSS_CHAIN_TRADE_TYPE.ROUTER]: this.getRouterDstSwapStatus }; /** @@ -447,7 +448,8 @@ export class CrossChainStatusManager { private async getXyDstSwapStatus(data: CrossChainTradeData): Promise { try { const { success, tx } = await this.httpClient.get( - `${XY_API_ENDPOINT}/crossChainStatus?srcChainId=${blockchainId[data.fromBlockchain] + `${XY_API_ENDPOINT}/crossChainStatus?srcChainId=${ + blockchainId[data.fromBlockchain] }&srcTxHash=${data.srcTxHash}` ); @@ -496,13 +498,13 @@ export class CrossChainStatusManager { case TRANSFER_HISTORY_STATUS.TRANSFER_TO_BE_REFUNDED: return XFER_STATUS_CODE[swapData.refund_reason] === XFER_STATUS.OK_TO_RELAY ? { - status: TX_STATUS.PENDING, - hash: null - } + status: TX_STATUS.PENDING, + hash: null + } : { - status: TX_STATUS.REVERT, - hash: null - }; + status: TX_STATUS.REVERT, + hash: null + }; } } catch { return { status: TX_STATUS.PENDING, hash: null }; @@ -725,4 +727,10 @@ export class CrossChainStatusManager { return txStatusData; } + + private async getRouterDstSwapStatus(data: CrossChainTradeData): Promise { + const txStatusData = await RouterApiService.getTxStatus(data); + + return txStatusData; + } } From 5f01d6ad1fb8fab6a9c122aa36345edc88f093f4 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 22 Jul 2024 17:00:59 +0300 Subject: [PATCH 09/18] add router util service --- .../router-cross-chain-provider.ts | 51 ++++++------------- .../router-cross-chain-trade.ts | 40 ++++----------- .../router-cross-chain-util-service.ts.ts | 23 +++++++++ 3 files changed, 49 insertions(+), 65 deletions(-) create mode 100644 src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts index 8c9c7e8ae1d..4c7aaa0b183 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts @@ -7,9 +7,7 @@ import { EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; -import { TronWeb3Public } from 'src/core/blockchain/web3-public-service/web3-public/tron-web3-public/tron-web3-public'; import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; -import { Injector } from 'src/core/injector/injector'; import { RouterQuoteResponseConfig } from 'src/features/common/providers/router/models/router-quote-response-config'; import { RouterApiService } from 'src/features/common/providers/router/services/router-api-service'; import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; @@ -27,14 +25,11 @@ import { routerCrossChainSupportedChains } from './constants/router-cross-chain-supported-chains'; import { RouterCrossChainTrade } from './router-cross-chain-trade'; +import { RouterCrossChainUtilService } from './utils/router-cross-chain-util-service.ts'; export class RouterCrossChainProvider extends CrossChainProvider { public readonly type = CROSS_CHAIN_TRADE_TYPE.ROUTER; - private get tronWeb3Public(): TronWeb3Public { - return Injector.web3PublicService.getWeb3Public(BLOCKCHAIN_NAME.TRON); - } - public isSupportedBlockchain(fromBlockchain: BlockchainName): boolean { return routerCrossChainSupportedChains.some(chain => chain === fromBlockchain); } @@ -44,7 +39,13 @@ export class RouterCrossChainProvider extends CrossChainProvider { toToken: PriceToken, options: RequiredCrossChainOptions ): Promise { - if (!this.areSupportedBlockchains(from.blockchain, toToken.blockchain)) { + const fromBlockchain = from.blockchain as RouterCrossChainSupportedBlockchains; + const toBlockchain = toToken.blockchain as RouterCrossChainSupportedBlockchains; + if ( + !this.areSupportedBlockchains(from.blockchain, toToken.blockchain) || + fromBlockchain === BLOCKCHAIN_NAME.TRON || + fromBlockchain === BLOCKCHAIN_NAME.DOGECOIN + ) { return { trade: null, error: new NotSupportedTokensError(), @@ -57,28 +58,14 @@ export class RouterCrossChainProvider extends CrossChainProvider { try { const srcChainId = blockchainId[from.blockchain]; const dstChainId = blockchainId[toToken.blockchain]; - const fromBlockchain = from.blockchain as RouterCrossChainSupportedBlockchains; - const toBlockchain = toToken.blockchain as RouterCrossChainSupportedBlockchains; const NATIVE_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; - let srcTronAddress = ''; - let dstTronAddress = ''; - - if (fromBlockchain === BLOCKCHAIN_NAME.TRON) { - const srcTronHexAddress = await this.tronWeb3Public.convertTronAddressToHex( - from.address - ); - srcTronAddress = `0x${srcTronHexAddress.slice(2)}`; - } else if (toBlockchain === BLOCKCHAIN_NAME.TRON) { - const dstTronHexAddress = await this.tronWeb3Public.convertTronAddressToHex( - toToken.address - ); - dstTronAddress = `0x${dstTronHexAddress.slice(2)}`; - } - const srcTokenAddress = - fromBlockchain === BLOCKCHAIN_NAME.TRON ? srcTronAddress : from.address; - const dstTokenAddress = - toBlockchain === BLOCKCHAIN_NAME.TRON ? dstTronAddress : toToken.address; + + const srcTokenAddress = from.address; + const dstTokenAddress = await RouterCrossChainUtilService.checkAndConvertAddress( + toBlockchain, + toToken.address + ); const feeInfo = await this.getFeeInfo( from.blockchain, @@ -112,10 +99,6 @@ export class RouterCrossChainProvider extends CrossChainProvider { const routePath = await this.getRoutePath(from, to, routerQuoteConfig); - const slippageAmount = dstTokenAmount.multipliedBy(options.slippageTolerance); - - const toTokenAmountMin = dstTokenAmount.minus(slippageAmount); - const gasData = options.gasCalculation === 'enabled' ? await RouterCrossChainTrade.getGasData( @@ -136,11 +119,7 @@ export class RouterCrossChainProvider extends CrossChainProvider { gasData, priceImpact: from.calculatePriceImpactPercent(to), routerQuoteConfig, - slippage: options.slippageTolerance, - toTokenAmountMin: Web3Pure.fromWei( - toTokenAmountMin, - routerQuoteConfig.destination.asset.decimals - ) + slippage: options.slippageTolerance }, options.providerAddress, routePath diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts index b1acb4ba9e3..8b86b0b03da 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -1,11 +1,9 @@ import BigNumber from 'bignumber.js'; import { RubicSdkError } from 'src/common/errors'; import { PriceTokenAmount } from 'src/common/tokens'; -import { BLOCKCHAIN_NAME, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; -import { TronWeb3Public } from 'src/core/blockchain/web3-public-service/web3-public/tron-web3-public/tron-web3-public'; +import { EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; import { EvmWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/evm-web3-pure'; import { EvmEncodeConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/models/evm-encode-config'; -import { Injector } from 'src/core/injector/injector'; import { ContractParams } from 'src/features/common/models/contract-params'; import { RouterQuoteResponseConfig } from 'src/features/common/providers/router/models/router-quote-response-config'; import { RouterApiService } from 'src/features/common/providers/router/services/router-api-service'; @@ -25,6 +23,7 @@ import { RubicStep } from '../common/models/rubicStep'; import { TradeInfo } from '../common/models/trade-info'; import { ProxyCrossChainEvmTrade } from '../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade'; import { RouterCrossChainSupportedBlockchains } from './constants/router-cross-chain-supported-chains'; +import { RouterCrossChainUtilService } from './utils/router-cross-chain-util-service.ts'; export class RouterCrossChainTrade extends EvmCrossChainTrade { public static async getGasData( @@ -43,8 +42,7 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { gasData: null, priceImpact: 0, routerQuoteConfig, - slippage: 0, - toTokenAmountMin: new BigNumber(0) + slippage: 0 }, providerAddress || EvmWeb3Pure.EMPTY_ADDRESS, [] @@ -52,10 +50,6 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { return getCrossChainGasData(trade, receiverAddress); } - private get tronWeb3Public(): TronWeb3Public { - return Injector.web3PublicService.getWeb3Public(BLOCKCHAIN_NAME.TRON); - } - public readonly type: CrossChainTradeType = CROSS_CHAIN_TRADE_TYPE.ROUTER; public readonly to: PriceTokenAmount; @@ -103,7 +97,6 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { priceImpact: number | null; routerQuoteConfig: RouterQuoteResponseConfig; slippage: number; - toTokenAmountMin: BigNumber; }, providerAddress: string, routePath: RubicStep[] @@ -116,7 +109,7 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { this.priceImpact = crossChainTrade.priceImpact; this.routerQuoteConfig = crossChainTrade.routerQuoteConfig; this.slippage = crossChainTrade.slippage; - this.toTokenAmountMin = crossChainTrade.toTokenAmountMin; + this.toTokenAmountMin = this.to.tokenAmount.multipliedBy(1 - this.slippage); } protected async getContractParams( @@ -187,28 +180,17 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { protected async getTransactionConfigAndAmount( receiverAddress?: string ): Promise<{ config: EvmEncodeConfig; amount: string }> { - let toAddress = receiverAddress; - let senderAddress = this.walletAddress; - const toBlockchain = this.to.blockchain as RouterCrossChainSupportedBlockchains; - if (toBlockchain === BLOCKCHAIN_NAME.TRON && receiverAddress) { - const toTronHexAddress = await this.tronWeb3Public.convertTronAddressToHex( - receiverAddress - ); - toAddress = `0x${toTronHexAddress.slice(2)}`; - } - if (this.fromBlockchain === BLOCKCHAIN_NAME.TRON) { - const senderTronHexAddress = await this.tronWeb3Public.convertTronAddressToHex( - this.walletAddress - ); - senderAddress = `0x${senderTronHexAddress.slice(2)}`; - } + const toAddress = await RouterCrossChainUtilService.checkAndConvertAddress( + toBlockchain, + receiverAddress || this.walletAddress + ); const { txn, destination } = await RouterApiService.getSwapTx({ ...this.routerQuoteConfig, - senderAddress, - receiverAddress: toAddress || this.walletAddress, - refundAddress: senderAddress + senderAddress: this.walletAddress, + receiverAddress: toAddress, + refundAddress: this.walletAddress }); if (!txn) { diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts new file mode 100644 index 00000000000..f72719f79bd --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts @@ -0,0 +1,23 @@ +import { BLOCKCHAIN_NAME } from 'src/core/blockchain/models/blockchain-name'; +import { TronWeb3Public } from 'src/core/blockchain/web3-public-service/web3-public/tron-web3-public/tron-web3-public'; +import { Injector } from 'src/core/injector/injector'; + +import { RouterCrossChainSupportedBlockchains } from '../constants/router-cross-chain-supported-chains'; + +export class RouterCrossChainUtilService { + private static get tronWeb3Public(): TronWeb3Public { + return Injector.web3PublicService.getWeb3Public(BLOCKCHAIN_NAME.TRON); + } + + public static async checkAndConvertAddress( + blockchain: RouterCrossChainSupportedBlockchains, + address: string + ): Promise { + if (blockchain === BLOCKCHAIN_NAME.TRON) { + const tronHexAddress = await this.tronWeb3Public.convertTronAddressToHex(address); + return `0x${tronHexAddress.slice(2)}`; + } + + return address; + } +} From 81adb8eca691a843a506b3af8504a764f058e99a Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 22 Jul 2024 17:43:35 +0300 Subject: [PATCH 10/18] minor fix --- .../router-cross-chain-provider.ts | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts index 4c7aaa0b183..535a564f8cf 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts @@ -6,6 +6,7 @@ import { BlockchainName, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { BlockchainsInfo } from 'src/core/blockchain/utils/blockchains-info/blockchains-info'; import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; import { RouterQuoteResponseConfig } from 'src/features/common/providers/router/models/router-quote-response-config'; @@ -26,7 +27,7 @@ import { } from './constants/router-cross-chain-supported-chains'; import { RouterCrossChainTrade } from './router-cross-chain-trade'; import { RouterCrossChainUtilService } from './utils/router-cross-chain-util-service.ts'; - +import { CHAIN_TYPE } from 'src/core/blockchain/models/chain-type' export class RouterCrossChainProvider extends CrossChainProvider { public readonly type = CROSS_CHAIN_TRADE_TYPE.ROUTER; @@ -43,8 +44,7 @@ export class RouterCrossChainProvider extends CrossChainProvider { const toBlockchain = toToken.blockchain as RouterCrossChainSupportedBlockchains; if ( !this.areSupportedBlockchains(from.blockchain, toToken.blockchain) || - fromBlockchain === BLOCKCHAIN_NAME.TRON || - fromBlockchain === BLOCKCHAIN_NAME.DOGECOIN + BlockchainsInfo.getChainType(fromBlockchain) !== CHAIN_TYPE.EVM ) { return { trade: null, @@ -102,13 +102,13 @@ export class RouterCrossChainProvider extends CrossChainProvider { const gasData = options.gasCalculation === 'enabled' ? await RouterCrossChainTrade.getGasData( - from, - to, - feeInfo, - options.providerAddress, - routerQuoteConfig, - options?.receiverAddress - ) + from, + to, + feeInfo, + options.providerAddress, + routerQuoteConfig, + options?.receiverAddress + ) : null; return { trade: new RouterCrossChainTrade( @@ -154,29 +154,29 @@ export class RouterCrossChainProvider extends CrossChainProvider { } const transitFromAddress = fromToken.address.toLowerCase() !== - routerSrcAsset.stableReserveAsset.address.toLowerCase() + routerSrcAsset.stableReserveAsset.address.toLowerCase() ? routerSrcAsset.stableReserveAsset.address : null; const transitToAddress = toToken.address.toLowerCase() !== - routerDstAsset.stableReserveAsset.address.toLowerCase() + routerDstAsset.stableReserveAsset.address.toLowerCase() ? routerDstAsset.stableReserveAsset.address : null; const fromTransitToken = transitFromAddress ? await TokenAmount.createToken({ - blockchain: fromToken.blockchain, - address: transitFromAddress, - weiAmount: new BigNumber(routerSrcAsset.stableReserveAmount) - }) + blockchain: fromToken.blockchain, + address: transitFromAddress, + weiAmount: new BigNumber(routerSrcAsset.stableReserveAmount) + }) : fromToken; const toTransitToken = transitToAddress ? await TokenAmount.createToken({ - blockchain: toToken.blockchain, - address: transitToAddress, - weiAmount: new BigNumber(routerDstAsset.stableReserveAmount) - }) + blockchain: toToken.blockchain, + address: transitToAddress, + weiAmount: new BigNumber(routerDstAsset.stableReserveAmount) + }) : toToken; const routePath: RubicStep[] = []; From 45fc744d52a3d79f84ddc0d7575ffeed839e9d1d Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 24 Jul 2024 12:25:47 +0300 Subject: [PATCH 11/18] add solana network --- package.json | 2 +- .../router-cross-chain-supported-chains.ts | 3 +- .../router-cross-chain-provider.ts | 43 ++++++++++--------- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index a7b6e439920..0fb20f315f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.33.0-alpha-router.0", + "version": "5.33.0-alpha-router.1", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts index d43cbaa1ecf..2b0f7394470 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts @@ -25,7 +25,8 @@ export const routerCrossChainSupportedChains = [ BLOCKCHAIN_NAME.TAIKO, BLOCKCHAIN_NAME.SCROLL, BLOCKCHAIN_NAME.TRON, - BLOCKCHAIN_NAME.AURORA + BLOCKCHAIN_NAME.AURORA, + BLOCKCHAIN_NAME.SOLANA ]; export type RouterCrossChainSupportedBlockchains = (typeof routerCrossChainSupportedChains)[number]; diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts index 535a564f8cf..171f5075aaf 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts @@ -6,6 +6,7 @@ import { BlockchainName, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { CHAIN_TYPE } from 'src/core/blockchain/models/chain-type'; import { BlockchainsInfo } from 'src/core/blockchain/utils/blockchains-info/blockchains-info'; import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; @@ -27,7 +28,6 @@ import { } from './constants/router-cross-chain-supported-chains'; import { RouterCrossChainTrade } from './router-cross-chain-trade'; import { RouterCrossChainUtilService } from './utils/router-cross-chain-util-service.ts'; -import { CHAIN_TYPE } from 'src/core/blockchain/models/chain-type' export class RouterCrossChainProvider extends CrossChainProvider { public readonly type = CROSS_CHAIN_TRADE_TYPE.ROUTER; @@ -53,11 +53,14 @@ export class RouterCrossChainProvider extends CrossChainProvider { }; } - const useProxy = false; + const useProxy = options?.useProxy?.[this.type] ?? true; try { const srcChainId = blockchainId[from.blockchain]; - const dstChainId = blockchainId[toToken.blockchain]; + const dstChainId = + toBlockchain === BLOCKCHAIN_NAME.SOLANA + ? 'solana' + : blockchainId[toToken.blockchain]; const NATIVE_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; @@ -102,13 +105,13 @@ export class RouterCrossChainProvider extends CrossChainProvider { const gasData = options.gasCalculation === 'enabled' ? await RouterCrossChainTrade.getGasData( - from, - to, - feeInfo, - options.providerAddress, - routerQuoteConfig, - options?.receiverAddress - ) + from, + to, + feeInfo, + options.providerAddress, + routerQuoteConfig, + options?.receiverAddress + ) : null; return { trade: new RouterCrossChainTrade( @@ -154,29 +157,29 @@ export class RouterCrossChainProvider extends CrossChainProvider { } const transitFromAddress = fromToken.address.toLowerCase() !== - routerSrcAsset.stableReserveAsset.address.toLowerCase() + routerSrcAsset.stableReserveAsset.address.toLowerCase() ? routerSrcAsset.stableReserveAsset.address : null; const transitToAddress = toToken.address.toLowerCase() !== - routerDstAsset.stableReserveAsset.address.toLowerCase() + routerDstAsset.stableReserveAsset.address.toLowerCase() ? routerDstAsset.stableReserveAsset.address : null; const fromTransitToken = transitFromAddress ? await TokenAmount.createToken({ - blockchain: fromToken.blockchain, - address: transitFromAddress, - weiAmount: new BigNumber(routerSrcAsset.stableReserveAmount) - }) + blockchain: fromToken.blockchain, + address: transitFromAddress, + weiAmount: new BigNumber(routerSrcAsset.stableReserveAmount) + }) : fromToken; const toTransitToken = transitToAddress ? await TokenAmount.createToken({ - blockchain: toToken.blockchain, - address: transitToAddress, - weiAmount: new BigNumber(routerDstAsset.stableReserveAmount) - }) + blockchain: toToken.blockchain, + address: transitToAddress, + weiAmount: new BigNumber(routerDstAsset.stableReserveAmount) + }) : toToken; const routePath: RubicStep[] = []; From 455cd30ccfe6d0300ebf413de8fd69702d8336c4 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 31 Jul 2024 12:55:17 +0300 Subject: [PATCH 12/18] fix issues --- package.json | 2 +- .../constants/blockchain-id.ts | 1 - .../router-cross-chain-supported-chains.ts | 2 -- .../router-cross-chain-provider.ts | 18 +++++------------- .../router-cross-chain-util-service.ts.ts | 14 +++++++++++++- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 0fb20f315f0..87215fb8d61 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.33.0-alpha-router.1", + "version": "5.33.0-alpha-router.2", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/core/blockchain/utils/blockchains-info/constants/blockchain-id.ts b/src/core/blockchain/utils/blockchains-info/constants/blockchain-id.ts index d358cd1ca50..da2db0c795d 100644 --- a/src/core/blockchain/utils/blockchains-info/constants/blockchain-id.ts +++ b/src/core/blockchain/utils/blockchains-info/constants/blockchain-id.ts @@ -83,6 +83,5 @@ export const blockchainId: Record = { [BLOCKCHAIN_NAME.BITCOIN]: 5555, [BLOCKCHAIN_NAME.FILECOIN]: 314, [BLOCKCHAIN_NAME.SOLANA]: 7565164, - [BLOCKCHAIN_NAME.TRON]: 728126428, [BLOCKCHAIN_NAME.DOGECOIN]: 2000 }; diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts index 2b0f7394470..1f28006e67a 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts @@ -13,10 +13,8 @@ export const routerCrossChainSupportedChains = [ BLOCKCHAIN_NAME.ZK_SYNC, BLOCKCHAIN_NAME.METIS, BLOCKCHAIN_NAME.POLYGON_ZKEVM, - BLOCKCHAIN_NAME.DOGECOIN, BLOCKCHAIN_NAME.MANTLE, BLOCKCHAIN_NAME.BASE, - BLOCKCHAIN_NAME.OASIS, BLOCKCHAIN_NAME.MODE, BLOCKCHAIN_NAME.ARBITRUM, BLOCKCHAIN_NAME.AVALANCHE, diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts index 171f5075aaf..7f057f49101 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts @@ -1,14 +1,9 @@ import BigNumber from 'bignumber.js'; import { NotSupportedTokensError } from 'src/common/errors'; import { PriceToken, PriceTokenAmount, TokenAmount } from 'src/common/tokens'; -import { - BLOCKCHAIN_NAME, - BlockchainName, - EvmBlockchainName -} from 'src/core/blockchain/models/blockchain-name'; +import { BlockchainName, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; import { CHAIN_TYPE } from 'src/core/blockchain/models/chain-type'; import { BlockchainsInfo } from 'src/core/blockchain/utils/blockchains-info/blockchains-info'; -import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; import { RouterQuoteResponseConfig } from 'src/features/common/providers/router/models/router-quote-response-config'; import { RouterApiService } from 'src/features/common/providers/router/services/router-api-service'; @@ -56,11 +51,8 @@ export class RouterCrossChainProvider extends CrossChainProvider { const useProxy = options?.useProxy?.[this.type] ?? true; try { - const srcChainId = blockchainId[from.blockchain]; - const dstChainId = - toBlockchain === BLOCKCHAIN_NAME.SOLANA - ? 'solana' - : blockchainId[toToken.blockchain]; + const srcChainId = RouterCrossChainUtilService.getBlockchainId(fromBlockchain); + const dstChainId = RouterCrossChainUtilService.getBlockchainId(toBlockchain); const NATIVE_TOKEN_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; @@ -85,9 +77,9 @@ export class RouterCrossChainProvider extends CrossChainProvider { const routerQuoteConfig = await RouterApiService.getQuote({ amount: fromWithoutFee.stringWeiAmount, fromTokenAddress: from.isNative ? NATIVE_TOKEN_ADDRESS : srcTokenAddress, - fromTokenChainId: srcChainId.toString(), + fromTokenChainId: srcChainId, toTokenAddress: toToken.isNative ? NATIVE_TOKEN_ADDRESS : dstTokenAddress, - toTokenChainId: dstChainId.toString(), + toTokenChainId: dstChainId, slippageTolerance: options.slippageTolerance * 100 }); const dstTokenAmount = new BigNumber(routerQuoteConfig.destination.tokenAmount); diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts index f72719f79bd..767476f8d60 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts @@ -1,4 +1,5 @@ -import { BLOCKCHAIN_NAME } from 'src/core/blockchain/models/blockchain-name'; +import { BLOCKCHAIN_NAME, BlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; import { TronWeb3Public } from 'src/core/blockchain/web3-public-service/web3-public/tron-web3-public/tron-web3-public'; import { Injector } from 'src/core/injector/injector'; @@ -20,4 +21,15 @@ export class RouterCrossChainUtilService { return address; } + + public static getBlockchainId(blockchain: BlockchainName): string { + if (blockchain === BLOCKCHAIN_NAME.TRON) { + return '728126428'; + } + if (blockchain === BLOCKCHAIN_NAME.SOLANA) { + return 'solana'; + } + + return blockchainId[blockchain].toString(); + } } From c2d15ecb661b436a7f9f2e8642675e3ad9e94081 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 2 Aug 2024 15:24:08 +0300 Subject: [PATCH 13/18] fix receiver address for tron/solana --- package.json | 2 +- .../router/services/router-api-service.ts | 2 +- .../providers/common/cross-chain-trade.ts | 2 +- .../router-cross-chain-trade.ts | 20 +++++++++++++++++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 87215fb8d61..28a99f484b7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.33.0-alpha-router.2", + "version": "5.33.0-alpha-router.5", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/common/providers/router/services/router-api-service.ts b/src/features/common/providers/router/services/router-api-service.ts index ebf51591aff..2a90f61de78 100644 --- a/src/features/common/providers/router/services/router-api-service.ts +++ b/src/features/common/providers/router/services/router-api-service.ts @@ -15,7 +15,7 @@ export class RouterApiService { private static readonly ROUTER_ENDPOINT = 'https://api-beta.pathfinder.routerprotocol.com/api/v2'; - private static readonly partnerId = 0; + private static readonly partnerId = 1; public static async getQuote( params: RouterQuoteSendParams diff --git a/src/features/cross-chain/calculation-manager/providers/common/cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/common/cross-chain-trade.ts index f3069dee3aa..d10617d7676 100644 --- a/src/features/cross-chain/calculation-manager/providers/common/cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/common/cross-chain-trade.ts @@ -123,7 +123,7 @@ export abstract class CrossChainTrade { protected checkAmountChange(newWeiAmount: string, oldWeiAmount: string): void { const oldAmount = new BigNumber(oldWeiAmount); const newAmount = new BigNumber(newWeiAmount); - const changePercent = 0.5; + const changePercent = 0.01; const acceptablePercentPriceChange = new BigNumber(changePercent).dividedBy(100); const amountPlusPercent = oldAmount.multipliedBy(acceptablePercentPriceChange.plus(1)); diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts index 8b86b0b03da..c626efe6fd3 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -24,6 +24,7 @@ import { TradeInfo } from '../common/models/trade-info'; import { ProxyCrossChainEvmTrade } from '../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade'; import { RouterCrossChainSupportedBlockchains } from './constants/router-cross-chain-supported-chains'; import { RouterCrossChainUtilService } from './utils/router-cross-chain-util-service.ts'; +import { BlockchainsInfo } from 'src/core/blockchain/utils/blockchains-info/blockchains-info'; export class RouterCrossChainTrade extends EvmCrossChainTrade { public static async getGasData( @@ -127,14 +128,29 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { options?.receiverAddress ); try { - const bridgeData = ProxyCrossChainEvmTrade.getBridgeData(options, { + + const isEvmDestination = BlockchainsInfo.isEvmBlockchainName(this.to.blockchain); + const receivingAsset = isEvmDestination ? this.to.address : this.from.address; + const toBlockchain = this.to.blockchain as RouterCrossChainSupportedBlockchains; + const receiverAddress = + await RouterCrossChainUtilService.checkAndConvertAddress( + toBlockchain, + options.receiverAddress || this.walletAddress + ); + const bridgeData = ProxyCrossChainEvmTrade.getBridgeData( + { + ...options, + receiverAddress + }, + { walletAddress: this.walletAddress, fromTokenAmount: this.from, toTokenAmount: this.to, srcChainTrade: null, providerAddress: this.providerAddress, type: `native:${this.type}`, - fromAddress: this.walletAddress + fromAddress: this.walletAddress, + toAddress: receivingAsset }); const extraNativeFee = this.from.isNative ? new BigNumber(providerValue).minus(this.from.stringWeiAmount).toFixed() From f48d6be03db4f18c067e134d7b3e1a3f33f54896 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 6 Aug 2024 17:22:30 +0300 Subject: [PATCH 14/18] add ata address check --- package.json | 3 +- .../solana-web3-public/solana-web3-public.ts | 24 +++ .../providers/common/cross-chain-trade.ts | 2 +- .../router-cross-chain-provider.ts | 13 +- .../router-cross-chain-trade.ts | 30 ++-- .../router-cross-chain-util-service.ts.ts | 25 ++- yarn.lock | 160 ++++++++++++++++++ 7 files changed, 238 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index 28a99f484b7..e72316d9ee9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.33.0-alpha-router.5", + "version": "5.33.0-alpha-router.6", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -79,6 +79,7 @@ "@pancakeswap/smart-router": "4.2.1", "@pancakeswap/swap-sdk-core": "^1.0.0", "@pancakeswap/tokens": "0.1.6", + "@solana/spl-token": "^0.4.8", "@solana/web3.js": "^1.89.1", "@solflare-wallet/utl-sdk": "^1.4.0", "@viaprotocol/router-sdk": "^1.0.7", diff --git a/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public.ts b/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public.ts index c94d8080696..427aceee213 100644 --- a/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public.ts +++ b/src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public.ts @@ -1,3 +1,8 @@ +import { + ASSOCIATED_TOKEN_PROGRAM_ID, + getAssociatedTokenAddress, + TOKEN_PROGRAM_ID +} from '@solana/spl-token'; import { BlockhashWithExpiryBlockHeight, Connection, PublicKey } from '@solana/web3.js'; import { Client as TokenSdk } from '@solflare-wallet/utl-sdk'; import BigNumber from 'bignumber.js'; @@ -199,4 +204,23 @@ export class SolanaWeb3Public extends Web3Public { public async getRecentBlockhash(): Promise { return this.connection.getLatestBlockhash(); } + + public async getAtaAddress( + walletAddress: string, + tokenAddress: string + ): Promise { + const tokenKey = new PublicKey(tokenAddress); + const walletKey = new PublicKey(walletAddress); + const ataAddress = await getAssociatedTokenAddress( + tokenKey, + walletKey, + false, + TOKEN_PROGRAM_ID, + ASSOCIATED_TOKEN_PROGRAM_ID + ); + + const accountInfo = await this.connection.getAccountInfo(ataAddress); + + return accountInfo ? ataAddress.toString() : null; + } } diff --git a/src/features/cross-chain/calculation-manager/providers/common/cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/common/cross-chain-trade.ts index d10617d7676..62f3fe22a64 100644 --- a/src/features/cross-chain/calculation-manager/providers/common/cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/common/cross-chain-trade.ts @@ -123,7 +123,7 @@ export abstract class CrossChainTrade { protected checkAmountChange(newWeiAmount: string, oldWeiAmount: string): void { const oldAmount = new BigNumber(oldWeiAmount); const newAmount = new BigNumber(newWeiAmount); - const changePercent = 0.01; + const changePercent = 0.0001; const acceptablePercentPriceChange = new BigNumber(changePercent).dividedBy(100); const amountPlusPercent = oldAmount.multipliedBy(acceptablePercentPriceChange.plus(1)); diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts index 7f057f49101..c3341db1906 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts @@ -1,7 +1,11 @@ import BigNumber from 'bignumber.js'; import { NotSupportedTokensError } from 'src/common/errors'; import { PriceToken, PriceTokenAmount, TokenAmount } from 'src/common/tokens'; -import { BlockchainName, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { + BLOCKCHAIN_NAME, + BlockchainName, + EvmBlockchainName +} from 'src/core/blockchain/models/blockchain-name'; import { CHAIN_TYPE } from 'src/core/blockchain/models/chain-type'; import { BlockchainsInfo } from 'src/core/blockchain/utils/blockchains-info/blockchains-info'; import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; @@ -51,6 +55,13 @@ export class RouterCrossChainProvider extends CrossChainProvider { const useProxy = options?.useProxy?.[this.type] ?? true; try { + if (toBlockchain === BLOCKCHAIN_NAME.SOLANA && options.receiverAddress) { + await RouterCrossChainUtilService.checkAtaAddress( + options.receiverAddress, + toToken.address + ); + } + const srcChainId = RouterCrossChainUtilService.getBlockchainId(fromBlockchain); const dstChainId = RouterCrossChainUtilService.getBlockchainId(toBlockchain); diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts index c626efe6fd3..54499280c45 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -2,6 +2,7 @@ import BigNumber from 'bignumber.js'; import { RubicSdkError } from 'src/common/errors'; import { PriceTokenAmount } from 'src/common/tokens'; import { EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { BlockchainsInfo } from 'src/core/blockchain/utils/blockchains-info/blockchains-info'; import { EvmWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/evm-web3-pure'; import { EvmEncodeConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/models/evm-encode-config'; import { ContractParams } from 'src/features/common/models/contract-params'; @@ -24,7 +25,6 @@ import { TradeInfo } from '../common/models/trade-info'; import { ProxyCrossChainEvmTrade } from '../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade'; import { RouterCrossChainSupportedBlockchains } from './constants/router-cross-chain-supported-chains'; import { RouterCrossChainUtilService } from './utils/router-cross-chain-util-service.ts'; -import { BlockchainsInfo } from 'src/core/blockchain/utils/blockchains-info/blockchains-info'; export class RouterCrossChainTrade extends EvmCrossChainTrade { public static async getGasData( @@ -128,30 +128,29 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { options?.receiverAddress ); try { - const isEvmDestination = BlockchainsInfo.isEvmBlockchainName(this.to.blockchain); const receivingAsset = isEvmDestination ? this.to.address : this.from.address; const toBlockchain = this.to.blockchain as RouterCrossChainSupportedBlockchains; - const receiverAddress = - await RouterCrossChainUtilService.checkAndConvertAddress( - toBlockchain, - options.receiverAddress || this.walletAddress - ); + const receiverAddress = await RouterCrossChainUtilService.checkAndConvertAddress( + toBlockchain, + options.receiverAddress || this.walletAddress + ); const bridgeData = ProxyCrossChainEvmTrade.getBridgeData( { ...options, receiverAddress }, { - walletAddress: this.walletAddress, - fromTokenAmount: this.from, - toTokenAmount: this.to, - srcChainTrade: null, - providerAddress: this.providerAddress, - type: `native:${this.type}`, + walletAddress: this.walletAddress, + fromTokenAmount: this.from, + toTokenAmount: this.to, + srcChainTrade: null, + providerAddress: this.providerAddress, + type: `native:${this.type}`, fromAddress: this.walletAddress, toAddress: receivingAsset - }); + } + ); const extraNativeFee = this.from.isNative ? new BigNumber(providerValue).minus(this.from.stringWeiAmount).toFixed() : new BigNumber(providerValue).toFixed(); @@ -200,7 +199,8 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { const toAddress = await RouterCrossChainUtilService.checkAndConvertAddress( toBlockchain, - receiverAddress || this.walletAddress + receiverAddress || this.walletAddress, + this.to.address ); const { txn, destination } = await RouterApiService.getSwapTx({ ...this.routerQuoteConfig, diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts index 767476f8d60..769938dc361 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts @@ -1,5 +1,7 @@ +import { RubicSdkError } from 'src/common/errors'; import { BLOCKCHAIN_NAME, BlockchainName } from 'src/core/blockchain/models/blockchain-name'; import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; +import { SolanaWeb3Public } from 'src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public'; import { TronWeb3Public } from 'src/core/blockchain/web3-public-service/web3-public/tron-web3-public/tron-web3-public'; import { Injector } from 'src/core/injector/injector'; @@ -10,18 +12,39 @@ export class RouterCrossChainUtilService { return Injector.web3PublicService.getWeb3Public(BLOCKCHAIN_NAME.TRON); } + private static get solanaWeb3Public(): SolanaWeb3Public { + return Injector.web3PublicService.getWeb3Public(BLOCKCHAIN_NAME.SOLANA); + } + public static async checkAndConvertAddress( blockchain: RouterCrossChainSupportedBlockchains, - address: string + address: string, + tokenAddress?: string ): Promise { if (blockchain === BLOCKCHAIN_NAME.TRON) { const tronHexAddress = await this.tronWeb3Public.convertTronAddressToHex(address); return `0x${tronHexAddress.slice(2)}`; } + if (blockchain === BLOCKCHAIN_NAME.SOLANA && tokenAddress) { + const ataAddress = await this.solanaWeb3Public.getAtaAddress(address, tokenAddress); + return ataAddress!; + } + return address; } + public static async checkAtaAddress( + walletAddress: string, + tokenAddress: string + ): Promise { + const ataAddress = await this.solanaWeb3Public.getAtaAddress(walletAddress, tokenAddress); + + if (!ataAddress) { + throw new RubicSdkError('It is necessary to have an ATA address'); + } + } + public static getBlockchainId(blockchain: BlockchainName): string { if (blockchain === BLOCKCHAIN_NAME.TRON) { return '728126428'; diff --git a/yarn.lock b/yarn.lock index 1cd06d8de86..9783e00c92e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2589,6 +2589,20 @@ resolved "https://registry.yarnpkg.com/@solana/codecs-core/-/codecs-core-2.0.0-experimental.8618508.tgz#4f6709dd50e671267f3bea7d09209bc6471b7ad0" integrity sha512-JCz7mKjVKtfZxkuDtwMAUgA7YvJcA2BwpZaA1NOLcted4OMC4Prwa3DUe3f3181ixPYaRyptbF0Ikq2MbDkYEA== +"@solana/codecs-core@2.0.0-preview.2": + version "2.0.0-preview.2" + resolved "https://registry.yarnpkg.com/@solana/codecs-core/-/codecs-core-2.0.0-preview.2.tgz#689784d032fbc1fedbde40bb25d76cdcecf6553b" + integrity sha512-gLhCJXieSCrAU7acUJjbXl+IbGnqovvxQLlimztPoGgfLQ1wFYu+XJswrEVQqknZYK1pgxpxH3rZ+OKFs0ndQg== + dependencies: + "@solana/errors" "2.0.0-preview.2" + +"@solana/codecs-core@2.0.0-preview.4": + version "2.0.0-preview.4" + resolved "https://registry.yarnpkg.com/@solana/codecs-core/-/codecs-core-2.0.0-preview.4.tgz#770826105f2f884110a21662573e7a2014654324" + integrity sha512-A0VVuDDA5kNKZUinOqHxJQK32aKTucaVbvn31YenGzHX1gPqq+SOnFwgaEY6pq4XEopSmaK16w938ZQS8IvCnw== + dependencies: + "@solana/errors" "2.0.0-preview.4" + "@solana/codecs-data-structures@2.0.0-experimental.8618508": version "2.0.0-experimental.8618508" resolved "https://registry.yarnpkg.com/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-experimental.8618508.tgz#c16a704ac0f743a2e0bf73ada42d830b3402d848" @@ -2597,6 +2611,24 @@ "@solana/codecs-core" "2.0.0-experimental.8618508" "@solana/codecs-numbers" "2.0.0-experimental.8618508" +"@solana/codecs-data-structures@2.0.0-preview.2": + version "2.0.0-preview.2" + resolved "https://registry.yarnpkg.com/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-preview.2.tgz#e82cb1b6d154fa636cd5c8953ff3f32959cc0370" + integrity sha512-Xf5vIfromOZo94Q8HbR04TbgTwzigqrKII0GjYr21K7rb3nba4hUW2ir8kguY7HWFBcjHGlU5x3MevKBOLp3Zg== + dependencies: + "@solana/codecs-core" "2.0.0-preview.2" + "@solana/codecs-numbers" "2.0.0-preview.2" + "@solana/errors" "2.0.0-preview.2" + +"@solana/codecs-data-structures@2.0.0-preview.4": + version "2.0.0-preview.4" + resolved "https://registry.yarnpkg.com/@solana/codecs-data-structures/-/codecs-data-structures-2.0.0-preview.4.tgz#f8a2470982a9792334737ea64000ccbdff287247" + integrity sha512-nt2k2eTeyzlI/ccutPcG36M/J8NAYfxBPI9h/nQjgJ+M+IgOKi31JV8StDDlG/1XvY0zyqugV3I0r3KAbZRJpA== + dependencies: + "@solana/codecs-core" "2.0.0-preview.4" + "@solana/codecs-numbers" "2.0.0-preview.4" + "@solana/errors" "2.0.0-preview.4" + "@solana/codecs-numbers@2.0.0-experimental.8618508": version "2.0.0-experimental.8618508" resolved "https://registry.yarnpkg.com/@solana/codecs-numbers/-/codecs-numbers-2.0.0-experimental.8618508.tgz#d84f9ed0521b22e19125eefc7d51e217fcaeb3e4" @@ -2604,6 +2636,22 @@ dependencies: "@solana/codecs-core" "2.0.0-experimental.8618508" +"@solana/codecs-numbers@2.0.0-preview.2": + version "2.0.0-preview.2" + resolved "https://registry.yarnpkg.com/@solana/codecs-numbers/-/codecs-numbers-2.0.0-preview.2.tgz#56995c27396cd8ee3bae8bd055363891b630bbd0" + integrity sha512-aLZnDTf43z4qOnpTcDsUVy1Ci9im1Md8thWipSWbE+WM9ojZAx528oAql+Cv8M8N+6ALKwgVRhPZkto6E59ARw== + dependencies: + "@solana/codecs-core" "2.0.0-preview.2" + "@solana/errors" "2.0.0-preview.2" + +"@solana/codecs-numbers@2.0.0-preview.4": + version "2.0.0-preview.4" + resolved "https://registry.yarnpkg.com/@solana/codecs-numbers/-/codecs-numbers-2.0.0-preview.4.tgz#6a53b456bb7866f252d8c032c81a92651e150f66" + integrity sha512-Q061rLtMadsO7uxpguT+Z7G4UHnjQ6moVIxAQxR58nLxDPCC7MB1Pk106/Z7NDhDLHTcd18uO6DZ7ajHZEn2XQ== + dependencies: + "@solana/codecs-core" "2.0.0-preview.4" + "@solana/errors" "2.0.0-preview.4" + "@solana/codecs-strings@2.0.0-experimental.8618508": version "2.0.0-experimental.8618508" resolved "https://registry.yarnpkg.com/@solana/codecs-strings/-/codecs-strings-2.0.0-experimental.8618508.tgz#72457b884d9be80b59b263bcce73892b081e9402" @@ -2612,6 +2660,62 @@ "@solana/codecs-core" "2.0.0-experimental.8618508" "@solana/codecs-numbers" "2.0.0-experimental.8618508" +"@solana/codecs-strings@2.0.0-preview.2": + version "2.0.0-preview.2" + resolved "https://registry.yarnpkg.com/@solana/codecs-strings/-/codecs-strings-2.0.0-preview.2.tgz#8bd01a4e48614d5289d72d743c3e81305d445c46" + integrity sha512-EgBwY+lIaHHgMJIqVOGHfIfpdmmUDNoNO/GAUGeFPf+q0dF+DtwhJPEMShhzh64X2MeCZcmSO6Kinx0Bvmmz2g== + dependencies: + "@solana/codecs-core" "2.0.0-preview.2" + "@solana/codecs-numbers" "2.0.0-preview.2" + "@solana/errors" "2.0.0-preview.2" + +"@solana/codecs-strings@2.0.0-preview.4": + version "2.0.0-preview.4" + resolved "https://registry.yarnpkg.com/@solana/codecs-strings/-/codecs-strings-2.0.0-preview.4.tgz#4d06bb722a55a5d04598d362021bfab4bd446760" + integrity sha512-YDbsQePRWm+xnrfS64losSGRg8Wb76cjK1K6qfR8LPmdwIC3787x9uW5/E4icl/k+9nwgbIRXZ65lpF+ucZUnw== + dependencies: + "@solana/codecs-core" "2.0.0-preview.4" + "@solana/codecs-numbers" "2.0.0-preview.4" + "@solana/errors" "2.0.0-preview.4" + +"@solana/codecs@2.0.0-preview.2": + version "2.0.0-preview.2" + resolved "https://registry.yarnpkg.com/@solana/codecs/-/codecs-2.0.0-preview.2.tgz#d6615fec98f423166fb89409f9a4ad5b74c10935" + integrity sha512-4HHzCD5+pOSmSB71X6w9ptweV48Zj1Vqhe732+pcAQ2cMNnN0gMPMdDq7j3YwaZDZ7yrILVV/3+HTnfT77t2yA== + dependencies: + "@solana/codecs-core" "2.0.0-preview.2" + "@solana/codecs-data-structures" "2.0.0-preview.2" + "@solana/codecs-numbers" "2.0.0-preview.2" + "@solana/codecs-strings" "2.0.0-preview.2" + "@solana/options" "2.0.0-preview.2" + +"@solana/codecs@2.0.0-preview.4": + version "2.0.0-preview.4" + resolved "https://registry.yarnpkg.com/@solana/codecs/-/codecs-2.0.0-preview.4.tgz#a1923cc78a6f64ebe656c7ec6335eb6b70405b22" + integrity sha512-gLMupqI4i+G4uPi2SGF/Tc1aXcviZF2ybC81x7Q/fARamNSgNOCUUoSCg9nWu1Gid6+UhA7LH80sWI8XjKaRog== + dependencies: + "@solana/codecs-core" "2.0.0-preview.4" + "@solana/codecs-data-structures" "2.0.0-preview.4" + "@solana/codecs-numbers" "2.0.0-preview.4" + "@solana/codecs-strings" "2.0.0-preview.4" + "@solana/options" "2.0.0-preview.4" + +"@solana/errors@2.0.0-preview.2": + version "2.0.0-preview.2" + resolved "https://registry.yarnpkg.com/@solana/errors/-/errors-2.0.0-preview.2.tgz#e0ea8b008c5c02528d5855bc1903e5e9bbec322e" + integrity sha512-H2DZ1l3iYF5Rp5pPbJpmmtCauWeQXRJapkDg8epQ8BJ7cA2Ut/QEtC3CMmw/iMTcuS6uemFNLcWvlOfoQhvQuA== + dependencies: + chalk "^5.3.0" + commander "^12.0.0" + +"@solana/errors@2.0.0-preview.4": + version "2.0.0-preview.4" + resolved "https://registry.yarnpkg.com/@solana/errors/-/errors-2.0.0-preview.4.tgz#056ba76b6dd900dafa70117311bec3aef0f5250b" + integrity sha512-kadtlbRv2LCWr8A9V22On15Us7Nn8BvqNaOB4hXsTB3O0fU40D1ru2l+cReqLcRPij4znqlRzW9Xi0m6J5DIhA== + dependencies: + chalk "^5.3.0" + commander "^12.1.0" + "@solana/options@2.0.0-experimental.8618508": version "2.0.0-experimental.8618508" resolved "https://registry.yarnpkg.com/@solana/options/-/options-2.0.0-experimental.8618508.tgz#95385340e85f9e8a81b2bfba089404a61c8e9520" @@ -2620,6 +2724,33 @@ "@solana/codecs-core" "2.0.0-experimental.8618508" "@solana/codecs-numbers" "2.0.0-experimental.8618508" +"@solana/options@2.0.0-preview.2": + version "2.0.0-preview.2" + resolved "https://registry.yarnpkg.com/@solana/options/-/options-2.0.0-preview.2.tgz#13ff008bf43a5056ef9a091dc7bb3f39321e867e" + integrity sha512-FAHqEeH0cVsUOTzjl5OfUBw2cyT8d5Oekx4xcn5hn+NyPAfQJgM3CEThzgRD6Q/4mM5pVUnND3oK/Mt1RzSE/w== + dependencies: + "@solana/codecs-core" "2.0.0-preview.2" + "@solana/codecs-numbers" "2.0.0-preview.2" + +"@solana/options@2.0.0-preview.4": + version "2.0.0-preview.4" + resolved "https://registry.yarnpkg.com/@solana/options/-/options-2.0.0-preview.4.tgz#212d35d1da87c7efb13de4d3569ad9eb070f013d" + integrity sha512-tv2O/Frxql/wSe3jbzi5nVicIWIus/BftH+5ZR+r9r3FO0/htEllZS5Q9XdbmSboHu+St87584JXeDx3xm4jaA== + dependencies: + "@solana/codecs-core" "2.0.0-preview.4" + "@solana/codecs-data-structures" "2.0.0-preview.4" + "@solana/codecs-numbers" "2.0.0-preview.4" + "@solana/codecs-strings" "2.0.0-preview.4" + "@solana/errors" "2.0.0-preview.4" + +"@solana/spl-token-group@^0.0.5": + version "0.0.5" + resolved "https://registry.yarnpkg.com/@solana/spl-token-group/-/spl-token-group-0.0.5.tgz#f955dcca782031c85e862b2b46878d1bb02db6c2" + integrity sha512-CLJnWEcdoUBpQJfx9WEbX3h6nTdNiUzswfFdkABUik7HVwSNA98u5AYvBVK2H93d9PGMOHAak2lHW9xr+zAJGQ== + dependencies: + "@solana/codecs" "2.0.0-preview.4" + "@solana/spl-type-length-value" "0.1.0" + "@solana/spl-token-metadata@^0.1.2": version "0.1.2" resolved "https://registry.yarnpkg.com/@solana/spl-token-metadata/-/spl-token-metadata-0.1.2.tgz#876e13432bd2960bd3cac16b9b0af63e69e37719" @@ -2632,6 +2763,14 @@ "@solana/options" "2.0.0-experimental.8618508" "@solana/spl-type-length-value" "0.1.0" +"@solana/spl-token-metadata@^0.1.3": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@solana/spl-token-metadata/-/spl-token-metadata-0.1.4.tgz#5cdc3b857a8c4a6877df24e24a8648c4132d22ba" + integrity sha512-N3gZ8DlW6NWDV28+vCCDJoTqaCZiF/jDUnk3o8GRkAFzHObiR60Bs1gXHBa8zCPdvOwiG6Z3dg5pg7+RW6XNsQ== + dependencies: + "@solana/codecs" "2.0.0-preview.2" + "@solana/spl-type-length-value" "0.1.0" + "@solana/spl-token@^0.2.0": version "0.2.0" resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.2.0.tgz#329bb6babb5de0f9c40035ddb1657f01a8347acd" @@ -2652,6 +2791,17 @@ "@solana/spl-token-metadata" "^0.1.2" buffer "^6.0.3" +"@solana/spl-token@^0.4.8": + version "0.4.8" + resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.4.8.tgz#a84e4131af957fa9fbd2727e5fc45dfbf9083586" + integrity sha512-RO0JD9vPRi4LsAbMUdNbDJ5/cv2z11MGhtAvFeRzT4+hAGE/FUzRi0tkkWtuCfSIU3twC6CtmAihRp/+XXjWsA== + dependencies: + "@solana/buffer-layout" "^4.0.0" + "@solana/buffer-layout-utils" "^0.2.0" + "@solana/spl-token-group" "^0.0.5" + "@solana/spl-token-metadata" "^0.1.3" + buffer "^6.0.3" + "@solana/spl-type-length-value@0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@solana/spl-type-length-value/-/spl-type-length-value-0.1.0.tgz#b5930cf6c6d8f50c7ff2a70463728a4637a2f26b" @@ -4354,6 +4504,11 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== + char-regex@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" @@ -4544,6 +4699,11 @@ command-line-usage@^6.1.1: table-layout "^1.0.2" typical "^5.2.0" +commander@^12.0.0, commander@^12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3" + integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== + commander@^2.20.0, commander@^2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" From 56cc640f1bf966b648d8d69d287861b5007cc2fc Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 7 Aug 2024 10:03:53 +0300 Subject: [PATCH 15/18] fix comments --- package.json | 2 +- .../router-provider/router-cross-chain-trade.ts | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index e72316d9ee9..0e98efe4a18 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.33.0-alpha-router.6", + "version": "5.33.0-alpha-router.7", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts index 54499280c45..c0b4f9668d2 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -131,10 +131,17 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { const isEvmDestination = BlockchainsInfo.isEvmBlockchainName(this.to.blockchain); const receivingAsset = isEvmDestination ? this.to.address : this.from.address; const toBlockchain = this.to.blockchain as RouterCrossChainSupportedBlockchains; - const receiverAddress = await RouterCrossChainUtilService.checkAndConvertAddress( + let receiverAddress = ''; + if (!isEvmDestination && options.receiverAddress) { + receiverAddress = await RouterCrossChainUtilService.checkAndConvertAddress( toBlockchain, - options.receiverAddress || this.walletAddress + options?.receiverAddress ); + } + else { + receiverAddress = options?.receiverAddress || this.walletAddress; + } + const bridgeData = ProxyCrossChainEvmTrade.getBridgeData( { ...options, From e36f202f50766de6ab19f36e268bc79b24ee731d Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 7 Aug 2024 11:24:58 +0300 Subject: [PATCH 16/18] add unsupported contract address check --- .../router-cross-chain-contract-address.ts | 102 ++++++++++++++++++ .../router-cross-chain-trade.ts | 15 ++- .../router-cross-chain-util-service.ts.ts | 19 ++++ 3 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-contract-address.ts diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-contract-address.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-contract-address.ts new file mode 100644 index 00000000000..7a64b352d23 --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-contract-address.ts @@ -0,0 +1,102 @@ +import { BLOCKCHAIN_NAME } from 'src/core/blockchain/models/blockchain-name'; + +import { RouterCrossChainSupportedBlockchains } from './router-cross-chain-supported-chains'; + +export const routerCrossChainContractAddress: Partial< + Record +> = { + [BLOCKCHAIN_NAME.ETHEREUM]: [ + '0x6c45e28a76977a96e263f84f95912b47f927b687', + '0xf9f4c3dc7ba8f56737a92d74fd67230c38af51f2', + '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9', + '0xfB375Cdfb975381731be52c05e8e695C8253c319' + ], + [BLOCKCHAIN_NAME.OPTIMISM]: [ + '0x5501A36b1313aC5d27e85418acd2AA4564f50b44', + '0x21c1E74CAaDf990E237920d5515955a024031109', + '0x8201c02d4ab2214471e8c3ad6475c8b0cd9f2d06', + '0x8fE7fA902E57a1C74F6af3fC54272dce03d54b1F' + ], + [BLOCKCHAIN_NAME.ROOTSTOCK]: [ + '0xff13a7a12fd485bc9687ff88d8ae1a6b655ab469', + '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9' + ], + [BLOCKCHAIN_NAME.BINANCE_SMART_CHAIN]: [ + '0x2F301d3b045544A9D7Ec3FA090CD78986F11f2E7', + '0x21c1E74CAaDf990E237920d5515955a024031109', + '0x260687ebc6c55dadd578264260f9f6e968f7b2a5' + ], + [BLOCKCHAIN_NAME.POLYGON]: [ + '0xc57133521ffbd729cb81cc8ddc12d9e9f61e0f6a', + '0xa62ec33abd6d7ebdf8ec98ce874820517ae71e4d', + '0x1396f41d89b96eaf29a7ef9ee01ad36e452235ae', + '0x3a5A635FD8c6fcEBa7A8b2861c1CBde7ED32A918' + ], + [BLOCKCHAIN_NAME.MANTA_PACIFIC]: [ + '0x8201c02d4AB2214471E8C3AD6475C8b0CD9F2D06', + '0x21c1e74caadf990e237920d5515955a024031109' + ], + [BLOCKCHAIN_NAME.XLAYER]: [ + '0x01B4CE0d48Ce91eB6bcaf5dB33870C65d641b894', + '0x21c1e74caadf990e237920d5515955a024031109' + ], + [BLOCKCHAIN_NAME.FANTOM]: ['0xc21e4ebd1d92036cb467b53fe3258f219d909eb9'], + [BLOCKCHAIN_NAME.ZK_SYNC]: [ + '0x7E7D4185D9c3C44D5266eD974493b24811398049', + '0xCa9E3756b9e20F9eDB204523210AF736839B07E9', + '0x8b6f1c18c866f37e6ea98aa539e0c117e70178a2' + ], + [BLOCKCHAIN_NAME.METIS]: [ + '0x21c1E74CAaDf990E237920d5515955a024031109', + '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9' + ], + [BLOCKCHAIN_NAME.POLYGON_ZKEVM]: [ + '0x6a0fd5577c540e16a3a49c40b51e0880a2a528ce', + '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9' + ], + [BLOCKCHAIN_NAME.MANTLE]: [ + '0xB6dc6C8b71e88642cEAD3be1025565A9eE74d1C6', + '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9' + ], + [BLOCKCHAIN_NAME.BASE]: [ + '0x02D728B9C1513478a6b6de77a92648e1D8F801e7', + '0x21c1E74CAaDf990E237920d5515955a024031109', + '0x0fa205c0446cd9eedcc7538c9e24bc55ad08207f', + '0x2F301d3b045544A9D7Ec3FA090CD78986F11f2E7' + ], + [BLOCKCHAIN_NAME.MODE]: [ + '0xf0773508c585246bd09bfb401aa18b72685b03f9', + '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9' + ], + [BLOCKCHAIN_NAME.ARBITRUM]: [ + '0xCA94d8C245601B152C904f42fE788B4125f5b46B', + '0x0Fa205c0446cD9EeDCc7538c9E24BC55AD08207f', + '0xef300fb4243a0ff3b90c8ccfa1264d78182adaa4', + '0x60b483D521b844e13E3337D304929D0519Bd50C8' + ], + [BLOCKCHAIN_NAME.AVALANCHE]: [ + '0x4406ebEb7028fc0fc06bB7706A736AC6ada8D2bF', + '0x8c4acd74ff4385f3b7911432fa6787aa14406f8b', + '0xf9f4c3dc7ba8f56737a92d74fd67230c38af51f2', + '0xf8555Aac045eEA3a355b5ce4f8916b67Cc74d693' + ], + [BLOCKCHAIN_NAME.LINEA]: [ + '0x6D6050Ca1dd8e4aAb9164B663d805104a3ECFC34', + '0x01B4CE0d48Ce91eB6bcaf5dB33870C65d641b894', + '0x8c4acd74ff4385f3b7911432fa6787aa14406f8b' + ], + [BLOCKCHAIN_NAME.BLAST]: [ + '0x01B4CE0d48Ce91eB6bcaf5dB33870C65d641b894', + '0x97eec1c29f745dC7c267F90292AA663d997a601D' + ], + [BLOCKCHAIN_NAME.TAIKO]: ['0x7bd616192fb2b364f9d29b2026165281a5f2ff2f'], + [BLOCKCHAIN_NAME.SCROLL]: [ + '0x5546dA2bCdCFF39b187723434cDE10D4eE99C566', + '0x21c1E74CAaDf990E237920d5515955a024031109', + '0x01b4ce0d48ce91eb6bcaf5db33870c65d641b894' + ], + [BLOCKCHAIN_NAME.AURORA]: [ + '0x7BD616192fB2B364f9d29B2026165281a5f2ff2F', + '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9' + ] +}; diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts index c0b4f9668d2..fac3da5e017 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -128,17 +128,24 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { options?.receiverAddress ); try { + const isValidContractAddress = + RouterCrossChainUtilService.checkSupportedContractAddress( + this.from.blockchain as RouterCrossChainSupportedBlockchains, + to + ); + if (!isValidContractAddress) { + throw new RubicSdkError('Invalid Router contract address'); + } const isEvmDestination = BlockchainsInfo.isEvmBlockchainName(this.to.blockchain); const receivingAsset = isEvmDestination ? this.to.address : this.from.address; const toBlockchain = this.to.blockchain as RouterCrossChainSupportedBlockchains; let receiverAddress = ''; if (!isEvmDestination && options.receiverAddress) { receiverAddress = await RouterCrossChainUtilService.checkAndConvertAddress( - toBlockchain, + toBlockchain, options?.receiverAddress - ); - } - else { + ); + } else { receiverAddress = options?.receiverAddress || this.walletAddress; } diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts index 769938dc361..8bc585f3425 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts @@ -1,10 +1,12 @@ import { RubicSdkError } from 'src/common/errors'; +import { compareAddresses } from 'src/common/utils/blockchain'; import { BLOCKCHAIN_NAME, BlockchainName } from 'src/core/blockchain/models/blockchain-name'; import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; import { SolanaWeb3Public } from 'src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public'; import { TronWeb3Public } from 'src/core/blockchain/web3-public-service/web3-public/tron-web3-public/tron-web3-public'; import { Injector } from 'src/core/injector/injector'; +import { routerCrossChainContractAddress } from '../constants/router-cross-chain-contract-address'; import { RouterCrossChainSupportedBlockchains } from '../constants/router-cross-chain-supported-chains'; export class RouterCrossChainUtilService { @@ -55,4 +57,21 @@ export class RouterCrossChainUtilService { return blockchainId[blockchain].toString(); } + + public static checkSupportedContractAddress( + fromBlockchain: RouterCrossChainSupportedBlockchains, + allowanceAddress: string + ): boolean { + if ( + fromBlockchain === BLOCKCHAIN_NAME.TRON || + fromBlockchain === BLOCKCHAIN_NAME.SOLANA || + fromBlockchain === BLOCKCHAIN_NAME.BOBA + ) { + return true; + } + + return routerCrossChainContractAddress[fromBlockchain]!.some(contractAddress => + compareAddresses(contractAddress, allowanceAddress) + ); + } } From ad4f5360eb768b0d29613809d155952cf1cc5a95 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 7 Aug 2024 11:55:28 +0300 Subject: [PATCH 17/18] Revert "add unsupported contract address check" --- .../router-cross-chain-contract-address.ts | 102 ------------------ .../router-cross-chain-trade.ts | 15 +-- .../router-cross-chain-util-service.ts.ts | 19 ---- 3 files changed, 4 insertions(+), 132 deletions(-) delete mode 100644 src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-contract-address.ts diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-contract-address.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-contract-address.ts deleted file mode 100644 index 7a64b352d23..00000000000 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-contract-address.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { BLOCKCHAIN_NAME } from 'src/core/blockchain/models/blockchain-name'; - -import { RouterCrossChainSupportedBlockchains } from './router-cross-chain-supported-chains'; - -export const routerCrossChainContractAddress: Partial< - Record -> = { - [BLOCKCHAIN_NAME.ETHEREUM]: [ - '0x6c45e28a76977a96e263f84f95912b47f927b687', - '0xf9f4c3dc7ba8f56737a92d74fd67230c38af51f2', - '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9', - '0xfB375Cdfb975381731be52c05e8e695C8253c319' - ], - [BLOCKCHAIN_NAME.OPTIMISM]: [ - '0x5501A36b1313aC5d27e85418acd2AA4564f50b44', - '0x21c1E74CAaDf990E237920d5515955a024031109', - '0x8201c02d4ab2214471e8c3ad6475c8b0cd9f2d06', - '0x8fE7fA902E57a1C74F6af3fC54272dce03d54b1F' - ], - [BLOCKCHAIN_NAME.ROOTSTOCK]: [ - '0xff13a7a12fd485bc9687ff88d8ae1a6b655ab469', - '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9' - ], - [BLOCKCHAIN_NAME.BINANCE_SMART_CHAIN]: [ - '0x2F301d3b045544A9D7Ec3FA090CD78986F11f2E7', - '0x21c1E74CAaDf990E237920d5515955a024031109', - '0x260687ebc6c55dadd578264260f9f6e968f7b2a5' - ], - [BLOCKCHAIN_NAME.POLYGON]: [ - '0xc57133521ffbd729cb81cc8ddc12d9e9f61e0f6a', - '0xa62ec33abd6d7ebdf8ec98ce874820517ae71e4d', - '0x1396f41d89b96eaf29a7ef9ee01ad36e452235ae', - '0x3a5A635FD8c6fcEBa7A8b2861c1CBde7ED32A918' - ], - [BLOCKCHAIN_NAME.MANTA_PACIFIC]: [ - '0x8201c02d4AB2214471E8C3AD6475C8b0CD9F2D06', - '0x21c1e74caadf990e237920d5515955a024031109' - ], - [BLOCKCHAIN_NAME.XLAYER]: [ - '0x01B4CE0d48Ce91eB6bcaf5dB33870C65d641b894', - '0x21c1e74caadf990e237920d5515955a024031109' - ], - [BLOCKCHAIN_NAME.FANTOM]: ['0xc21e4ebd1d92036cb467b53fe3258f219d909eb9'], - [BLOCKCHAIN_NAME.ZK_SYNC]: [ - '0x7E7D4185D9c3C44D5266eD974493b24811398049', - '0xCa9E3756b9e20F9eDB204523210AF736839B07E9', - '0x8b6f1c18c866f37e6ea98aa539e0c117e70178a2' - ], - [BLOCKCHAIN_NAME.METIS]: [ - '0x21c1E74CAaDf990E237920d5515955a024031109', - '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9' - ], - [BLOCKCHAIN_NAME.POLYGON_ZKEVM]: [ - '0x6a0fd5577c540e16a3a49c40b51e0880a2a528ce', - '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9' - ], - [BLOCKCHAIN_NAME.MANTLE]: [ - '0xB6dc6C8b71e88642cEAD3be1025565A9eE74d1C6', - '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9' - ], - [BLOCKCHAIN_NAME.BASE]: [ - '0x02D728B9C1513478a6b6de77a92648e1D8F801e7', - '0x21c1E74CAaDf990E237920d5515955a024031109', - '0x0fa205c0446cd9eedcc7538c9e24bc55ad08207f', - '0x2F301d3b045544A9D7Ec3FA090CD78986F11f2E7' - ], - [BLOCKCHAIN_NAME.MODE]: [ - '0xf0773508c585246bd09bfb401aa18b72685b03f9', - '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9' - ], - [BLOCKCHAIN_NAME.ARBITRUM]: [ - '0xCA94d8C245601B152C904f42fE788B4125f5b46B', - '0x0Fa205c0446cD9EeDCc7538c9E24BC55AD08207f', - '0xef300fb4243a0ff3b90c8ccfa1264d78182adaa4', - '0x60b483D521b844e13E3337D304929D0519Bd50C8' - ], - [BLOCKCHAIN_NAME.AVALANCHE]: [ - '0x4406ebEb7028fc0fc06bB7706A736AC6ada8D2bF', - '0x8c4acd74ff4385f3b7911432fa6787aa14406f8b', - '0xf9f4c3dc7ba8f56737a92d74fd67230c38af51f2', - '0xf8555Aac045eEA3a355b5ce4f8916b67Cc74d693' - ], - [BLOCKCHAIN_NAME.LINEA]: [ - '0x6D6050Ca1dd8e4aAb9164B663d805104a3ECFC34', - '0x01B4CE0d48Ce91eB6bcaf5dB33870C65d641b894', - '0x8c4acd74ff4385f3b7911432fa6787aa14406f8b' - ], - [BLOCKCHAIN_NAME.BLAST]: [ - '0x01B4CE0d48Ce91eB6bcaf5dB33870C65d641b894', - '0x97eec1c29f745dC7c267F90292AA663d997a601D' - ], - [BLOCKCHAIN_NAME.TAIKO]: ['0x7bd616192fb2b364f9d29b2026165281a5f2ff2f'], - [BLOCKCHAIN_NAME.SCROLL]: [ - '0x5546dA2bCdCFF39b187723434cDE10D4eE99C566', - '0x21c1E74CAaDf990E237920d5515955a024031109', - '0x01b4ce0d48ce91eb6bcaf5db33870c65d641b894' - ], - [BLOCKCHAIN_NAME.AURORA]: [ - '0x7BD616192fB2B364f9d29B2026165281a5f2ff2F', - '0xc21e4ebd1d92036cb467b53fe3258f219d909eb9' - ] -}; diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts index fac3da5e017..c0b4f9668d2 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -128,24 +128,17 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { options?.receiverAddress ); try { - const isValidContractAddress = - RouterCrossChainUtilService.checkSupportedContractAddress( - this.from.blockchain as RouterCrossChainSupportedBlockchains, - to - ); - if (!isValidContractAddress) { - throw new RubicSdkError('Invalid Router contract address'); - } const isEvmDestination = BlockchainsInfo.isEvmBlockchainName(this.to.blockchain); const receivingAsset = isEvmDestination ? this.to.address : this.from.address; const toBlockchain = this.to.blockchain as RouterCrossChainSupportedBlockchains; let receiverAddress = ''; if (!isEvmDestination && options.receiverAddress) { receiverAddress = await RouterCrossChainUtilService.checkAndConvertAddress( - toBlockchain, + toBlockchain, options?.receiverAddress - ); - } else { + ); + } + else { receiverAddress = options?.receiverAddress || this.walletAddress; } diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts index 8bc585f3425..769938dc361 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts @@ -1,12 +1,10 @@ import { RubicSdkError } from 'src/common/errors'; -import { compareAddresses } from 'src/common/utils/blockchain'; import { BLOCKCHAIN_NAME, BlockchainName } from 'src/core/blockchain/models/blockchain-name'; import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; import { SolanaWeb3Public } from 'src/core/blockchain/web3-public-service/web3-public/solana-web3-public/solana-web3-public'; import { TronWeb3Public } from 'src/core/blockchain/web3-public-service/web3-public/tron-web3-public/tron-web3-public'; import { Injector } from 'src/core/injector/injector'; -import { routerCrossChainContractAddress } from '../constants/router-cross-chain-contract-address'; import { RouterCrossChainSupportedBlockchains } from '../constants/router-cross-chain-supported-chains'; export class RouterCrossChainUtilService { @@ -57,21 +55,4 @@ export class RouterCrossChainUtilService { return blockchainId[blockchain].toString(); } - - public static checkSupportedContractAddress( - fromBlockchain: RouterCrossChainSupportedBlockchains, - allowanceAddress: string - ): boolean { - if ( - fromBlockchain === BLOCKCHAIN_NAME.TRON || - fromBlockchain === BLOCKCHAIN_NAME.SOLANA || - fromBlockchain === BLOCKCHAIN_NAME.BOBA - ) { - return true; - } - - return routerCrossChainContractAddress[fromBlockchain]!.some(contractAddress => - compareAddresses(contractAddress, allowanceAddress) - ); - } } From b34a4d34ae3fa2af6e0141080959ae60505bac8d Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 8 Aug 2024 16:54:05 +0300 Subject: [PATCH 18/18] disable solana --- package.json | 2 +- .../router/services/router-api-service.ts | 2 +- .../providers/common/cross-chain-trade.ts | 2 +- .../router-cross-chain-supported-chains.ts | 4 ++-- .../router-cross-chain-provider.ts | 18 +++++++----------- .../router-cross-chain-trade.ts | 7 +++---- .../router-cross-chain-util-service.ts.ts | 16 ++++++++-------- 7 files changed, 23 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index 0e98efe4a18..336a45e9d67 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.33.0-alpha-router.7", + "version": "5.33.0", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/features/common/providers/router/services/router-api-service.ts b/src/features/common/providers/router/services/router-api-service.ts index 2a90f61de78..61e095e6677 100644 --- a/src/features/common/providers/router/services/router-api-service.ts +++ b/src/features/common/providers/router/services/router-api-service.ts @@ -15,7 +15,7 @@ export class RouterApiService { private static readonly ROUTER_ENDPOINT = 'https://api-beta.pathfinder.routerprotocol.com/api/v2'; - private static readonly partnerId = 1; + private static readonly partnerId = 159; public static async getQuote( params: RouterQuoteSendParams diff --git a/src/features/cross-chain/calculation-manager/providers/common/cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/common/cross-chain-trade.ts index 62f3fe22a64..f3069dee3aa 100644 --- a/src/features/cross-chain/calculation-manager/providers/common/cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/common/cross-chain-trade.ts @@ -123,7 +123,7 @@ export abstract class CrossChainTrade { protected checkAmountChange(newWeiAmount: string, oldWeiAmount: string): void { const oldAmount = new BigNumber(oldWeiAmount); const newAmount = new BigNumber(newWeiAmount); - const changePercent = 0.0001; + const changePercent = 0.5; const acceptablePercentPriceChange = new BigNumber(changePercent).dividedBy(100); const amountPlusPercent = oldAmount.multipliedBy(acceptablePercentPriceChange.plus(1)); diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts index 1f28006e67a..b6a5337f2a3 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/constants/router-cross-chain-supported-chains.ts @@ -23,8 +23,8 @@ export const routerCrossChainSupportedChains = [ BLOCKCHAIN_NAME.TAIKO, BLOCKCHAIN_NAME.SCROLL, BLOCKCHAIN_NAME.TRON, - BLOCKCHAIN_NAME.AURORA, - BLOCKCHAIN_NAME.SOLANA + BLOCKCHAIN_NAME.AURORA + // BLOCKCHAIN_NAME.SOLANA ]; export type RouterCrossChainSupportedBlockchains = (typeof routerCrossChainSupportedChains)[number]; diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts index c3341db1906..61131de5194 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-provider.ts @@ -1,11 +1,7 @@ import BigNumber from 'bignumber.js'; import { NotSupportedTokensError } from 'src/common/errors'; import { PriceToken, PriceTokenAmount, TokenAmount } from 'src/common/tokens'; -import { - BLOCKCHAIN_NAME, - BlockchainName, - EvmBlockchainName -} from 'src/core/blockchain/models/blockchain-name'; +import { BlockchainName, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; import { CHAIN_TYPE } from 'src/core/blockchain/models/chain-type'; import { BlockchainsInfo } from 'src/core/blockchain/utils/blockchains-info/blockchains-info'; import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; @@ -55,12 +51,12 @@ export class RouterCrossChainProvider extends CrossChainProvider { const useProxy = options?.useProxy?.[this.type] ?? true; try { - if (toBlockchain === BLOCKCHAIN_NAME.SOLANA && options.receiverAddress) { - await RouterCrossChainUtilService.checkAtaAddress( - options.receiverAddress, - toToken.address - ); - } + // if (toBlockchain === BLOCKCHAIN_NAME.SOLANA && options.receiverAddress) { + // await RouterCrossChainUtilService.checkAtaAddress( + // options.receiverAddress, + // toToken.address + // ); + // } const srcChainId = RouterCrossChainUtilService.getBlockchainId(fromBlockchain); const dstChainId = RouterCrossChainUtilService.getBlockchainId(toBlockchain); diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts index c0b4f9668d2..333da9b6202 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/router-cross-chain-trade.ts @@ -134,11 +134,10 @@ export class RouterCrossChainTrade extends EvmCrossChainTrade { let receiverAddress = ''; if (!isEvmDestination && options.receiverAddress) { receiverAddress = await RouterCrossChainUtilService.checkAndConvertAddress( - toBlockchain, + toBlockchain, options?.receiverAddress - ); - } - else { + ); + } else { receiverAddress = options?.receiverAddress || this.walletAddress; } diff --git a/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts b/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts index 769938dc361..3e5bb5cb508 100644 --- a/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts +++ b/src/features/cross-chain/calculation-manager/providers/router-provider/utils/router-cross-chain-util-service.ts.ts @@ -19,17 +19,17 @@ export class RouterCrossChainUtilService { public static async checkAndConvertAddress( blockchain: RouterCrossChainSupportedBlockchains, address: string, - tokenAddress?: string + _tokenAddress?: string ): Promise { if (blockchain === BLOCKCHAIN_NAME.TRON) { const tronHexAddress = await this.tronWeb3Public.convertTronAddressToHex(address); return `0x${tronHexAddress.slice(2)}`; } - if (blockchain === BLOCKCHAIN_NAME.SOLANA && tokenAddress) { - const ataAddress = await this.solanaWeb3Public.getAtaAddress(address, tokenAddress); - return ataAddress!; - } + // if (blockchain === BLOCKCHAIN_NAME.SOLANA && tokenAddress) { + // const ataAddress = await this.solanaWeb3Public.getAtaAddress(address, tokenAddress); + // return ataAddress!; + // } return address; } @@ -49,9 +49,9 @@ export class RouterCrossChainUtilService { if (blockchain === BLOCKCHAIN_NAME.TRON) { return '728126428'; } - if (blockchain === BLOCKCHAIN_NAME.SOLANA) { - return 'solana'; - } + // if (blockchain === BLOCKCHAIN_NAME.SOLANA) { + // return 'solana'; + // } return blockchainId[blockchain].toString(); }