diff --git a/package.json b/package.json index fa4f38338b4..050a8b2a0b3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rubic-sdk", - "version": "5.42.6", + "version": "5.43.0", "description": "Simplify dApp creation", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/core/blockchain/web3-private-service/web3-private/tron-web3-private/models/tron-transaction-options.ts b/src/core/blockchain/web3-private-service/web3-private/tron-web3-private/models/tron-transaction-options.ts index 9281decc263..944acd0c5b3 100644 --- a/src/core/blockchain/web3-private-service/web3-private/tron-web3-private/models/tron-transaction-options.ts +++ b/src/core/blockchain/web3-private-service/web3-private/tron-web3-private/models/tron-transaction-options.ts @@ -4,4 +4,6 @@ export interface TronTransactionOptions extends BasicTransactionOptions { feeLimit?: number; callValue?: number | string; + + rawParameter?: string; } diff --git a/src/core/blockchain/web3-private-service/web3-private/tron-web3-private/tron-web3-private.ts b/src/core/blockchain/web3-private-service/web3-private/tron-web3-private/tron-web3-private.ts index b027fbd8f9c..57e1449dd9d 100644 --- a/src/core/blockchain/web3-private-service/web3-private/tron-web3-private/tron-web3-private.ts +++ b/src/core/blockchain/web3-private-service/web3-private/tron-web3-private/tron-web3-private.ts @@ -13,7 +13,6 @@ import { TronParameters } from 'src/core/blockchain/web3-pure/typed-web3-pure/tr import { TronTransactionConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config'; import { TronWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/tron-web3-pure'; import { WalletProviderCore } from 'src/core/sdk/models/wallet-provider'; -import { AbiItem } from 'web3-utils'; export class TronWeb3Private extends Web3Private { /** @@ -91,42 +90,16 @@ export class TronWeb3Private extends Web3Private { tokenAddress, TRC20_CONTRACT_ABI, 'approve', - [spenderAddress, rawValue.toFixed(0)], + [ + { type: 'address', value: spenderAddress }, + { type: 'uint256', value: rawValue.toFixed(0) } + ], '0', options.feeLimit ); } - public async executeContractMethod( - contractAddress: string, - contractAbi: AbiItem[], - methodName: string, - methodArguments: unknown[], - options: TronTransactionOptions = {} - ): Promise { - try { - const contract = await this.tronWeb.contract(contractAbi, contractAddress); - - const transactionHash = await contract[methodName](...methodArguments).send({ - from: this.address, - ...(options.callValue && { - callValue: Web3Private.stringifyAmount(options.callValue) - }), - ...(options.feeLimit && { - feeLimit: Web3Private.stringifyAmount(options.feeLimit) - }) - }); - if (options.onTransactionHash) { - options.onTransactionHash(transactionHash); - } - return transactionHash; - } catch (err) { - console.error('Method execution error: ', err); - throw TronWeb3Private.parseError(err); - } - } - - public async triggerContract( + public async sendTransaction( contractAddress: string, methodSignature: string, parameters: TronParameters, @@ -154,4 +127,27 @@ export class TronWeb3Private extends Web3Private { throw TronWeb3Private.parseError(err); } } + + public async trySendTransaction( + contractAddress: string, + methodSignature: string, + parameters: TronParameters, + options: TronTransactionOptions = {} + ): Promise { + try { + await this.tronWeb.transactionBuilder.estimateEnergy( + contractAddress, + methodSignature, + {}, + parameters, + this.address + ); + } catch (err) { + if (err !== 'this node does not support estimate energy') { + throw new Error('Tron transaction simulation error'); + } + } + + return this.sendTransaction(contractAddress, methodSignature, parameters, options); + } } diff --git a/src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config.ts b/src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config.ts index 7b75e38c1fa..f2b425a2857 100644 --- a/src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config.ts +++ b/src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config.ts @@ -1,6 +1,12 @@ +import { TronParameters } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-parameters'; + export interface TronTransactionConfig { + signature: string; + arguments: TronParameters; to: string; - data: string; - callValue?: string; + feeLimit?: number; + callValue?: string; + + rawParameter?: string; } diff --git a/src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/tron-web3-pure.ts b/src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/tron-web3-pure.ts index 0adffbcf0e3..db9e9a0183a 100644 --- a/src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/tron-web3-pure.ts +++ b/src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/tron-web3-pure.ts @@ -43,16 +43,25 @@ export class TronWeb3Pure { contractAddress: string, contractAbi: AbiItem[], methodName: string, - methodArguments: unknown[] = [], + methodArguments: TronParameters, callValue?: string, feeLimit?: number ): TronTransactionConfig { - const data = this.encodeFunctionCall(contractAbi, methodName, methodArguments); + const methodAbi = contractAbi.find(abiItem => abiItem.name === methodName); + if (!methodAbi) { + throw new Error('Encode fail. No method in ABI'); + } + + const signature = `${methodAbi.name!}(${this.flattenTypesToString(methodAbi.inputs!).join( + ',' + )})`; + return { to: contractAddress, - data, - callValue, - feeLimit + arguments: methodArguments, + signature, + ...(callValue && { callValue }), + ...(feeLimit && { feeLimit }) }; } diff --git a/src/features/common/constants/fake-wallet-address.ts b/src/features/common/constants/fake-wallet-address.ts index 633a782c057..4155a77183a 100644 --- a/src/features/common/constants/fake-wallet-address.ts +++ b/src/features/common/constants/fake-wallet-address.ts @@ -1,3 +1,4 @@ /* used for passing fromAddress in swap/quote requests with disabled wallet */ export const FAKE_WALLET_ADDRESS = '0xe388Ed184958062a2ea29B7fD049ca21244AE02e'; export const FAKE_SOLANA_WALLET_ADDRESS = '7cwWhuCJUHc27Dq4nQRhggwgeuVHEeS3NWv7BY6yY9Bk'; +export const FAKE_TRON_WALLET_ADDRESS = 'TFwy9q45E5kK6HKzmc3gAcJY4rVD96VNi5'; diff --git a/src/features/common/providers/bridgers/models/bridgers-swap-api.ts b/src/features/common/providers/bridgers/models/bridgers-swap-api.ts index 3d5707a1a96..7f118260fc9 100644 --- a/src/features/common/providers/bridgers/models/bridgers-swap-api.ts +++ b/src/features/common/providers/bridgers/models/bridgers-swap-api.ts @@ -1,6 +1,6 @@ import { BridgersSourceFlag } from 'src/features/common/providers/bridgers/models/bridgers-source-flag'; -import { EvmBridgersTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/evm-bridgers-trade/models/evm-bridgers-transaction-data'; -import { TronBridgersTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/tron-bridgers-trade/models/tron-bridgers-transaction-data'; +import { EvmBridgersTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/evm-bridgers-transaction-data'; +import { TronBridgersTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/tron-bridgers-transaction-data'; export interface BridgersSwapRequest { fromTokenAddress: string; diff --git a/src/features/cross-chain/calculation-manager/providers/bridgers-provider/bridgers-cross-chain-provider-factory.ts b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/bridgers-cross-chain-provider-factory.ts new file mode 100644 index 00000000000..e0825621769 --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/bridgers-cross-chain-provider-factory.ts @@ -0,0 +1,46 @@ +import { + BlockchainName, + EvmBlockchainName, + TronBlockchainName +} from 'src/core/blockchain/models/blockchain-name'; +import { BlockchainsInfo } from 'src/core/blockchain/utils/blockchains-info/blockchains-info'; +import { + BridgersCrossChainGasParams, + BridgersCrossChainParams, + BridgersEvmCrossChainParams, + BridgersTronCrossChainParams +} from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/bridgers-cross-chain-trade-types'; +import { EvmBridgersCrossChainTrade } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/networks/evm-bridgers-cross-chain-trade'; +import { TronBridgersCrossChainTrade } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/networks/tron-bridgers-cross-chain-trade'; +import { GasData } from 'src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/models/gas-data'; + +export class BridgersCrossChainProviderFactory { + public static createTrade( + params: BridgersCrossChainParams + ): EvmBridgersCrossChainTrade | TronBridgersCrossChainTrade { + const fromBlockchain = params.crossChainTrade.from.blockchain; + if (BlockchainsInfo.isTronBlockchainName(fromBlockchain)) { + return new TronBridgersCrossChainTrade(params as BridgersTronCrossChainParams); + } + + if (BlockchainsInfo.isEvmBlockchainName(fromBlockchain)) { + return new EvmBridgersCrossChainTrade(params as BridgersEvmCrossChainParams); + } + throw new Error('Can not create trade instance'); + } + + public static async getGasData( + calculateGas: boolean, + params: BridgersCrossChainGasParams + ): Promise { + if (calculateGas) { + const fromBlockchain = params.from.blockchain; + if (BlockchainsInfo.isEvmBlockchainName(fromBlockchain)) { + return EvmBridgersCrossChainTrade.getGasData( + params as BridgersCrossChainGasParams + ); + } + } + return null; + } +} diff --git a/src/features/cross-chain/calculation-manager/providers/bridgers-provider/bridgers-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/bridgers-cross-chain-provider.ts index 727daa82f28..4bba69aee68 100644 --- a/src/features/cross-chain/calculation-manager/providers/bridgers-provider/bridgers-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/bridgers-cross-chain-provider.ts @@ -9,9 +9,9 @@ import { PriceToken, PriceTokenAmount } from 'src/common/tokens'; import { BLOCKCHAIN_NAME, BlockchainName, + EvmBlockchainName, TronBlockchainName } from 'src/core/blockchain/models/blockchain-name'; -import { BlockchainsInfo } from 'src/core/blockchain/utils/blockchains-info/blockchains-info'; import { Web3PublicSupportedBlockchain } from 'src/core/blockchain/web3-public-service/models/web3-public-storage'; 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'; @@ -26,13 +26,11 @@ import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fe import { createTokenNativeAddressProxy } from 'src/features/common/utils/token-native-address-proxy'; import { RequiredCrossChainOptions } from 'src/features/cross-chain/calculation-manager/models/cross-chain-options'; import { CROSS_CHAIN_TRADE_TYPE } from 'src/features/cross-chain/calculation-manager/models/cross-chain-trade-type'; +import { BridgersCrossChainProviderFactory } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/bridgers-cross-chain-provider-factory'; import { BridgersCrossChainSupportedBlockchain, - bridgersCrossChainSupportedBlockchains, - BridgersEvmCrossChainSupportedBlockchain + bridgersCrossChainSupportedBlockchains } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/constants/bridgers-cross-chain-supported-blockchain'; -import { EvmBridgersCrossChainTrade } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/evm-bridgers-trade/evm-bridgers-cross-chain-trade'; -import { TronBridgersCrossChainTrade } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/tron-bridgers-trade/tron-bridgers-cross-chain-trade'; import { CrossChainProvider } from 'src/features/cross-chain/calculation-manager/providers/common/cross-chain-provider'; import { CalculationResult } from 'src/features/cross-chain/calculation-manager/providers/common/models/calculation-result'; import { FeeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/fee-info'; @@ -152,49 +150,34 @@ export class BridgersCrossChainProvider extends CrossChainProvider { toToken.decimals ); - if (BlockchainsInfo.isEvmBlockchainName(fromBlockchain)) { - const gasData = - options.gasCalculation === 'enabled' && options.receiverAddress - ? await EvmBridgersCrossChainTrade.getGasData( - from as PriceTokenAmount, - to as PriceTokenAmount, - options.receiverAddress, - options.providerAddress, - feeInfo - ) - : null; - - const evmTrade = new EvmBridgersCrossChainTrade( - { - from: from as PriceTokenAmount, - to: to as PriceTokenAmount, - toTokenAmountMin, - feeInfo, - gasData, - slippage: options.slippageTolerance - }, - options.providerAddress, - await this.getRoutePath(from, to), - useProxy - ); - - return this.getCalculationResponse(from, transactionData, evmTrade); - } - - const tronTrade = new TronBridgersCrossChainTrade( + const gasData = await BridgersCrossChainProviderFactory.getGasData( + options.gasCalculation === 'enabled' && Boolean(options.receiverAddress), { - from: from as PriceTokenAmount, - to: to as PriceTokenAmount, + from, + to, + receiverAddress: options.receiverAddress!, + providerAddress: options.providerAddress, + feeInfo + } + ); + + const trade = BridgersCrossChainProviderFactory.createTrade({ + crossChainTrade: { + from: from as + | PriceTokenAmount + | PriceTokenAmount, + to, toTokenAmountMin, feeInfo, - slippage: options.slippageTolerance, - contractAddress: transactionData.contractAddress + gasData, + slippage: options.slippageTolerance }, - options.providerAddress, - await this.getRoutePath(from, to) - ); + providerAddress: options.providerAddress, + routePath: await this.getRoutePath(from, to), + useProxy + }); - return this.getCalculationResponse(from, transactionData, tronTrade); + return this.getCalculationResponse(from, transactionData, trade); } catch (err: unknown) { return { trade: null, diff --git a/src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/bridgers-cross-chain-trade-types.ts b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/bridgers-cross-chain-trade-types.ts new file mode 100644 index 00000000000..767cccad2a4 --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/bridgers-cross-chain-trade-types.ts @@ -0,0 +1,36 @@ +import BigNumber from 'bignumber.js'; +import { PriceTokenAmount } from 'src/common/tokens'; +import { + BlockchainName, + EvmBlockchainName, + TronBlockchainName +} from 'src/core/blockchain/models/blockchain-name'; + +import { GasData } from '../../common/evm-cross-chain-trade/models/gas-data'; +import { FeeInfo } from '../../common/models/fee-info'; +import { RubicStep } from '../../common/models/rubicStep'; + +export interface BridgersCrossChainGasParams { + from: PriceTokenAmount; + to: PriceTokenAmount; + receiverAddress: string; + providerAddress: string; + feeInfo: FeeInfo; +} + +export interface BridgersCrossChainParams { + crossChainTrade: { + from: PriceTokenAmount; + to: PriceTokenAmount; + toTokenAmountMin: BigNumber; + feeInfo: FeeInfo; + gasData: GasData; + slippage: number; + }; + providerAddress: string; + routePath: RubicStep[]; + useProxy: boolean; +} + +export type BridgersEvmCrossChainParams = BridgersCrossChainParams; +export type BridgersTronCrossChainParams = BridgersCrossChainParams; diff --git a/src/features/cross-chain/calculation-manager/providers/bridgers-provider/evm-bridgers-trade/models/evm-bridgers-transaction-data.ts b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/evm-bridgers-transaction-data.ts similarity index 100% rename from src/features/cross-chain/calculation-manager/providers/bridgers-provider/evm-bridgers-trade/models/evm-bridgers-transaction-data.ts rename to src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/evm-bridgers-transaction-data.ts diff --git a/src/features/cross-chain/calculation-manager/providers/bridgers-provider/tron-bridgers-trade/models/tron-bridgers-transaction-data.ts b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/tron-bridgers-transaction-data.ts similarity index 100% rename from src/features/cross-chain/calculation-manager/providers/bridgers-provider/tron-bridgers-trade/models/tron-bridgers-transaction-data.ts rename to src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/tron-bridgers-transaction-data.ts diff --git a/src/features/cross-chain/calculation-manager/providers/bridgers-provider/evm-bridgers-trade/evm-bridgers-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/networks/evm-bridgers-cross-chain-trade.ts similarity index 60% rename from src/features/cross-chain/calculation-manager/providers/bridgers-provider/evm-bridgers-trade/evm-bridgers-cross-chain-trade.ts rename to src/features/cross-chain/calculation-manager/providers/bridgers-provider/networks/evm-bridgers-cross-chain-trade.ts index 96f93d4bdfc..b546b7b74d4 100644 --- a/src/features/cross-chain/calculation-manager/providers/bridgers-provider/evm-bridgers-trade/evm-bridgers-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/networks/evm-bridgers-cross-chain-trade.ts @@ -1,25 +1,34 @@ import BigNumber from 'bignumber.js'; +import { NotSupportedTokensError } from 'src/common/errors'; +import { NotSupportedRegionError } from 'src/common/errors/swap/not-supported-region'; import { PriceTokenAmount } from 'src/common/tokens'; -import { - BLOCKCHAIN_NAME, - EvmBlockchainName, - TronBlockchainName -} from 'src/core/blockchain/models/blockchain-name'; +import { BLOCKCHAIN_NAME, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; import { BlockchainsInfo } from 'src/core/blockchain/utils/blockchains-info/blockchains-info'; -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 { TronWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/tron-web3-pure'; +import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; import { Injector } from 'src/core/injector/injector'; import { ContractParams } from 'src/features/common/models/contract-params'; -import { EncodeTransactionOptions } from 'src/features/common/models/encode-transaction-options'; -import { SwapTransactionOptions } from 'src/features/common/models/swap-transaction-options'; +import { bridgersNativeAddress } from 'src/features/common/providers/bridgers/constants/bridgers-native-address'; +import { toBridgersBlockchain } from 'src/features/common/providers/bridgers/constants/to-bridgers-blockchain'; import { bridgersContractAddresses } from 'src/features/common/providers/bridgers/models/bridgers-contract-addresses'; +import { + BridgersQuoteRequest, + BridgersQuoteResponse +} from 'src/features/common/providers/bridgers/models/bridgers-quote-api'; +import { + BridgersSwapRequest, + BridgersSwapResponse +} from 'src/features/common/providers/bridgers/models/bridgers-swap-api'; import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; +import { createTokenNativeAddressProxy } from 'src/features/common/utils/token-native-address-proxy'; import { CROSS_CHAIN_TRADE_TYPE } from 'src/features/cross-chain/calculation-manager/models/cross-chain-trade-type'; -import { BridgersEvmCrossChainSupportedBlockchain } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/constants/bridgers-cross-chain-supported-blockchain'; -import { EvmBridgersTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/evm-bridgers-trade/models/evm-bridgers-transaction-data'; -import { getProxyMethodArgumentsAndTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/utils/get-proxy-method-arguments-and-transaction-data'; +import { BridgersCrossChainSupportedBlockchain } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/constants/bridgers-cross-chain-supported-blockchain'; +import { + BridgersCrossChainGasParams, + BridgersEvmCrossChainParams +} from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/bridgers-cross-chain-trade-types'; +import { EvmBridgersTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/evm-bridgers-transaction-data'; import { rubicProxyContractAddress } from 'src/features/cross-chain/calculation-manager/providers/common/constants/rubic-proxy-contract-address'; import { evmCommonCrossChainAbi } from 'src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/constants/evm-common-cross-chain-abi'; import { gatewayRubicCrossChainAbi } from 'src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/constants/gateway-rubic-cross-chain-abi'; @@ -28,7 +37,6 @@ import { GasData } from 'src/features/cross-chain/calculation-manager/providers/ import { BRIDGE_TYPE } from 'src/features/cross-chain/calculation-manager/providers/common/models/bridge-type'; import { FeeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/fee-info'; import { GetContractParamsOptions } from 'src/features/cross-chain/calculation-manager/providers/common/models/get-contract-params-options'; -import { RubicStep } from 'src/features/cross-chain/calculation-manager/providers/common/models/rubicStep'; import { TradeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/trade-info'; import { ProxyCrossChainEvmTrade } from 'src/features/cross-chain/calculation-manager/providers/common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade'; import { getCrossChainGasData } from 'src/features/cross-chain/calculation-manager/utils/get-cross-chain-gas-data'; @@ -37,40 +45,33 @@ import { MarkRequired } from 'ts-essentials'; export class EvmBridgersCrossChainTrade extends EvmCrossChainTrade { /** @internal */ public static async getGasData( - from: PriceTokenAmount, - to: PriceTokenAmount, - receiverAddress: string, - providerAddress: string, - feeInfo: FeeInfo + params: BridgersCrossChainGasParams ): Promise { - const trade = new EvmBridgersCrossChainTrade( - { - from, - to, + const tradeStruct = { + crossChainTrade: { + from: params.from, + to: params.to, toTokenAmountMin: new BigNumber(0), - feeInfo, + feeInfo: params.feeInfo, gasData: null, slippage: 0 }, - providerAddress || EvmWeb3Pure.EMPTY_ADDRESS, - [], - false - ); - - return getCrossChainGasData(trade, receiverAddress); - } + providerAddress: params.providerAddress || EvmWeb3Pure.EMPTY_ADDRESS, + routePath: [], + useProxy: false + }; + const trade = new EvmBridgersCrossChainTrade(tradeStruct); - private get tronWeb3Public(): TronWeb3Public { - return Injector.web3PublicService.getWeb3Public(BLOCKCHAIN_NAME.TRON); + return getCrossChainGasData(trade, params.receiverAddress); } public readonly type = CROSS_CHAIN_TRADE_TYPE.BRIDGERS; public readonly isAggregator = false; - public readonly from: PriceTokenAmount; + public readonly from: PriceTokenAmount; - public readonly to: PriceTokenAmount; + public readonly to: PriceTokenAmount; public readonly toTokenAmountMin: BigNumber; @@ -89,26 +90,17 @@ export class EvmBridgersCrossChainTrade extends EvmCrossChainTrade { protected get fromContractAddress(): string { return this.isProxyTrade ? rubicProxyContractAddress[this.from.blockchain].gateway - : bridgersContractAddresses[this.from.blockchain]; + : bridgersContractAddresses[ + this.from.blockchain as BridgersCrossChainSupportedBlockchain + ]; } protected get methodName(): string { return 'startBridgeTokensViaGenericCrossChain'; } - constructor( - crossChainTrade: { - from: PriceTokenAmount; - to: PriceTokenAmount; - toTokenAmountMin: BigNumber; - feeInfo: FeeInfo; - gasData: GasData; - slippage: number; - }, - providerAddress: string, - routePath: RubicStep[], - useProxy: boolean - ) { + constructor(params: BridgersEvmCrossChainParams) { + const { crossChainTrade, providerAddress, routePath, useProxy } = params; super(providerAddress, routePath, useProxy); this.from = crossChainTrade.from; @@ -120,61 +112,6 @@ export class EvmBridgersCrossChainTrade extends EvmCrossChainTrade { this.slippage = crossChainTrade.slippage; } - protected override async swapDirect( - options: MarkRequired - ): Promise { - await this.checkTradeErrors(); - await this.checkReceiverAddress(options.receiverAddress, true); - - await this.checkAllowanceAndApprove(options); - - const { onConfirm, gasPriceOptions } = options; - let transactionHash: string; - const onTransactionHash = (hash: string) => { - if (onConfirm) { - onConfirm(hash); - } - transactionHash = hash; - }; - - // eslint-disable-next-line no-useless-catch - try { - const fromWithoutFee = getFromWithoutFee( - this.from, - this.feeInfo.rubicProxy?.platformFee?.percent - ); - - const { transactionData } = - await getProxyMethodArgumentsAndTransactionData( - this.from, - fromWithoutFee, - this.to, - this.toTokenAmountMin, - this.walletAddress, - this.providerAddress, - options, - this.checkAmountChange - ); - - await this.web3Private.trySendTransaction(transactionData.to, { - data: transactionData.data, - value: transactionData.value, - onTransactionHash, - gasPriceOptions - }); - - return transactionHash!; - } catch (err) { - throw err; - } - } - - public async encode( - options: MarkRequired - ): Promise { - return super.encode(options); - } - protected async getContractParams( options: MarkRequired ): Promise { @@ -261,21 +198,65 @@ export class EvmBridgersCrossChainTrade extends EvmCrossChainTrade { protected async getTransactionConfigAndAmount( receiverAddress?: string ): Promise<{ config: EvmBridgersTransactionData; amount: string }> { + const fromBlockchain = this.from.blockchain as BridgersCrossChainSupportedBlockchain; + const toBlockchain = this.to.blockchain as BridgersCrossChainSupportedBlockchain; + const fromWithoutFee = getFromWithoutFee( this.from, this.feeInfo.rubicProxy?.platformFee?.percent ); - const { transactionData: config, amountOut: amount } = - await getProxyMethodArgumentsAndTransactionData( - this.from, - fromWithoutFee, - this.to, - this.toTokenAmountMin, - this.walletAddress, - this.providerAddress, - { receiverAddress: receiverAddress! }, - this.checkAmountChange - ); + const amountOutMin = Web3Pure.toWei(this.toTokenAmountMin, this.to.decimals); + + const fromTokenAddress = createTokenNativeAddressProxy( + fromWithoutFee, + bridgersNativeAddress, + true + ).address; + + const toTokenAddress = createTokenNativeAddressProxy( + this.to, + bridgersNativeAddress, + this.to.blockchain !== BLOCKCHAIN_NAME.TRON + ).address; + + const fromAddress = this.walletAddress; + const swapRequest: BridgersSwapRequest = { + fromTokenAddress, + toTokenAddress, + fromAddress, + toAddress: receiverAddress!, + fromTokenChain: toBridgersBlockchain[fromBlockchain], + toTokenChain: toBridgersBlockchain[toBlockchain], + fromTokenAmount: fromWithoutFee.stringWeiAmount, + amountOutMin, + equipmentNo: fromAddress.slice(0, 32), + sourceFlag: 'rubic' + }; + + const swapData = await Injector.httpClient.post< + BridgersSwapResponse + >('https://sswap.swft.pro/api/sswap/swap', swapRequest); + if (swapData.resCode === 1146) { + throw new NotSupportedRegionError(); + } + if (!swapData.data?.txData) { + throw new NotSupportedTokensError(); + } + + const config = swapData.data?.txData; + + const quoteRequest: BridgersQuoteRequest = { + fromTokenAddress, + toTokenAddress, + fromTokenAmount: fromWithoutFee.stringWeiAmount, + fromTokenChain: toBridgersBlockchain[fromBlockchain], + toTokenChain: toBridgersBlockchain[toBlockchain] + }; + const quoteResponse = await Injector.httpClient.post( + 'https://sswap.swft.pro/api/sswap/quote', + quoteRequest + ); + const amount = quoteResponse.data?.txData?.amountOutMin; return { config, amount }; } diff --git a/src/features/cross-chain/calculation-manager/providers/bridgers-provider/networks/tron-bridgers-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/networks/tron-bridgers-cross-chain-trade.ts new file mode 100644 index 00000000000..08bc3e30fd3 --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/networks/tron-bridgers-cross-chain-trade.ts @@ -0,0 +1,168 @@ +import BigNumber from 'bignumber.js'; +import { NotSupportedTokensError } from 'src/common/errors'; +import { NotSupportedRegionError } from 'src/common/errors/swap/not-supported-region'; +import { PriceTokenAmount } from 'src/common/tokens'; +import { BLOCKCHAIN_NAME, TronBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +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 { Injector } from 'src/core/injector/injector'; +import { bridgersNativeAddress } from 'src/features/common/providers/bridgers/constants/bridgers-native-address'; +import { toBridgersBlockchain } from 'src/features/common/providers/bridgers/constants/to-bridgers-blockchain'; +import { bridgersContractAddresses } from 'src/features/common/providers/bridgers/models/bridgers-contract-addresses'; +import { + BridgersQuoteRequest, + BridgersQuoteResponse +} from 'src/features/common/providers/bridgers/models/bridgers-quote-api'; +import { + BridgersSwapRequest, + BridgersSwapResponse +} from 'src/features/common/providers/bridgers/models/bridgers-swap-api'; +import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; +import { createTokenNativeAddressProxy } from 'src/features/common/utils/token-native-address-proxy'; +import { CROSS_CHAIN_TRADE_TYPE } from 'src/features/cross-chain/calculation-manager/models/cross-chain-trade-type'; +import { BridgersCrossChainSupportedBlockchain } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/constants/bridgers-cross-chain-supported-blockchain'; +import { BridgersTronCrossChainParams } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/bridgers-cross-chain-trade-types'; +import { TronBridgersTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/tron-bridgers-transaction-data'; +import { BRIDGE_TYPE } from 'src/features/cross-chain/calculation-manager/providers/common/models/bridge-type'; +import { FeeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/fee-info'; +import { TradeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/trade-info'; +import { TronContractParams } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/models/tron-contract-params'; +import { TronGetContractParamsOptions } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/models/tron-get-contract-params-options'; +import { TronCrossChainTrade } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/tron-cross-chain-trade'; + +export class TronBridgersCrossChainTrade extends TronCrossChainTrade { + public readonly type = CROSS_CHAIN_TRADE_TYPE.BRIDGERS; + + public readonly isAggregator = false; + + public readonly from: PriceTokenAmount; + + public readonly to: PriceTokenAmount; + + public readonly toTokenAmountMin: BigNumber; + + public readonly feeInfo: FeeInfo; + + public readonly onChainSubtype = { from: undefined, to: undefined }; + + public readonly bridgeType = BRIDGE_TYPE.BRIDGERS; + + public readonly priceImpact: number | null; + + private readonly slippage: number; + + protected get fromContractAddress(): string { + return bridgersContractAddresses.TRON; + } + + protected get methodName(): string { + return ''; + } + + constructor(params: BridgersTronCrossChainParams) { + const { crossChainTrade, providerAddress, routePath } = params; + super(providerAddress, routePath, false); + + this.from = crossChainTrade.from; + this.to = crossChainTrade.to; + this.toTokenAmountMin = crossChainTrade.toTokenAmountMin; + this.feeInfo = crossChainTrade.feeInfo; + this.priceImpact = this.from.calculatePriceImpactPercent(this.to); + this.slippage = crossChainTrade.slippage; + } + + protected async getContractParams( + _options: TronGetContractParamsOptions + ): Promise { + throw new Error('Not implemeted'); + } + + public getTradeAmountRatio(fromUsd: BigNumber): BigNumber { + return fromUsd.dividedBy(this.to.tokenAmount); + } + + public getTradeInfo(): TradeInfo { + return { + estimatedGas: null, + feeInfo: this.feeInfo, + priceImpact: this.priceImpact ?? null, + slippage: this.slippage * 100, + routePath: this.routePath + }; + } + + protected async getTransactionConfigAndAmount( + receiverAddress?: string + ): Promise<{ config: TronTransactionConfig; amount: string }> { + const fromBlockchain = this.from.blockchain as BridgersCrossChainSupportedBlockchain; + const toBlockchain = this.to.blockchain as BridgersCrossChainSupportedBlockchain; + + const fromWithoutFee = getFromWithoutFee( + this.from, + this.feeInfo.rubicProxy?.platformFee?.percent + ); + const amountOutMin = Web3Pure.toWei(this.toTokenAmountMin, this.to.decimals); + + const fromTokenAddress = createTokenNativeAddressProxy( + fromWithoutFee, + bridgersNativeAddress, + false + ).address; + + const toTokenAddress = createTokenNativeAddressProxy( + this.to, + bridgersNativeAddress, + this.to.blockchain !== BLOCKCHAIN_NAME.TRON + ).address; + + const fromAddress = this.walletAddress; + const swapRequest: BridgersSwapRequest = { + fromTokenAddress, + toTokenAddress, + fromAddress, + toAddress: receiverAddress!, + fromTokenChain: toBridgersBlockchain[fromBlockchain], + toTokenChain: toBridgersBlockchain[toBlockchain], + fromTokenAmount: fromWithoutFee.stringWeiAmount, + amountOutMin, + equipmentNo: fromAddress.slice(0, 32), + sourceFlag: 'rubic' + }; + + const swapData = await Injector.httpClient.post< + BridgersSwapResponse + >('https://sswap.swft.pro/api/sswap/swap', swapRequest); + if (swapData.resCode === 1146) { + throw new NotSupportedRegionError(); + } + if (!swapData.data?.txData) { + throw new NotSupportedTokensError(); + } + + const config = swapData.data?.txData; + + const quoteRequest: BridgersQuoteRequest = { + fromTokenAddress, + toTokenAddress, + fromTokenAmount: fromWithoutFee.stringWeiAmount, + fromTokenChain: toBridgersBlockchain[fromBlockchain], + toTokenChain: toBridgersBlockchain[toBlockchain] + }; + const quoteResponse = await Injector.httpClient.post( + 'https://sswap.swft.pro/api/sswap/quote', + quoteRequest + ); + const amount = quoteResponse.data?.txData?.amountOutMin; + + return { + amount, + config: { + signature: config.functionName, + arguments: config.parameter, + to: config.to, + feeLimit: config?.options?.feeLimit, + callValue: config?.options?.callValue + } + }; + } +} diff --git a/src/features/cross-chain/calculation-manager/providers/bridgers-provider/tron-bridgers-trade/tron-bridgers-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/tron-bridgers-trade/tron-bridgers-cross-chain-trade.ts deleted file mode 100644 index 830bda257c0..00000000000 --- a/src/features/cross-chain/calculation-manager/providers/bridgers-provider/tron-bridgers-trade/tron-bridgers-cross-chain-trade.ts +++ /dev/null @@ -1,223 +0,0 @@ -import BigNumber from 'bignumber.js'; -import { PriceTokenAmount } from 'src/common/tokens'; -import { TronBlockchainName } from 'src/core/blockchain/models/blockchain-name'; -import { TronTransactionConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config'; -import { TronWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/tron-web3-pure'; -import { SwapTransactionOptions } from 'src/features/common/models/swap-transaction-options'; -import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; -import { CROSS_CHAIN_TRADE_TYPE } from 'src/features/cross-chain/calculation-manager/models/cross-chain-trade-type'; -import { BridgersEvmCrossChainSupportedBlockchain } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/constants/bridgers-cross-chain-supported-blockchain'; -import { TronBridgersTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/tron-bridgers-trade/models/tron-bridgers-transaction-data'; -import { getProxyMethodArgumentsAndTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/utils/get-proxy-method-arguments-and-transaction-data'; -import { BRIDGE_TYPE } from 'src/features/cross-chain/calculation-manager/providers/common/models/bridge-type'; -import { FeeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/fee-info'; -import { RubicStep } from 'src/features/cross-chain/calculation-manager/providers/common/models/rubicStep'; -import { TradeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/trade-info'; -import { tronCommonCrossChainAbi } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/constants/tron-common-cross-chain-abi'; -import { tronNativeSwapAbi } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/constants/tron-native-swap-abi'; -import { TronContractParams } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/models/tron-contract-params'; -import { TronGetContractParamsOptions } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/models/tron-get-contract-params-options'; -import { TronCrossChainTrade } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/tron-cross-chain-trade'; -import { MarkRequired } from 'ts-essentials'; - -export class TronBridgersCrossChainTrade extends TronCrossChainTrade { - public readonly type = CROSS_CHAIN_TRADE_TYPE.BRIDGERS; - - public readonly isAggregator = false; - - public readonly from: PriceTokenAmount; - - public readonly to: PriceTokenAmount; - - public readonly toTokenAmountMin: BigNumber; - - public readonly feeInfo: FeeInfo; - - public readonly onChainSubtype = { from: undefined, to: undefined }; - - public readonly bridgeType = BRIDGE_TYPE.BRIDGERS; - - public readonly priceImpact: number | null; - - private readonly slippage: number; - - private readonly contractAddress: string; - - protected get fromContractAddress(): string { - // return rubicProxyContractAddress[this.from.blockchain]; - return this.contractAddress; - } - - protected get methodName(): string { - return ''; - } - - constructor( - crossChainTrade: { - from: PriceTokenAmount; - to: PriceTokenAmount; - toTokenAmountMin: BigNumber; - feeInfo: FeeInfo; - slippage: number; - contractAddress: string; - }, - providerAddress: string, - routePath: RubicStep[] - ) { - super(providerAddress, routePath, false); - - this.from = crossChainTrade.from; - this.to = crossChainTrade.to; - this.toTokenAmountMin = crossChainTrade.toTokenAmountMin; - this.feeInfo = crossChainTrade.feeInfo; - this.priceImpact = this.from.calculatePriceImpactPercent(this.to); - this.slippage = crossChainTrade.slippage; - this.contractAddress = crossChainTrade.contractAddress; - } - - public async swap( - options: MarkRequired - ): Promise { - return this.swapDirect(options); - } - - private async swapDirect( - options: MarkRequired - ): Promise { - await this.checkTradeErrors(); - await this.checkReceiverAddress(options.receiverAddress, true); - await this.checkAllowanceAndApprove(options); - - const { onConfirm } = options; - let transactionHash: string; - const onTransactionHash = (hash: string) => { - if (onConfirm) { - onConfirm(hash); - } - transactionHash = hash; - }; - - // eslint-disable-next-line no-useless-catch - try { - const fromWithoutFee = getFromWithoutFee( - this.from, - this.feeInfo.rubicProxy?.platformFee?.percent - ); - - const { transactionData } = - await getProxyMethodArgumentsAndTransactionData( - this.from, - fromWithoutFee, - this.to, - this.toTokenAmountMin, - this.walletAddress, - this.providerAddress, - options, - this.checkAmountChange - ); - - await this.web3Private.executeContractMethod( - transactionData.to, - tronNativeSwapAbi, - this.from.isNative ? 'swapEth' : 'swap', - transactionData.parameter.map(el => el.value), - { - onTransactionHash, - callValue: transactionData.options.callValue, - feeLimit: transactionData.options.feeLimit - } - ); - - return transactionHash!; - } catch (err) { - throw err; - } - } - - protected async getContractParams( - options: TronGetContractParamsOptions - ): Promise { - const fromWithoutFee = getFromWithoutFee( - this.from, - this.feeInfo.rubicProxy?.platformFee?.percent - ); - const { methodArguments, transactionData } = - await getProxyMethodArgumentsAndTransactionData( - this.from, - fromWithoutFee, - this.to, - this.toTokenAmountMin, - this.walletAddress, - this.providerAddress, - options, - this.checkAmountChange - ); - - const encodedData = TronWeb3Pure.encodeMethodSignature( - transactionData.functionName, - transactionData.parameter - ); - methodArguments.push(encodedData); - - const value = this.getSwapValue(transactionData.options.callValue); - const { feeLimit } = transactionData.options; - - return { - contractAddress: this.fromContractAddress, - contractAbi: tronCommonCrossChainAbi, - methodName: this.methodName, - methodArguments, - value, - feeLimit - }; - } - - public getTradeAmountRatio(fromUsd: BigNumber): BigNumber { - return fromUsd.dividedBy(this.to.tokenAmount); - } - - public getTradeInfo(): TradeInfo { - return { - estimatedGas: null, - feeInfo: this.feeInfo, - priceImpact: this.priceImpact ?? null, - slippage: this.slippage * 100, - routePath: this.routePath - }; - } - - protected async getTransactionConfigAndAmount( - receiverAddress?: string - ): Promise<{ config: TronTransactionConfig; amount: string }> { - const fromWithoutFee = getFromWithoutFee( - this.from, - this.feeInfo.rubicProxy?.platformFee?.percent - ); - const { transactionData, amountOut } = - await getProxyMethodArgumentsAndTransactionData( - this.from, - fromWithoutFee, - this.to, - this.toTokenAmountMin, - this.walletAddress, - this.providerAddress, - { receiverAddress: receiverAddress! }, - this.checkAmountChange - ); - - const encodedData = TronWeb3Pure.encodeMethodSignature( - transactionData.functionName, - transactionData.parameter - ); - - return { - amount: amountOut, - config: { - data: encodedData, - callValue: transactionData.options.callValue, - feeLimit: transactionData.options.feeLimit, - to: transactionData.to - } - }; - } -} diff --git a/src/features/cross-chain/calculation-manager/providers/bridgers-provider/utils/get-proxy-method-arguments-and-transaction-data.ts b/src/features/cross-chain/calculation-manager/providers/bridgers-provider/utils/get-proxy-method-arguments-and-transaction-data.ts deleted file mode 100644 index b8a1a92f4ce..00000000000 --- a/src/features/cross-chain/calculation-manager/providers/bridgers-provider/utils/get-proxy-method-arguments-and-transaction-data.ts +++ /dev/null @@ -1,133 +0,0 @@ -import BigNumber from 'bignumber.js'; -import { NotSupportedTokensError } from 'src/common/errors'; -import { NotSupportedRegionError } from 'src/common/errors/swap/not-supported-region'; -import { PriceTokenAmount } from 'src/common/tokens'; -import { BLOCKCHAIN_NAME } 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 { TronWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/tron-web3-pure'; -import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; -import { Injector } from 'src/core/injector/injector'; -import { bridgersNativeAddress } from 'src/features/common/providers/bridgers/constants/bridgers-native-address'; -import { toBridgersBlockchain } from 'src/features/common/providers/bridgers/constants/to-bridgers-blockchain'; -import { bridgersContractAddresses } from 'src/features/common/providers/bridgers/models/bridgers-contract-addresses'; -import { - BridgersQuoteRequest, - BridgersQuoteResponse -} from 'src/features/common/providers/bridgers/models/bridgers-quote-api'; -import { - BridgersSwapRequest, - BridgersSwapResponse -} from 'src/features/common/providers/bridgers/models/bridgers-swap-api'; -import { createTokenNativeAddressProxy } from 'src/features/common/utils/token-native-address-proxy'; -import { BridgersCrossChainSupportedBlockchain } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/constants/bridgers-cross-chain-supported-blockchain'; -import { EvmBridgersTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/evm-bridgers-trade/models/evm-bridgers-transaction-data'; -import { TronBridgersTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/tron-bridgers-trade/models/tron-bridgers-transaction-data'; -import { GetContractParamsOptions } from 'src/features/cross-chain/calculation-manager/providers/common/models/get-contract-params-options'; -import { MarkRequired } from 'ts-essentials'; - -export async function getProxyMethodArgumentsAndTransactionData< - T extends EvmBridgersTransactionData | TronBridgersTransactionData ->( - from: PriceTokenAmount, - fromWithoutFee: PriceTokenAmount, - to: PriceTokenAmount, - toTokenAmountMin: BigNumber, - walletAddress: string, - providerAddress: string, - options: MarkRequired, - checkAmountFn: (newWeiAmount: string, oldWeiAmount: string) => void -): Promise<{ - methodArguments: unknown[]; - transactionData: T; - amountOut: string; -}> { - const amountOutMin = Web3Pure.toWei(toTokenAmountMin, to.decimals); - const fromTokenAddress = createTokenNativeAddressProxy( - fromWithoutFee, - bridgersNativeAddress, - from.blockchain !== BLOCKCHAIN_NAME.TRON - ).address; - const toTokenAddress = createTokenNativeAddressProxy( - to, - bridgersNativeAddress, - to.blockchain !== BLOCKCHAIN_NAME.TRON - ).address; - const fromAddress = options.fromAddress || walletAddress; - const swapRequest: BridgersSwapRequest = { - fromTokenAddress, - toTokenAddress, - fromAddress, - toAddress: options.receiverAddress, - fromTokenChain: toBridgersBlockchain[fromWithoutFee.blockchain], - toTokenChain: toBridgersBlockchain[to.blockchain], - fromTokenAmount: fromWithoutFee.stringWeiAmount, - amountOutMin, - equipmentNo: fromAddress.slice(0, 32), - sourceFlag: 'rubic' - }; - - const swapData = await Injector.httpClient.post>( - 'https://sswap.swft.pro/api/sswap/swap', - swapRequest - ); - if (swapData.resCode === 1146) { - throw new NotSupportedRegionError(); - } - if (!swapData.data?.txData) { - throw new NotSupportedTokensError(); - } - - const transactionData = swapData.data?.txData; - - const quoteRequest: BridgersQuoteRequest = { - fromTokenAddress, - toTokenAddress, - fromTokenAmount: fromWithoutFee.stringWeiAmount, - fromTokenChain: toBridgersBlockchain[from.blockchain], - toTokenChain: toBridgersBlockchain[to.blockchain] - }; - const quoteResponse = await Injector.httpClient.post( - 'https://sswap.swft.pro/api/sswap/quote', - quoteRequest - ); - const transactionQuoteData = quoteResponse.data?.txData; - - if (transactionQuoteData?.amountOutMin) { - checkAmountFn( - transactionQuoteData.amountOutMin, - Web3Pure.toWei(toTokenAmountMin, to.decimals) - ); - } - - const dstTokenAddress = BlockchainsInfo.isTronBlockchainName(to.blockchain) - ? TronWeb3Pure.addressToHex(to.address) - : to.address; - const receiverAddress = BlockchainsInfo.isTronBlockchainName(to.blockchain) - ? TronWeb3Pure.addressToHex(options.receiverAddress) - : options.receiverAddress; - const contractAddress = transactionData?.to || bridgersContractAddresses[from.blockchain]; - - const methodArguments: unknown[] = [ - 'native:bridgers', - [ - from.address, - from.stringWeiAmount, - blockchainId[to.blockchain], - dstTokenAddress, - amountOutMin, - receiverAddress, - providerAddress, - contractAddress - ] - ]; - if (!from.isNative) { - methodArguments.push(contractAddress); - } - - return { - methodArguments, - transactionData: { ...transactionData, to: contractAddress }, - amountOut: amountOutMin - }; -} diff --git a/src/features/cross-chain/calculation-manager/providers/changenow-provider/changenow-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/changenow-provider/changenow-cross-chain-trade.ts index 961f6b0efbd..90e758b2310 100644 --- a/src/features/cross-chain/calculation-manager/providers/changenow-provider/changenow-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/changenow-provider/changenow-cross-chain-trade.ts @@ -194,7 +194,7 @@ export class ChangenowCrossChainTrade extends EvmCrossChainTrade { public async swapDirect(options: SwapTransactionOptions = {}): Promise { if (!BlockchainsInfo.isEvmBlockchainName(this.from.blockchain)) { - throw new RubicSdkError("For non-evm chains use 'getChangenowPostTrade' method"); + throw new RubicSdkError("For non-evm networks use 'getChangenowPostTrade' method"); } await this.checkTradeErrors(); diff --git a/src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/evm-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/evm-cross-chain-trade.ts index 4c4f0f1f2b6..f3d9ec1e807 100644 --- a/src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/evm-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/evm-cross-chain-trade.ts @@ -241,63 +241,6 @@ export abstract class EvmCrossChainTrade extends CrossChainTrade { - await this.checkTradeErrors(); - await this.checkReceiverAddress( - options.receiverAddress, - !BlockchainsInfo.isEvmBlockchainName(this.to.blockchain) - ); - - await this.checkAllowanceAndApprove(options); - - const { onConfirm, gasPriceOptions } = options; - let transactionHash: string; - const onTransactionHash = (hash: string) => { - if (onConfirm) { - onConfirm(hash); - } - transactionHash = hash; - }; - - const { contractAddress, contractAbi, methodName, methodArguments, value } = - await this.getContractParams(options, false); - - try { - let method: 'tryExecuteContractMethod' | 'executeContractMethod' = - 'tryExecuteContractMethod'; - if (options?.testMode) { - console.info( - contractAddress, - contractAbi, - methodName, - methodName, - value, - gasPriceOptions - ); - method = 'executeContractMethod'; - } - - await this.web3Private[method]( - contractAddress, - contractAbi, - methodName, - methodArguments, - { - value, - onTransactionHash, - gasPriceOptions - } - ); - - return transactionHash!; - } catch (err) { - if (err instanceof FailedToCheckForTransactionReceiptError) { - return transactionHash!; - } - throw err; - } - } - public async encode(options: EncodeTransactionOptions): Promise { await this.checkFromAddress(options.fromAddress, true); await this.checkReceiverAddress( diff --git a/src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/tron-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/tron-cross-chain-trade.ts index b7c9a7bd709..59bb029fdf9 100644 --- a/src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/tron-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/tron-cross-chain-trade.ts @@ -9,13 +9,10 @@ import { TronTransactionOptions } from 'src/core/blockchain/web3-private-service import { TronWeb3Private } from 'src/core/blockchain/web3-private-service/web3-private/tron-web3-private/tron-web3-private'; import { TronWeb3Public } from 'src/core/blockchain/web3-public-service/web3-public/tron-web3-public/tron-web3-public'; import { TronTransactionConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config'; -import { TronWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/tron-web3-pure'; import { Injector } from 'src/core/injector/injector'; import { EncodeTransactionOptions } from 'src/features/common/models/encode-transaction-options'; import { SwapTransactionOptions } from 'src/features/common/models/swap-transaction-options'; import { CrossChainTrade } from 'src/features/cross-chain/calculation-manager/providers/common/cross-chain-trade'; -import { TronContractParams } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/models/tron-contract-params'; -import { TronGetContractParamsOptions } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/models/tron-get-contract-params-options'; import { MarkRequired } from 'ts-essentials'; export abstract class TronCrossChainTrade extends CrossChainTrade { @@ -70,10 +67,11 @@ export abstract class TronCrossChainTrade extends CrossChainTrade ): Promise { - await this.checkTradeErrors(); + if (!options?.testMode) { + await this.checkTradeErrors(); + } await this.checkReceiverAddress(options.receiverAddress, true); - - await this.checkAllowanceAndApprove(options); + const method = options?.testMode ? 'sendTransaction' : 'trySendTransaction'; const { onConfirm } = options; let transactionHash: string; @@ -84,19 +82,18 @@ export abstract class TronCrossChainTrade extends CrossChainTrade; - public getUsdPrice(): BigNumber { let feeSum = new BigNumber(0); const providerFee = this.feeInfo.provider?.cryptoFee; diff --git a/src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-contract-addresses.ts b/src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-contract-addresses.ts index 2478801c048..3a7e8e3adb6 100644 --- a/src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-contract-addresses.ts +++ b/src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-contract-addresses.ts @@ -37,5 +37,6 @@ export const mesonContractAddresses: Record = [BLOCKCHAIN_NAME.CORE]: '0x25aB3Efd52e6470681CE037cD546Dc60726948D3', [BLOCKCHAIN_NAME.KROMA]: '0x25aB3Efd52e6470681CE037cD546Dc60726948D3', // [BLOCKCHAIN_NAME.TAIKO]: '0x25aB3Efd52e6470681CE037cD546Dc60726948D3', - [BLOCKCHAIN_NAME.BITLAYER]: '0x25aB3Efd52e6470681CE037cD546Dc60726948D3' + [BLOCKCHAIN_NAME.BITLAYER]: '0x25aB3Efd52e6470681CE037cD546Dc60726948D3', + [BLOCKCHAIN_NAME.TRON]: 'TKWqpzNucNNBMpfaE47F8CLhA8vzfNndH4' }; diff --git a/src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-cross-chain-supported-chains.ts b/src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-cross-chain-supported-chains.ts index 499d174ad40..c66a118e6c9 100644 --- a/src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-cross-chain-supported-chains.ts +++ b/src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-cross-chain-supported-chains.ts @@ -25,7 +25,7 @@ export const mesonCrossChainSupportedChains = [ BLOCKCHAIN_NAME.POLYGON, BLOCKCHAIN_NAME.SCROLL, // BLOCKCHAIN_NAME.SOLANA, - // BLOCKCHAIN_NAME.TRON, + BLOCKCHAIN_NAME.TRON, BLOCKCHAIN_NAME.XLAYER, BLOCKCHAIN_NAME.ZETACHAIN, BLOCKCHAIN_NAME.POLYGON_ZKEVM, diff --git a/src/features/cross-chain/calculation-manager/providers/meson-provider/meson-cross-chain-factory.ts b/src/features/cross-chain/calculation-manager/providers/meson-provider/meson-cross-chain-factory.ts new file mode 100644 index 00000000000..32cbc1555ea --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/meson-provider/meson-cross-chain-factory.ts @@ -0,0 +1,37 @@ +import { BlockchainName, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { BlockchainsInfo } from 'src/core/blockchain/utils/blockchains-info/blockchains-info'; +import { GasData } from 'src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/models/gas-data'; +import { + MesonCrossChainEvmTradeConstructorParams, + MesonGetGasDataParams +} from 'src/features/cross-chain/calculation-manager/providers/meson-provider/models/meson-trade-types'; +import { MesonCrossChainEvmTrade } from 'src/features/cross-chain/calculation-manager/providers/meson-provider/networks/meson-cross-chain-evm-trade'; + +export class MesonCrossChainFactory { + public static createTrade( + params: MesonCrossChainEvmTradeConstructorParams + ): MesonCrossChainEvmTrade { + const fromBlockchain = params.crossChainTrade.from.blockchain; + + if (BlockchainsInfo.isEvmBlockchainName(fromBlockchain)) { + return new MesonCrossChainEvmTrade(params); + } + throw new Error('Can not create trade instance'); + } + + public static async getGasData( + calculateGas: boolean, + params: MesonGetGasDataParams + ): Promise { + if (calculateGas) { + const fromBlockchain = params.from.blockchain; + + if (BlockchainsInfo.isEvmBlockchainName(fromBlockchain)) { + return MesonCrossChainEvmTrade.getGasData( + params as MesonGetGasDataParams + ); + } + } + return null; + } +} diff --git a/src/features/cross-chain/calculation-manager/providers/meson-provider/meson-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/meson-provider/meson-cross-chain-provider.ts index ef458ad8262..f969b5f83e9 100644 --- a/src/features/cross-chain/calculation-manager/providers/meson-provider/meson-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/meson-provider/meson-cross-chain-provider.ts @@ -8,10 +8,14 @@ import { } from 'src/common/errors'; import { PriceToken, PriceTokenAmount } from 'src/common/tokens'; import { compareAddresses } from 'src/common/utils/blockchain'; -import { EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; -import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; +import { + BLOCKCHAIN_NAME, + BlockchainName, + EvmBlockchainName +} from 'src/core/blockchain/models/blockchain-name'; import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; -import Web3 from 'web3'; +import { MesonCrossChainFactory } from 'src/features/cross-chain/calculation-manager/providers/meson-provider/meson-cross-chain-factory'; +import { MesonCrossChainUtils } from 'src/features/cross-chain/calculation-manager/providers/meson-provider/services/meson-cross-chain-utils'; import { RequiredCrossChainOptions } from '../../models/cross-chain-options'; import { CrossChainProvider } from '../common/cross-chain-provider'; @@ -24,7 +28,6 @@ import { mesonCrossChainSupportedChains, MesonSupportedBlockchain } from './constants/meson-cross-chain-supported-chains'; -import { MesonCrossChainTrade } from './meson-cross-chain-trade'; import { MesonLimitsChain, MesonLimitsToken, SrcDstChainsIds } from './models/meson-api-types'; import { FetchedMesonTradeInfo } from './models/meson-provider-types'; import { MesonCcrApiService } from './services/meson-cross-chain-api-service'; @@ -44,7 +47,10 @@ export class MesonCrossChainProvider extends CrossChainProvider { options: RequiredCrossChainOptions ): Promise { const fromBlockchain = from.blockchain as MesonSupportedBlockchain; - const useProxy = options?.useProxy?.[this.type] ?? true; + let useProxy = options?.useProxy?.[this.type] ?? true; + if (fromBlockchain === BLOCKCHAIN_NAME.TRON) { + useProxy = false; + } try { if (!useProxy) { @@ -74,19 +80,19 @@ export class MesonCrossChainProvider extends CrossChainProvider { tokenAmount: toAmount }); - const gasData = - options.gasCalculation === 'enabled' - ? await MesonCrossChainTrade.getGasData({ - from: fromWith6Decimals, - feeInfo, - toToken: to, - providerAddress: options.providerAddress, - sourceAssetString, - targetAssetString - }) - : null; - - const trade = new MesonCrossChainTrade({ + const gasData = await MesonCrossChainFactory.getGasData( + options?.gasCalculation === 'enabled', + { + from: fromWith6Decimals, + feeInfo, + toToken: to, + providerAddress: options.providerAddress, + sourceAssetString, + targetAssetString + } + ); + + const trade = MesonCrossChainFactory.createTrade({ crossChainTrade: { feeInfo, from: fromWith6Decimals, @@ -157,12 +163,11 @@ export class MesonCrossChainProvider extends CrossChainProvider { } private getApiTokenInfo( - token: PriceToken, + token: PriceToken, apiChains: MesonLimitsChain[] ): MesonLimitsToken { - const chainId = blockchainId[token.blockchain]; - const hexChainId = Web3.utils.toHex(chainId); - const foundChain = apiChains.find(chain => compareAddresses(chain.chainId, hexChainId)); + const searchebleId = MesonCrossChainUtils.getSearchebleId(token.blockchain); + const foundChain = apiChains.find(chain => compareAddresses(chain.chainId, searchebleId)); if (!foundChain) { throw new NotSupportedBlockchain(); @@ -186,8 +191,8 @@ export class MesonCrossChainProvider extends CrossChainProvider { targetToken: PriceToken, apiChains: MesonLimitsChain[] ): SrcDstChainsIds { - const sourceChainIdHex = Web3.utils.toHex(blockchainId[sourceToken.blockchain]); - const targetChainIdHex = Web3.utils.toHex(blockchainId[targetToken.blockchain]); + const sourceChainIdHex = MesonCrossChainUtils.getSearchebleId(sourceToken.blockchain); + const targetChainIdHex = MesonCrossChainUtils.getSearchebleId(targetToken.blockchain); const ids = ['', ''] as SrcDstChainsIds; for (const chain of apiChains) { diff --git a/src/features/cross-chain/calculation-manager/providers/meson-provider/models/meson-trade-types.ts b/src/features/cross-chain/calculation-manager/providers/meson-provider/models/meson-trade-types.ts index bdfbf3e8695..e61e626f600 100644 --- a/src/features/cross-chain/calculation-manager/providers/meson-provider/models/meson-trade-types.ts +++ b/src/features/cross-chain/calculation-manager/providers/meson-provider/models/meson-trade-types.ts @@ -1,14 +1,18 @@ import { PriceTokenAmount } from 'src/common/tokens'; -import { EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { + BlockchainName, + EvmBlockchainName, + TronBlockchainName +} from 'src/core/blockchain/models/blockchain-name'; import { GasData } from '../../common/evm-cross-chain-trade/models/gas-data'; import { FeeInfo } from '../../common/models/fee-info'; import { RubicStep } from '../../common/models/rubicStep'; -export interface MesonCrossChainTradeConstructorParams { +export interface MesonCrossChainTradeConstructorParams { crossChainTrade: { - from: PriceTokenAmount; - to: PriceTokenAmount; + from: PriceTokenAmount; + to: PriceTokenAmount; gasData: GasData | null; feeInfo: FeeInfo; priceImpact: number | null; @@ -20,11 +24,16 @@ export interface MesonCrossChainTradeConstructorParams { useProxy: boolean; } -export interface MesonGetGasDataParams { - from: PriceTokenAmount; - toToken: PriceTokenAmount; +export interface MesonGetGasDataParams { + from: PriceTokenAmount; + toToken: PriceTokenAmount; feeInfo: FeeInfo; providerAddress: string; sourceAssetString: string; targetAssetString: string; } + +export type MesonCrossChainEvmTradeConstructorParams = + MesonCrossChainTradeConstructorParams; +export type MesonCrossChainTronTradeConstructorParams = + MesonCrossChainTradeConstructorParams; diff --git a/src/features/cross-chain/calculation-manager/providers/meson-provider/meson-cross-chain-trade.ts b/src/features/cross-chain/calculation-manager/providers/meson-provider/networks/meson-cross-chain-evm-trade.ts similarity index 64% rename from src/features/cross-chain/calculation-manager/providers/meson-provider/meson-cross-chain-trade.ts rename to src/features/cross-chain/calculation-manager/providers/meson-provider/networks/meson-cross-chain-evm-trade.ts index cefe00e06f5..2eec1acaae3 100644 --- a/src/features/cross-chain/calculation-manager/providers/meson-provider/meson-cross-chain-trade.ts +++ b/src/features/cross-chain/calculation-manager/providers/meson-provider/networks/meson-cross-chain-evm-trade.ts @@ -6,30 +6,36 @@ import { EvmWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-w 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 { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; - -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/evm-cross-chain-trade/constants/evm-common-cross-chain-abi'; -import { gatewayRubicCrossChainAbi } from '../common/evm-cross-chain-trade/constants/gateway-rubic-cross-chain-abi'; -import { EvmCrossChainTrade } from '../common/evm-cross-chain-trade/evm-cross-chain-trade'; -import { GasData } from '../common/evm-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 { TradeInfo } from '../common/models/trade-info'; -import { ProxyCrossChainEvmTrade } from '../common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade'; -import { MESON_ABI } from './constants/meson-abi'; -import { mesonContractAddresses } from './constants/meson-contract-addresses'; -import { MesonSupportedBlockchain } from './constants/meson-cross-chain-supported-chains'; import { - MesonCrossChainTradeConstructorParams, + CROSS_CHAIN_TRADE_TYPE, + CrossChainTradeType +} from 'src/features/cross-chain/calculation-manager/models/cross-chain-trade-type'; +import { rubicProxyContractAddress } from 'src/features/cross-chain/calculation-manager/providers/common/constants/rubic-proxy-contract-address'; +import { evmCommonCrossChainAbi } from 'src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/constants/evm-common-cross-chain-abi'; +import { gatewayRubicCrossChainAbi } from 'src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/constants/gateway-rubic-cross-chain-abi'; +import { EvmCrossChainTrade } from 'src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/evm-cross-chain-trade'; +import { GasData } from 'src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/models/gas-data'; +import { + BRIDGE_TYPE, + BridgeType +} from 'src/features/cross-chain/calculation-manager/providers/common/models/bridge-type'; +import { FeeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/fee-info'; +import { GetContractParamsOptions } from 'src/features/cross-chain/calculation-manager/providers/common/models/get-contract-params-options'; +import { OnChainSubtype } from 'src/features/cross-chain/calculation-manager/providers/common/models/on-chain-subtype'; +import { TradeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/trade-info'; +import { ProxyCrossChainEvmTrade } from 'src/features/cross-chain/calculation-manager/providers/common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade'; +import { MESON_ABI } from 'src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-abi'; +import { mesonContractAddresses } from 'src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-contract-addresses'; +import { MesonSupportedBlockchain } from 'src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-cross-chain-supported-chains'; +import { + MesonCrossChainEvmTradeConstructorParams, MesonGetGasDataParams -} from './models/meson-trade-types'; -import { MesonCcrApiService } from './services/meson-cross-chain-api-service'; +} from 'src/features/cross-chain/calculation-manager/providers/meson-provider/models/meson-trade-types'; +import { MesonCcrApiService } from 'src/features/cross-chain/calculation-manager/providers/meson-provider/services/meson-cross-chain-api-service'; +import { SymbiosisUtils } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/symbiosis-utils'; +import { getCrossChainGasData } from 'src/features/cross-chain/calculation-manager/utils/get-cross-chain-gas-data'; -export class MesonCrossChainTrade extends EvmCrossChainTrade { +export class MesonCrossChainEvmTrade extends EvmCrossChainTrade { /** @internal */ public static async getGasData({ feeInfo, @@ -38,9 +44,9 @@ export class MesonCrossChainTrade extends EvmCrossChainTrade { sourceAssetString, targetAssetString, toToken - }: MesonGetGasDataParams): Promise { + }: MesonGetGasDataParams): Promise { try { - const trade = new MesonCrossChainTrade({ + const trade = new MesonCrossChainEvmTrade({ crossChainTrade: { from, to: toToken, @@ -66,7 +72,7 @@ export class MesonCrossChainTrade extends EvmCrossChainTrade { public readonly isAggregator: boolean = false; - public readonly to: PriceTokenAmount; + public readonly to: PriceTokenAmount; public readonly from: PriceTokenAmount; // 0.0011 @@ -102,7 +108,7 @@ export class MesonCrossChainTrade extends EvmCrossChainTrade { return 'startBridgeTokensViaGenericCrossChain'; } - constructor(params: MesonCrossChainTradeConstructorParams) { + constructor(params: MesonCrossChainEvmTradeConstructorParams) { super(params.providerAddress, params.routePath, params.useProxy); this.to = params.crossChainTrade.to; this.from = params.crossChainTrade.from; @@ -125,16 +131,26 @@ export class MesonCrossChainTrade extends EvmCrossChainTrade { options?.useCacheData || false, options?.receiverAddress || this.walletAddress ); + const { receiverAddress: proxyReceiver, toAddress } = await SymbiosisUtils.getReceiver( + this.from, + this.to, + this.walletAddress, + options?.receiverAddress + ); - const bridgeData = ProxyCrossChainEvmTrade.getBridgeData(options, { - walletAddress: receiverAddress, - fromTokenAmount: this.from, // 0.0011 - toTokenAmount: this.to, - srcChainTrade: null, - providerAddress: this.providerAddress, - type: `native:${this.bridgeType}`, - fromAddress: this.walletAddress - }); + const bridgeData = ProxyCrossChainEvmTrade.getBridgeData( + { ...options, receiverAddress: proxyReceiver }, + { + walletAddress: receiverAddress, + fromTokenAmount: this.from, // 0.0011 + toTokenAmount: this.to, + srcChainTrade: null, + providerAddress: this.providerAddress, + type: `native:${this.bridgeType}`, + fromAddress: this.walletAddress, + toAddress + } + ); const extraNativeFee = '0'; const providerData = await ProxyCrossChainEvmTrade.getGenericProviderData( diff --git a/src/features/cross-chain/calculation-manager/providers/meson-provider/networks/meson-cross-chain-tron-trade.ts b/src/features/cross-chain/calculation-manager/providers/meson-provider/networks/meson-cross-chain-tron-trade.ts new file mode 100644 index 00000000000..4db7c983e11 --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/meson-provider/networks/meson-cross-chain-tron-trade.ts @@ -0,0 +1,129 @@ +import BigNumber from 'bignumber.js'; +import { ethers } from 'ethers'; +import { PriceTokenAmount } from 'src/common/tokens'; +import { TronBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { TronTransactionConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config'; +import { TronWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/tron-web3-pure'; +import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; +import { + CROSS_CHAIN_TRADE_TYPE, + CrossChainTradeType +} from 'src/features/cross-chain/calculation-manager/models/cross-chain-trade-type'; +import { rubicProxyContractAddress } from 'src/features/cross-chain/calculation-manager/providers/common/constants/rubic-proxy-contract-address'; +import { GasData } from 'src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/models/gas-data'; +import { + BRIDGE_TYPE, + BridgeType +} from 'src/features/cross-chain/calculation-manager/providers/common/models/bridge-type'; +import { FeeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/fee-info'; +import { OnChainSubtype } from 'src/features/cross-chain/calculation-manager/providers/common/models/on-chain-subtype'; +import { TradeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/trade-info'; +import { TronCrossChainTrade } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/tron-cross-chain-trade'; +import { MESON_ABI } from 'src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-abi'; +import { mesonContractAddresses } from 'src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-contract-addresses'; +import { MesonSupportedBlockchain } from 'src/features/cross-chain/calculation-manager/providers/meson-provider/constants/meson-cross-chain-supported-chains'; +import { MesonCrossChainTronTradeConstructorParams } from 'src/features/cross-chain/calculation-manager/providers/meson-provider/models/meson-trade-types'; +import { MesonCcrApiService } from 'src/features/cross-chain/calculation-manager/providers/meson-provider/services/meson-cross-chain-api-service'; + +export class MesonCrossChainTronTrade extends TronCrossChainTrade { + /**ABSTRACT PROPS */ + public readonly type: CrossChainTradeType = CROSS_CHAIN_TRADE_TYPE.MESON; + + public readonly isAggregator: boolean = false; + + public readonly to: PriceTokenAmount; + + public readonly from: PriceTokenAmount; // 0.0011 + + public readonly toTokenAmountMin: BigNumber; + + public readonly feeInfo: FeeInfo; + + public readonly onChainSubtype: OnChainSubtype = { from: undefined, to: undefined }; + + public readonly bridgeType: BridgeType = BRIDGE_TYPE.MESON; + + public readonly gasData: GasData; + + public readonly priceImpact: number | null; + /** */ + + /* Used in swap-request, example `bnb:usdc` */ + private readonly sourceAssetString: string; + + private readonly targetAssetString: string; + + private get fromBlockchain(): MesonSupportedBlockchain { + return this.from.blockchain as MesonSupportedBlockchain; + } + + protected get fromContractAddress(): string { + return mesonContractAddresses[this.fromBlockchain]; + } + + protected get methodName(): string { + throw new Error('Not implemented'); + } + + constructor(params: MesonCrossChainTronTradeConstructorParams) { + super(params.providerAddress, params.routePath, params.useProxy); + this.to = params.crossChainTrade.to; + this.from = params.crossChainTrade.from; + this.feeInfo = params.crossChainTrade.feeInfo; + this.gasData = params.crossChainTrade.gasData; + this.priceImpact = params.crossChainTrade.priceImpact; + this.toTokenAmountMin = this.to.tokenAmount; + this.sourceAssetString = params.crossChainTrade.sourceAssetString; + this.targetAssetString = params.crossChainTrade.targetAssetString; + } + + protected async getTransactionConfigAndAmount( + receiverAddress?: string + ): Promise<{ config: TronTransactionConfig; amount: string }> { + const rubicMultiProxyAddress = rubicProxyContractAddress[this.fromBlockchain].router; + const fromAddress = this.isProxyTrade ? rubicMultiProxyAddress : this.walletAddress; + + const fromWithoutFee = getFromWithoutFee( + this.from, + this.feeInfo.rubicProxy?.platformFee?.percent + ); + + const { encoded, initiator } = await MesonCcrApiService.fetchInfoForTx({ + sourceAssetString: this.sourceAssetString, + targetAssetString: this.targetAssetString, + amount: fromWithoutFee.tokenAmount.toFixed(), + fromAddress, + receiverAddress: receiverAddress || this.walletAddress, + useProxy: this.isProxyTrade + }); + const postingValue = ethers.utils.solidityPack(['address', 'uint40'], [initiator, 1]); + + const methodName = 'postSwapFromContract'; + const methodArgs = [ + { type: 'uint256', value: encoded }, + { type: 'uint200', value: postingValue }, + { type: 'address', value: encoded } + ]; + const value = this.from.isNative ? fromWithoutFee.stringWeiAmount : '0'; + + const config = TronWeb3Pure.encodeMethodCall( + mesonContractAddresses[this.fromBlockchain], + MESON_ABI, + methodName, + methodArgs, + value + ); + + return { config, amount: this.to.stringWeiAmount }; + } + + public getTradeInfo(): TradeInfo { + return { + estimatedGas: null, + feeInfo: this.feeInfo, + priceImpact: this.priceImpact || null, + slippage: 0, + routePath: this.routePath + }; + } +} diff --git a/src/features/cross-chain/calculation-manager/providers/meson-provider/services/meson-cross-chain-utils.ts b/src/features/cross-chain/calculation-manager/providers/meson-provider/services/meson-cross-chain-utils.ts new file mode 100644 index 00000000000..c0b93a0012b --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/meson-provider/services/meson-cross-chain-utils.ts @@ -0,0 +1,14 @@ +import { BLOCKCHAIN_NAME, BlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; +import Web3 from 'web3'; + +export class MesonCrossChainUtils { + public static getSearchebleId(chain: BlockchainName): string { + if (chain === BLOCKCHAIN_NAME.TRON) { + return 'tron'; + } + const chainId = blockchainId[chain]; + const hexChainId = Web3.utils.toHex(chainId); + return hexChainId; + } +} diff --git a/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/constants/orbiter-router-v4-abi.ts b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/constants/orbiter-router-v4-abi.ts new file mode 100644 index 00000000000..14117492c7f --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/constants/orbiter-router-v4-abi.ts @@ -0,0 +1,64 @@ +import { AbiItem } from 'web3-utils'; + +export const ORBITER_ROUTER_V4_ABI: AbiItem[] = [ + { + inputs: [ + { name: 'to', type: 'address' }, + { name: 'extra', type: 'bytes' } + ], + name: 'transfer', + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { name: 'token', type: 'address' }, + { name: 'to', type: 'address' }, + { name: 'value', type: 'uint256' }, + { name: 'extra', type: 'bytes' } + ], + name: 'transferToken', + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { name: 'token', type: 'address' }, + { name: 'tos', type: 'address[]' }, + { name: 'values', type: 'uint256[]' }, + { name: 'extras', type: 'bytes[]' } + ], + name: 'transferTokens', + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { name: 'token', type: 'address' }, + { name: 'tos', type: 'address[]' }, + { name: 'values', type: 'uint256[]' } + ], + name: 'transferTokens', + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { name: 'tos', type: 'address[]' }, + { name: 'values', type: 'uint256[]' } + ], + name: 'transfers', + stateMutability: 'payable', + type: 'function' + }, + { + inputs: [ + { name: 'tos', type: 'address[]' }, + { name: 'values', type: 'uint256[]' }, + { name: 'extras', type: 'bytes[]' } + ], + name: 'transfers', + stateMutability: 'payable', + type: 'function' + } +]; diff --git a/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/models/orbiter-bridge-trade-types.ts b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/models/orbiter-bridge-trade-types.ts index 57eb79280cc..e2e8e4a6010 100644 --- a/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/models/orbiter-bridge-trade-types.ts +++ b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/models/orbiter-bridge-trade-types.ts @@ -1,24 +1,28 @@ import { PriceTokenAmount } from 'src/common/tokens'; -import { EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { + BlockchainName, + EvmBlockchainName, + TronBlockchainName +} from 'src/core/blockchain/models/blockchain-name'; import { GasData } from '../../common/evm-cross-chain-trade/models/gas-data'; import { FeeInfo } from '../../common/models/fee-info'; import { RubicStep } from '../../common/models/rubicStep'; import { OrbiterQuoteConfig } from './orbiter-api-quote-types'; -export interface OrbiterGetGasDataParams { - fromToken: PriceTokenAmount; - toToken: PriceTokenAmount; +export interface OrbiterGetGasDataParams { + fromToken: PriceTokenAmount; + toToken: PriceTokenAmount; feeInfo: FeeInfo; providerAddress: string; quoteConfig: OrbiterQuoteConfig; receiverAddress?: string; } -export interface OrbiterTradeParams { +export interface OrbiterTradeParams { crossChainTrade: { - from: PriceTokenAmount; - to: PriceTokenAmount; + from: PriceTokenAmount; + to: PriceTokenAmount; gasData: GasData | null; feeInfo: FeeInfo; priceImpact: number | null; @@ -28,3 +32,6 @@ export interface OrbiterTradeParams { routePath: RubicStep[]; useProxy: boolean; } + +export type OrbiterEvmTradeParams = OrbiterTradeParams; +export type OrbiterTronTradeParams = OrbiterTradeParams; diff --git a/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/models/orbiter-contract-addresses.ts b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/models/orbiter-contract-addresses.ts index a826b55de7e..9085ab74c3c 100644 --- a/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/models/orbiter-contract-addresses.ts +++ b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/models/orbiter-contract-addresses.ts @@ -28,5 +28,6 @@ export const orbiterContractAddresses: Record { + }: OrbiterGetGasDataParams): Promise { try { - const trade = new OrbiterBridgeTrade({ + const trade = new OrbiterEvmBridgeTrade({ crossChainTrade: { from: fromToken, to: toToken, @@ -62,7 +69,7 @@ export class OrbiterBridgeTrade extends EvmCrossChainTrade { public readonly isAggregator: boolean = false; - public readonly to: PriceTokenAmount; + public readonly to: PriceTokenAmount; public readonly from: PriceTokenAmount; @@ -96,7 +103,7 @@ export class OrbiterBridgeTrade extends EvmCrossChainTrade { return 'startBridgeTokensViaGenericCrossChain'; } - constructor(params: OrbiterTradeParams) { + constructor(params: OrbiterEvmTradeParams) { super(params.providerAddress, params.routePath, params.useProxy); this.to = params.crossChainTrade.to; this.from = params.crossChainTrade.from; @@ -107,39 +114,6 @@ export class OrbiterBridgeTrade extends EvmCrossChainTrade { this.quoteConfig = params.crossChainTrade.quoteConfig; } - protected async swapDirect(options: SwapTransactionOptions = {}): Promise { - await this.checkTradeErrors(); - await this.checkAllowanceAndApprove(options); - - const { onConfirm, gasPriceOptions } = options; - let transactionHash: string; - const onTransactionHash = (hash: string) => { - if (onConfirm) { - onConfirm(hash); - } - transactionHash = hash; - }; - - try { - const { data, to, value } = await this.setTransactionConfig( - false, - options?.useCacheData || false, - options?.receiverAddress || this.walletAddress - ); - - await this.web3Private.trySendTransaction(to, { - data, - value, - onTransactionHash, - gasPriceOptions - }); - - return transactionHash!; - } catch (err) { - throw err; - } - } - public async getContractParams(options: GetContractParamsOptions): Promise { const receiverAddress = options?.receiverAddress || this.walletAddress; const { @@ -152,8 +126,17 @@ export class OrbiterBridgeTrade extends EvmCrossChainTrade { options?.receiverAddress || this.walletAddress ); + const { receiverAddress: proxyReceiver, toAddress } = await SymbiosisUtils.getReceiver( + this.from, + this.to, + this.walletAddress, + options?.receiverAddress + ); + const percentFee = (this.feeInfo.rubicProxy?.platformFee?.percent || 0) / 100; - const fromWeiAmountWithHiddenCode = new BigNumber(this.getFromAmountWithoutFeeWithCode()) + const fromWeiAmountWithHiddenCode = new BigNumber( + OrbiterUtils.getFromAmountWithoutFeeWithCode(this.from, this.feeInfo, this.quoteConfig) + ) .dividedBy(1 - percentFee) .decimalPlaces(0, 1); const fromWithCode = new PriceTokenAmount({ @@ -161,15 +144,19 @@ export class OrbiterBridgeTrade extends EvmCrossChainTrade { weiAmount: fromWeiAmountWithHiddenCode }); - const bridgeData = ProxyCrossChainEvmTrade.getBridgeData(options, { - walletAddress: receiverAddress, - fromTokenAmount: fromWithCode, - toTokenAmount: this.to, - srcChainTrade: null, - providerAddress: this.providerAddress, - type: `native:${this.bridgeType}`, - fromAddress: this.walletAddress - }); + const bridgeData = ProxyCrossChainEvmTrade.getBridgeData( + { ...options, receiverAddress: proxyReceiver }, + { + walletAddress: receiverAddress, + fromTokenAmount: fromWithCode, + toTokenAmount: this.to, + srcChainTrade: null, + providerAddress: this.providerAddress, + type: `native:${this.bridgeType}`, + fromAddress: this.walletAddress, + toAddress + } + ); const extraNativeFee = '0'; const providerData = await ProxyCrossChainEvmTrade.getGenericProviderData( @@ -210,7 +197,12 @@ export class OrbiterBridgeTrade extends EvmCrossChainTrade { const orbiterTokensDispenser = this.quoteConfig.endpoint; // const transferAmount = this.from.stringWeiAmount; - const transferAmount = this.getFromAmountWithoutFeeWithCode(); + + const transferAmount = OrbiterUtils.getFromAmountWithoutFeeWithCode( + this.from, + this.feeInfo, + this.quoteConfig + ); const encodedReceiverAndCode = OrbiterUtils.getHexDataArg( this.quoteConfig.vc, @@ -237,25 +229,6 @@ export class OrbiterBridgeTrade extends EvmCrossChainTrade { }; } - /** - * @example for native transfer - * 1000000 - 2%(rubicPercentFee) -> convertToCode -> 998015 - * amountJore - 998015 + 2% - * When Jora subtracts amountJore - 2%, he will get value with orbiter-vc-code - */ - private getFromAmountWithoutFeeWithCode(): string { - const fromWithoutFee = getFromWithoutFee( - this.from, - this.feeInfo.rubicProxy?.platformFee?.percent - ); - const transferAmount = OrbiterUtils.getAmountWithVcCode( - fromWithoutFee.stringWeiAmount, - this.quoteConfig - ); - - return transferAmount; - } - public getTradeInfo(): TradeInfo { return { estimatedGas: this.estimatedGas, diff --git a/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/networks/orbiter-tron-bridge-trade.ts b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/networks/orbiter-tron-bridge-trade.ts new file mode 100644 index 00000000000..d6c467e0d9e --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/networks/orbiter-tron-bridge-trade.ts @@ -0,0 +1,141 @@ +import BigNumber from 'bignumber.js'; +import { PriceTokenAmount } from 'src/common/tokens'; +import { TronBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { TronTransactionConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config'; +import { TronWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/tron-web3-pure'; +import { + CROSS_CHAIN_TRADE_TYPE, + CrossChainTradeType +} from 'src/features/cross-chain/calculation-manager/models/cross-chain-trade-type'; +import { GasData } from 'src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/models/gas-data'; +import { + BRIDGE_TYPE, + BridgeType +} from 'src/features/cross-chain/calculation-manager/providers/common/models/bridge-type'; +import { FeeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/fee-info'; +import { GetContractParamsOptions } from 'src/features/cross-chain/calculation-manager/providers/common/models/get-contract-params-options'; +import { OnChainSubtype } from 'src/features/cross-chain/calculation-manager/providers/common/models/on-chain-subtype'; +import { TradeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/trade-info'; +import { TronContractParams } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/models/tron-contract-params'; +import { TronCrossChainTrade } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/tron-cross-chain-trade'; +import { ORBITER_ROUTER_V3_ABI } from 'src/features/cross-chain/calculation-manager/providers/orbiter-bridge/constants/orbiter-router-v3-abi'; +import { OrbiterQuoteConfig } from 'src/features/cross-chain/calculation-manager/providers/orbiter-bridge/models/orbiter-api-quote-types'; +import { OrbiterTronTradeParams } from 'src/features/cross-chain/calculation-manager/providers/orbiter-bridge/models/orbiter-bridge-trade-types'; +import { orbiterContractAddresses } from 'src/features/cross-chain/calculation-manager/providers/orbiter-bridge/models/orbiter-contract-addresses'; +import { OrbiterSupportedBlockchain } from 'src/features/cross-chain/calculation-manager/providers/orbiter-bridge/models/orbiter-supported-blockchains'; +import { OrbiterUtils } from 'src/features/cross-chain/calculation-manager/providers/orbiter-bridge/services/orbiter-utils'; + +export class OrbiterTronBridgeTrade extends TronCrossChainTrade { + /**ABSTRACT PROPS */ + public readonly type: CrossChainTradeType = CROSS_CHAIN_TRADE_TYPE.ORBITER_BRIDGE; + + public readonly isAggregator: boolean = false; + + 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.ORBITER_BRIDGE; + + public readonly gasData: GasData; + + public readonly priceImpact: number | null; + /** */ + + /* used to get extraNativeFee(tradeFee) and orbiter contract params */ + private quoteConfig: OrbiterQuoteConfig; + + private get fromBlockchain(): OrbiterSupportedBlockchain { + return this.from.blockchain as OrbiterSupportedBlockchain; + } + + protected get fromContractAddress(): string { + return orbiterContractAddresses[this.fromBlockchain]; + } + + protected get methodName(): string { + throw new Error('Not implemented'); + } + + constructor(params: OrbiterTronTradeParams) { + super(params.providerAddress, params.routePath, params.useProxy); + this.to = params.crossChainTrade.to; + this.from = params.crossChainTrade.from; + this.toTokenAmountMin = params.crossChainTrade.to.tokenAmount; + this.feeInfo = params.crossChainTrade.feeInfo; + this.gasData = params.crossChainTrade.gasData; + this.priceImpact = params.crossChainTrade.priceImpact; + this.quoteConfig = params.crossChainTrade.quoteConfig; + } + + public async getContractParams( + _options: GetContractParamsOptions + ): Promise { + throw new Error('Not implemented'); + } + + protected async getTransactionConfigAndAmount(receiverAddress?: string): Promise<{ + config: TronTransactionConfig; + amount: string; + }> { + // Orbiter deposit address to send funds money to receiverWalletAddress after transfer confirmation + const orbiterTokensDispenser = this.quoteConfig.endpoint; + + // const transferAmount = this.from.stringWeiAmount; + const transferAmount = OrbiterUtils.getFromAmountWithoutFeeWithCode( + this.from, + this.feeInfo, + this.quoteConfig + ); + + const encodedReceiverAndCode = OrbiterUtils.getHexDataArg( + this.quoteConfig.vc, + receiverAddress || this.walletAddress + ); + + const methodName = this.from.isNative ? 'transfer' : 'transferToken'; + const methodArgs = this.from.isNative + ? [ + { type: 'address', value: orbiterTokensDispenser }, + { type: 'bytes', value: encodedReceiverAndCode } + ] + : [ + { type: 'address', value: this.from.address }, + { type: 'address', value: orbiterTokensDispenser }, + { type: 'uint256', value: transferAmount }, + { type: 'bytes', value: encodedReceiverAndCode } + ]; + + // this.from.address, orbiterTokensDispenser, transferAmount, encodedReceiverAndCode + const value = this.from.isNative ? transferAmount : '0'; + + const config = TronWeb3Pure.encodeMethodCall( + orbiterContractAddresses[this.fromBlockchain], + ORBITER_ROUTER_V3_ABI, + methodName, + methodArgs, + value + ); + + return { + config, + amount: this.to.stringWeiAmount + }; + } + + public getTradeInfo(): TradeInfo { + return { + estimatedGas: null, + feeInfo: this.feeInfo, + priceImpact: this.priceImpact, + slippage: 0, + routePath: this.routePath + }; + } +} diff --git a/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/orbiter-bridge-factory.ts b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/orbiter-bridge-factory.ts new file mode 100644 index 00000000000..b63da026afa --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/orbiter-bridge-factory.ts @@ -0,0 +1,44 @@ +import { + BlockchainName, + EvmBlockchainName, + TronBlockchainName +} from 'src/core/blockchain/models/blockchain-name'; +import { BlockchainsInfo } from 'src/core/blockchain/utils/blockchains-info/blockchains-info'; +import { GasData } from 'src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/models/gas-data'; +import { + OrbiterGetGasDataParams, + OrbiterTradeParams +} from 'src/features/cross-chain/calculation-manager/providers/orbiter-bridge/models/orbiter-bridge-trade-types'; +import { OrbiterEvmBridgeTrade } from 'src/features/cross-chain/calculation-manager/providers/orbiter-bridge/networks/orbiter-evm-bridge-trade'; +import { OrbiterTronBridgeTrade } from 'src/features/cross-chain/calculation-manager/providers/orbiter-bridge/networks/orbiter-tron-bridge-trade'; + +export class OrbiterBridgeFactory { + public static createTrade( + params: OrbiterTradeParams + ): OrbiterTronBridgeTrade | OrbiterEvmBridgeTrade { + const fromBlockchain = params.crossChainTrade.from.blockchain; + if (BlockchainsInfo.isTronBlockchainName(fromBlockchain)) { + return new OrbiterTronBridgeTrade(params as OrbiterTradeParams); + } + + if (BlockchainsInfo.isEvmBlockchainName(fromBlockchain)) { + return new OrbiterEvmBridgeTrade(params as OrbiterTradeParams); + } + throw new Error('Can not create trade instance'); + } + + public static async getGasData( + calculateGas: boolean, + params: OrbiterGetGasDataParams + ): Promise { + if (calculateGas) { + const fromBlockchain = params.fromToken.blockchain; + if (BlockchainsInfo.isEvmBlockchainName(fromBlockchain)) { + return OrbiterEvmBridgeTrade.getGasData( + params as OrbiterGetGasDataParams + ); + } + } + return null; + } +} diff --git a/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/orbiter-bridge-provider.ts b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/orbiter-bridge-provider.ts index 50e842bbb6c..e0758befc88 100644 --- a/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/orbiter-bridge-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/orbiter-bridge-provider.ts @@ -1,9 +1,12 @@ import BigNumber from 'bignumber.js'; import { MaxAmountError, MinAmountError } from 'src/common/errors'; import { PriceToken, 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 { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; +import { OrbiterEvmBridgeTrade } from 'src/features/cross-chain/calculation-manager/providers/orbiter-bridge/networks/orbiter-evm-bridge-trade'; +import { OrbiterTronBridgeTrade } from 'src/features/cross-chain/calculation-manager/providers/orbiter-bridge/networks/orbiter-tron-bridge-trade'; +import { OrbiterBridgeFactory } from 'src/features/cross-chain/calculation-manager/providers/orbiter-bridge/orbiter-bridge-factory'; import { RequiredCrossChainOptions } from '../../models/cross-chain-options'; import { CROSS_CHAIN_TRADE_TYPE } from '../../models/cross-chain-trade-type'; @@ -17,7 +20,6 @@ import { OrbiterSupportedBlockchain, orbiterSupportedBlockchains } from './models/orbiter-supported-blockchains'; -import { OrbiterBridgeTrade } from './orbiter-bridge-trade'; import { OrbiterApiService } from './services/orbiter-api-service'; import { OrbiterUtils } from './services/orbiter-utils'; @@ -38,7 +40,10 @@ export class OrbiterBridgeProvider extends CrossChainProvider { options: RequiredCrossChainOptions ): Promise { const fromBlockchain = from.blockchain as OrbiterSupportedBlockchain; - const useProxy = options?.useProxy?.[this.type] ?? true; + let useProxy = options?.useProxy?.[this.type] ?? true; + if (fromBlockchain === BLOCKCHAIN_NAME.TRON) { + useProxy = false; + } try { this.orbiterQuoteConfigs = await OrbiterApiService.getQuoteConfigs(); @@ -89,19 +94,16 @@ export class OrbiterBridgeProvider extends CrossChainProvider { tokenAmount: Web3Pure.fromWei(toAmount, toToken.decimals) }); - const gasData = - options.gasCalculation === 'enabled' - ? await OrbiterBridgeTrade.getGasData({ - feeInfo, - fromToken: from, - toToken: to, - receiverAddress: options.receiverAddress, - providerAddress: options.providerAddress, - quoteConfig - }) - : null; - - const trade = new OrbiterBridgeTrade({ + const gasData = await OrbiterBridgeFactory.getGasData(Boolean(options.gasCalculation), { + feeInfo, + fromToken: from, + toToken: to, + receiverAddress: options.receiverAddress, + providerAddress: options.providerAddress, + quoteConfig + }); + + const trade = OrbiterBridgeFactory.createTrade({ crossChainTrade: { feeInfo, from, @@ -167,12 +169,12 @@ export class OrbiterBridgeProvider extends CrossChainProvider { feeInfo: FeeInfo, quoteConfig: OrbiterQuoteConfig, providerAddress: string - ): OrbiterBridgeTrade { + ): OrbiterEvmBridgeTrade | OrbiterTronBridgeTrade { const to = new PriceTokenAmount({ ...toToken.asStruct, tokenAmount: new BigNumber(0) }); - const trade = new OrbiterBridgeTrade({ + const trade = OrbiterBridgeFactory.createTrade({ crossChainTrade: { from, gasData: null, diff --git a/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/services/orbiter-utils.ts b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/services/orbiter-utils.ts index ead03550e5a..160a948b182 100644 --- a/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/services/orbiter-utils.ts +++ b/src/features/cross-chain/calculation-manager/providers/orbiter-bridge/services/orbiter-utils.ts @@ -8,6 +8,8 @@ import { EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; +import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; +import { FeeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/fee-info'; import Web3 from 'web3'; import { ORBITER_FEE_DIVIDER } from '../constants/orbiter-api'; @@ -19,6 +21,9 @@ export class OrbiterUtils { if (blockchainName === BLOCKCHAIN_NAME.STARKNET) { return orbiterChainId === 'SN_MAIN'; } + if (blockchainName === BLOCKCHAIN_NAME.TRON) { + return orbiterChainId === '728126428'; + } return orbiterChainId === blockchainId[blockchainName].toString(); } @@ -76,4 +81,24 @@ export class OrbiterUtils { return total; } + + /** + * @example for native transfer + * 1000000 - 2%(rubicPercentFee) -> convertToCode -> 998015 + * amountJore - 998015 + 2% + * When Jora subtracts amountJore - 2%, he will get value with orbiter-vc-code + */ + public static getFromAmountWithoutFeeWithCode( + from: PriceTokenAmount, + feeInfo: FeeInfo, + quoteConfig: OrbiterQuoteConfig + ): string { + const fromWithoutFee = getFromWithoutFee(from, feeInfo.rubicProxy?.platformFee?.percent); + const transferAmount = OrbiterUtils.getAmountWithVcCode( + fromWithoutFee.stringWeiAmount, + quoteConfig + ); + + return transferAmount; + } } diff --git a/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/chain-trades/symbiosis-ccr-tron-trade.ts b/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/chain-trades/symbiosis-ccr-tron-trade.ts new file mode 100644 index 00000000000..150fc6f9c0e --- /dev/null +++ b/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/chain-trades/symbiosis-ccr-tron-trade.ts @@ -0,0 +1,138 @@ +import BigNumber from 'bignumber.js'; +import { PriceTokenAmount } from 'src/common/tokens'; +import { TronBlockchainName } from 'src/core/blockchain/models/blockchain-name'; +import { TronTransactionConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config'; +import { SymbiosisApiService } from 'src/features/common/providers/symbiosis/services/symbiosis-api-service'; +import { CROSS_CHAIN_TRADE_TYPE } from 'src/features/cross-chain/calculation-manager/models/cross-chain-trade-type'; +import { GasData } from 'src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/models/gas-data'; +import { BRIDGE_TYPE } from 'src/features/cross-chain/calculation-manager/providers/common/models/bridge-type'; +import { FeeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/fee-info'; +import { OnChainSubtype } from 'src/features/cross-chain/calculation-manager/providers/common/models/on-chain-subtype'; +import { RubicStep } from 'src/features/cross-chain/calculation-manager/providers/common/models/rubicStep'; +import { TradeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/trade-info'; +import { TronCrossChainTrade } from 'src/features/cross-chain/calculation-manager/providers/common/tron-cross-chain-trade/tron-cross-chain-trade'; +import { SymbiosisCrossChainSupportedBlockchain } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-cross-chain-supported-blockchains'; +import { SymbiosisTronCrossChainTradeConstructor } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-cross-chain-trade-constructor'; +import { SymbiosisSwappingParams } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-swapping-params'; +import { TronTx } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-trade-data'; +import { SymbiosisUtils } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/symbiosis-utils'; + +/** + * Calculated Symbiosis cross-chain trade. + */ +export class SymbiosisTronCcrTrade extends TronCrossChainTrade { + private readonly swappingParams: SymbiosisSwappingParams; + + public readonly type = CROSS_CHAIN_TRADE_TYPE.SYMBIOSIS; + + public readonly isAggregator = false; + + public readonly onChainSubtype: OnChainSubtype; + + public readonly bridgeType = BRIDGE_TYPE.SYMBIOSIS; + + public readonly from: PriceTokenAmount; + + public readonly to: PriceTokenAmount; + + public readonly toTokenAmountMin: BigNumber; + + /** @internal */ + public readonly transitAmount: BigNumber; + + public readonly feeInfo: FeeInfo; + + /** + * Overall price impact, fetched from symbiosis api. + */ + public readonly priceImpact: number | null; + + public readonly gasData: GasData | null; + + private readonly slippage: number; + + private readonly contractAddresses: { providerRouter: string; providerGateway: string }; + + private get fromBlockchain(): SymbiosisCrossChainSupportedBlockchain { + return this.from.blockchain as SymbiosisCrossChainSupportedBlockchain; + } + + protected get fromContractAddress(): string { + throw new Error('Not implemented'); + } + + protected get methodName(): string { + throw new Error('Not implemented'); + } + + constructor( + crossChainTrade: SymbiosisTronCrossChainTradeConstructor, + providerAddress: string, + routePath: RubicStep[], + useProxy: boolean + ) { + super(providerAddress, routePath, useProxy); + + this.from = crossChainTrade.from; + this.to = crossChainTrade.to; + this.swappingParams = crossChainTrade.swapParams; + this.gasData = crossChainTrade.gasData; + this.priceImpact = crossChainTrade.priceImpact; + this.toTokenAmountMin = this.to.tokenAmount.multipliedBy(1 - crossChainTrade.slippage); + this.feeInfo = crossChainTrade.feeInfo; + this.slippage = crossChainTrade.slippage; + this.transitAmount = crossChainTrade.transitAmount; + this.onChainSubtype = SymbiosisUtils.getSubtype( + crossChainTrade.tradeType, + crossChainTrade.to.blockchain + ); + this.contractAddresses = crossChainTrade.contractAddresses; + this.promotions = crossChainTrade?.promotions || []; + } + + public getTradeAmountRatio(fromUsd: BigNumber): BigNumber { + return fromUsd.dividedBy(this.to.tokenAmount); + } + + public getTradeInfo(): TradeInfo { + return { + estimatedGas: null, + feeInfo: this.feeInfo, + priceImpact: this.priceImpact ?? null, + slippage: this.slippage * 100, + routePath: this.routePath + }; + } + + protected async getTransactionConfigAndAmount( + receiverAddress?: string + ): Promise<{ config: TronTransactionConfig; amount: string }> { + const walletAddress = this.walletAddress; + + const params: SymbiosisSwappingParams = { + ...this.swappingParams, + from: walletAddress, + to: receiverAddress || walletAddress, + revertableAddress: SymbiosisUtils.getRevertableAddress( + receiverAddress, + walletAddress, + this.to.blockchain + ) + }; + + const tradeData = await SymbiosisApiService.getCrossChainSwapTx(params); + const tx = tradeData.tx as TronTx; + + const amount = tradeData.tokenAmountOut.amount; + const config: TronTransactionConfig = { + signature: tx.functionSelector, + arguments: [], + to: tx.to, + rawParameter: tx.data, + callValue: tx.value, + feeLimit: tx.feeLimit + }; + + return { amount, config }; + } +} diff --git a/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-cross-chain-trade-constructor.ts b/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-cross-chain-trade-constructor.ts index c44e4560942..8046a8645c5 100644 --- a/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-cross-chain-trade-constructor.ts +++ b/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-cross-chain-trade-constructor.ts @@ -3,7 +3,8 @@ import { PriceTokenAmount } from 'src/common/tokens'; import { BlockchainName, EvmBlockchainName, - TonBlockchainName + TonBlockchainName, + TronBlockchainName } from 'src/core/blockchain/models/blockchain-name'; import { GasData } from 'src/features/cross-chain/calculation-manager/providers/common/evm-cross-chain-trade/models/gas-data'; import { SymbiosisSwappingParams } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-swapping-params'; @@ -30,3 +31,6 @@ export type SymbiosisEvmCrossChainTradeConstructor = export type SymbiosisTonCrossChainTradeConstructor = SymbiosisCrossChainTradeConstructor; + +export type SymbiosisTronCrossChainTradeConstructor = + SymbiosisCrossChainTradeConstructor; diff --git a/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-trade-data.ts b/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-trade-data.ts index 2e7ab38a30e..69a971483b6 100644 --- a/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-trade-data.ts +++ b/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-trade-data.ts @@ -16,11 +16,20 @@ export interface SymbiosisTokenAmount extends SymbiosisToken { amount: string; } +export interface TronTx { + data: string; + feeLimit: number; + from: string; + functionSelector: string; + to: string; + value: string; +} + export interface SymbiosisTradeData { fee: SymbiosisTokenAmount; priceImpact: string; tokenAmountOut: SymbiosisTokenAmount; - tx: SendTransactionRequest | TransactionRequest; + tx: SendTransactionRequest | TransactionRequest | TronTx; amountInUsd: SymbiosisTokenAmount; approveTo: string; route: SymbiosisToken[]; diff --git a/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/symbiosis-cross-chain-factory.ts b/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/symbiosis-cross-chain-factory.ts index db39fa32495..b68af9387c3 100644 --- a/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/symbiosis-cross-chain-factory.ts +++ b/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/symbiosis-cross-chain-factory.ts @@ -6,10 +6,12 @@ import { GasData } from 'src/features/cross-chain/calculation-manager/providers/ import { FeeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/fee-info'; import { SymbiosisEvmCcrTrade } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/chain-trades/symbiosis-ccr-evm-trade'; import { SymbiosisCcrTonTrade } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/chain-trades/symbiosis-ccr-ton-trade'; +import { SymbiosisTronCcrTrade } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/chain-trades/symbiosis-ccr-tron-trade'; import { SymbiosisCrossChainTradeConstructor, SymbiosisEvmCrossChainTradeConstructor, - SymbiosisTonCrossChainTradeConstructor + SymbiosisTonCrossChainTradeConstructor, + SymbiosisTronCrossChainTradeConstructor } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-cross-chain-trade-constructor'; import { SymbiosisSwappingParams } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-swapping-params'; @@ -22,7 +24,7 @@ export class SymbiosisCrossChainFactory { providerAddress: string, routePath: RubicStep[], useProxy: boolean - ): SymbiosisCcrTonTrade | SymbiosisEvmCcrTrade { + ): SymbiosisCcrTonTrade | SymbiosisEvmCcrTrade | SymbiosisTronCcrTrade { if (BlockchainsInfo.isTonBlockchainName(fromBlockchain)) { return new SymbiosisCcrTonTrade( constructorParams as SymbiosisTonCrossChainTradeConstructor, @@ -40,6 +42,15 @@ export class SymbiosisCrossChainFactory { useProxy ); } + + if (BlockchainsInfo.isTronBlockchainName(fromBlockchain)) { + return new SymbiosisTronCcrTrade( + constructorParams as SymbiosisTronCrossChainTradeConstructor, + providerAddress, + routePath, + useProxy + ); + } throw new Error('Can not create trade instance'); } @@ -53,7 +64,7 @@ export class SymbiosisCrossChainFactory { receiverAddress?: string ): Promise { const type = BlockchainsInfo.getChainType(from.blockchain); - if (type === CHAIN_TYPE.TON) { + if (type === CHAIN_TYPE.TON || CHAIN_TYPE.TRON) { return null; } if (type === CHAIN_TYPE.EVM) { diff --git a/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/symbiosis-cross-chain-provider.ts b/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/symbiosis-cross-chain-provider.ts index 2cc60dbcec4..fe391476088 100644 --- a/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/symbiosis-cross-chain-provider.ts +++ b/src/features/cross-chain/calculation-manager/providers/symbiosis-provider/symbiosis-cross-chain-provider.ts @@ -14,7 +14,10 @@ import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constan import { Web3PrivateSupportedBlockchain } from 'src/core/blockchain/web3-private-service/models/web-private-supported-blockchain'; import { Web3PublicSupportedBlockchain } from 'src/core/blockchain/web3-public-service/models/web3-public-storage'; import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; -import { FAKE_WALLET_ADDRESS } from 'src/features/common/constants/fake-wallet-address'; +import { + FAKE_TRON_WALLET_ADDRESS, + FAKE_WALLET_ADDRESS +} from 'src/features/common/constants/fake-wallet-address'; import { SymbiosisApiService } from 'src/features/common/providers/symbiosis/services/symbiosis-api-service'; import { getFromWithoutFee } from 'src/features/common/utils/get-from-without-fee'; import { RequiredCrossChainOptions } from 'src/features/cross-chain/calculation-manager/models/cross-chain-options'; @@ -26,6 +29,7 @@ import { RubicStep } from 'src/features/cross-chain/calculation-manager/provider import { ProxyCrossChainEvmTrade } from 'src/features/cross-chain/calculation-manager/providers/common/proxy-cross-chain-evm-facade/proxy-cross-chain-evm-trade'; import { SymbiosisEvmCcrTrade } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/chain-trades/symbiosis-ccr-evm-trade'; import { SymbiosisCcrTonTrade } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/chain-trades/symbiosis-ccr-ton-trade'; +import { SymbiosisTronCcrTrade } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/chain-trades/symbiosis-ccr-tron-trade'; import { SymbiosisError } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-error'; import { SymbiosisSwappingParams } from 'src/features/cross-chain/calculation-manager/providers/symbiosis-provider/models/symbiosis-swapping-params'; import { @@ -56,7 +60,7 @@ export class SymbiosisCrossChainProvider extends CrossChainProvider { fromBlockchain: BlockchainName, toBlockchain: BlockchainName ): boolean { - if (fromBlockchain === BLOCKCHAIN_NAME.BITCOIN || fromBlockchain === BLOCKCHAIN_NAME.TRON) { + if (fromBlockchain === BLOCKCHAIN_NAME.BITCOIN) { return false; } @@ -77,7 +81,10 @@ export class SymbiosisCrossChainProvider extends CrossChainProvider { ? false : options?.useProxy?.[this.type] ?? true; - let disabledTrade = {} as SymbiosisCcrTonTrade | SymbiosisEvmCcrTrade; + let disabledTrade = {} as + | SymbiosisCcrTonTrade + | SymbiosisEvmCcrTrade + | SymbiosisTronCcrTrade; try { const fromAddress = @@ -326,7 +333,7 @@ export class SymbiosisCrossChainProvider extends CrossChainProvider { to: PriceTokenAmount, swapParams: SymbiosisSwappingParams, feeInfo: FeeInfo - ): SymbiosisEvmCcrTrade | SymbiosisCcrTonTrade { + ): SymbiosisEvmCcrTrade | SymbiosisCcrTonTrade | SymbiosisTronCcrTrade { return SymbiosisCrossChainFactory.createTrade( from.blockchain, { @@ -414,6 +421,9 @@ export class SymbiosisCrossChainProvider extends CrossChainProvider { if (chainType === CHAIN_TYPE.TON) { return 'UQATSC4TXAqjgLswuSEDVTIGmPG_kNnUTDhrTiIILVmymoQA'; } + if (chainType === CHAIN_TYPE.TRON) { + return FAKE_TRON_WALLET_ADDRESS; + } throw new Error('Blockchain not supported'); } } diff --git a/src/features/on-chain/calculation-manager/providers/dexes/tron/bridgers/bridgers-trade.ts b/src/features/on-chain/calculation-manager/providers/dexes/tron/bridgers/bridgers-trade.ts index 3d49b875df2..912511b5daf 100644 --- a/src/features/on-chain/calculation-manager/providers/dexes/tron/bridgers/bridgers-trade.ts +++ b/src/features/on-chain/calculation-manager/providers/dexes/tron/bridgers/bridgers-trade.ts @@ -2,7 +2,6 @@ import { SwapRequestError } from 'src/common/errors'; import { PriceTokenAmount, Token, TokenAmount } from 'src/common/tokens'; import { TronBlockchainName } from 'src/core/blockchain/models/blockchain-name'; import { TronTransactionConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/models/tron-transaction-config'; -import { TronWeb3Pure } from 'src/core/blockchain/web3-pure/typed-web3-pure/tron-web3-pure/tron-web3-pure'; import { Injector } from 'src/core/injector/injector'; import { EncodeTransactionOptions } from 'src/features/common/models/encode-transaction-options'; import { SwapTransactionOptions } from 'src/features/common/models/swap-transaction-options'; @@ -13,7 +12,7 @@ import { BridgersSwapResponse } from 'src/features/common/providers/bridgers/models/bridgers-swap-api'; import { createTokenNativeAddressProxy } from 'src/features/common/utils/token-native-address-proxy'; -import { TronBridgersTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/tron-bridgers-trade/models/tron-bridgers-transaction-data'; +import { TronBridgersTransactionData } from 'src/features/cross-chain/calculation-manager/providers/bridgers-provider/models/tron-bridgers-transaction-data'; import { FeeInfo } from 'src/features/cross-chain/calculation-manager/providers/common/models/fee-info'; import { OnChainPlatformFee } from 'src/features/on-chain/calculation-manager/providers/common/models/on-chain-proxy-fee-info'; import { @@ -87,7 +86,7 @@ export class BridgersTrade extends TronOnChainTrade { try { const transactionData = await this.getTransactionData(options); - return await this.web3Private.triggerContract( + return await this.web3Private.sendTransaction( this.contractAddress, transactionData.functionName, transactionData.parameter, @@ -104,16 +103,13 @@ export class BridgersTrade extends TronOnChainTrade { public async encode(options: EncodeTransactionOptions): Promise { try { const transactionData = await this.getTransactionData(options); - const encodedData = TronWeb3Pure.encodeMethodSignature( - transactionData.functionName, - transactionData.parameter - ); return { to: this.contractAddress, - data: encodedData, - callValue: transactionData.options.callValue, - feeLimit: options.feeLimit || transactionData.options.feeLimit + signature: transactionData.functionName, + arguments: transactionData.parameter, + feeLimit: options.feeLimit || transactionData.options.feeLimit, + callValue: transactionData.options.callValue }; } catch (err) { if ([400, 500, 503].includes(err.code)) {