-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
334 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
...n-manager/providers/aggregators/piteas/constants/piteas-on-chain-supported-blockchains.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { BLOCKCHAIN_NAME } from 'src/core/blockchain/models/blockchain-name'; | ||
|
||
export const piteasOnChainSupportedBlockchains = [BLOCKCHAIN_NAME.PULSECHAIN] as const; |
1 change: 1 addition & 0 deletions
1
...chain/calculation-manager/providers/aggregators/piteas/constants/piteas-router-address.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const piteasRouterAddress = '0x6BF228eb7F8ad948d37deD07E595EfddfaAF88A6'; |
20 changes: 20 additions & 0 deletions
20
...features/on-chain/calculation-manager/providers/aggregators/piteas/models/piteas-quote.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
export interface PiteasQuoteRequestParams { | ||
tokenInAddress: string; | ||
tokenInChainId: number; | ||
tokenOutAddress: string; | ||
tokenOutChainId: number; | ||
amount: string; // Amount with decimals | ||
allowedSlippage: number; | ||
account?: string; // Receiver address | ||
} | ||
|
||
export interface PiteasSuccessQuoteResponse { | ||
destAmount: string; | ||
gasUseEstimate: number; | ||
methodParameters: PiteasMethodParameters; | ||
} | ||
|
||
export interface PiteasMethodParameters { | ||
calldata: string; | ||
value: string; | ||
} |
8 changes: 8 additions & 0 deletions
8
...s/on-chain/calculation-manager/providers/aggregators/piteas/models/piteas-trade-struct.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { PiteasMethodParameters } from 'src/features/on-chain/calculation-manager/providers/aggregators/piteas/models/piteas-quote'; | ||
|
||
import { EvmOnChainTradeStruct } from '../../../common/on-chain-trade/evm-on-chain-trade/models/evm-on-chain-trade-struct'; | ||
|
||
export interface PiteasTradeStruct extends EvmOnChainTradeStruct { | ||
methodParameters: PiteasMethodParameters; | ||
gasUseEstimate: number; | ||
} |
20 changes: 20 additions & 0 deletions
20
src/features/on-chain/calculation-manager/providers/aggregators/piteas/piteas-api-service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { Injector } from 'src/core/injector/injector'; | ||
import { | ||
PiteasQuoteRequestParams, | ||
PiteasSuccessQuoteResponse | ||
} from 'src/features/on-chain/calculation-manager/providers/aggregators/piteas/models/piteas-quote'; | ||
|
||
export class PiteasApiService { | ||
public static apiEndpoint = 'https://api.piteas.io'; | ||
|
||
public static fetchQuote( | ||
quoteRequestParams: PiteasQuoteRequestParams | ||
): Promise<PiteasSuccessQuoteResponse> { | ||
return Injector.httpClient.get<PiteasSuccessQuoteResponse>( | ||
`${PiteasApiService.apiEndpoint}/quote`, | ||
{ | ||
params: { ...quoteRequestParams } | ||
} | ||
); | ||
} | ||
} |
136 changes: 136 additions & 0 deletions
136
src/features/on-chain/calculation-manager/providers/aggregators/piteas/piteas-provider.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import BigNumber from 'bignumber.js'; | ||
import { RubicSdkError } from 'src/common/errors'; | ||
import { PriceToken, PriceTokenAmount } from 'src/common/tokens'; | ||
import { combineOptions } from 'src/common/utils/options'; | ||
import { BlockchainName, EvmBlockchainName } from 'src/core/blockchain/models/blockchain-name'; | ||
import { blockchainId } from 'src/core/blockchain/utils/blockchains-info/constants/blockchain-id'; | ||
import { Web3Pure } from 'src/core/blockchain/web3-pure/web3-pure'; | ||
import { rubicProxyContractAddress } from 'src/features/cross-chain/calculation-manager/providers/common/constants/rubic-proxy-contract-address'; | ||
import { OnChainTradeError } from 'src/features/on-chain/calculation-manager/models/on-chain-trade-error'; | ||
import { piteasOnChainSupportedBlockchains } from 'src/features/on-chain/calculation-manager/providers/aggregators/piteas/constants/piteas-on-chain-supported-blockchains'; | ||
import { piteasRouterAddress } from 'src/features/on-chain/calculation-manager/providers/aggregators/piteas/constants/piteas-router-address'; | ||
import { PiteasQuoteRequestParams } from 'src/features/on-chain/calculation-manager/providers/aggregators/piteas/models/piteas-quote'; | ||
import { PiteasTradeStruct } from 'src/features/on-chain/calculation-manager/providers/aggregators/piteas/models/piteas-trade-struct'; | ||
import { PiteasApiService } from 'src/features/on-chain/calculation-manager/providers/aggregators/piteas/piteas-api-service'; | ||
import { PiteasTrade } from 'src/features/on-chain/calculation-manager/providers/aggregators/piteas/piteas-trade'; | ||
import { RequiredOnChainCalculationOptions } from 'src/features/on-chain/calculation-manager/providers/common/models/on-chain-calculation-options'; | ||
import { ON_CHAIN_TRADE_TYPE } from 'src/features/on-chain/calculation-manager/providers/common/models/on-chain-trade-type'; | ||
import { AggregatorOnChainProvider } from 'src/features/on-chain/calculation-manager/providers/common/on-chain-aggregator/aggregator-on-chain-provider-abstract'; | ||
import { OnChainTrade } from 'src/features/on-chain/calculation-manager/providers/common/on-chain-trade/on-chain-trade'; | ||
import { getGasFeeInfo } from 'src/features/on-chain/calculation-manager/providers/common/utils/get-gas-fee-info'; | ||
import { evmProviderDefaultOptions } from 'src/features/on-chain/calculation-manager/providers/dexes/common/on-chain-provider/evm-on-chain-provider/constants/evm-provider-default-options'; | ||
|
||
import { GasFeeInfo } from '../../common/on-chain-trade/evm-on-chain-trade/models/gas-fee-info'; | ||
import { getGasPriceInfo } from '../../common/utils/get-gas-price-info'; | ||
|
||
export class PiteasProvider extends AggregatorOnChainProvider { | ||
private readonly defaultOptions: RequiredOnChainCalculationOptions = { | ||
...evmProviderDefaultOptions, | ||
deadlineMinutes: 20, | ||
disableMultihops: false | ||
}; | ||
|
||
public readonly tradeType = ON_CHAIN_TRADE_TYPE.PITEAS; | ||
|
||
protected isSupportedBlockchain(blockchain: BlockchainName): boolean { | ||
return piteasOnChainSupportedBlockchains.some( | ||
supportedNetwork => supportedNetwork === blockchain | ||
); | ||
} | ||
|
||
public async calculate( | ||
from: PriceTokenAmount<EvmBlockchainName>, | ||
toToken: PriceToken<EvmBlockchainName>, | ||
options?: RequiredOnChainCalculationOptions | ||
): Promise<OnChainTrade | OnChainTradeError> { | ||
if (!this.isSupportedBlockchain(from.blockchain)) { | ||
throw new RubicSdkError(`Piteas doesn't support ${from.blockchain} chain!`); | ||
} | ||
|
||
try { | ||
const fromAddress = | ||
options?.useProxy || this.defaultOptions.useProxy | ||
? rubicProxyContractAddress[from.blockchain].gateway | ||
: this.getWalletAddress(from.blockchain); | ||
|
||
const fullOptions = combineOptions(options, { | ||
...this.defaultOptions, | ||
fromAddress | ||
}); | ||
|
||
const quoteRequestParams: PiteasQuoteRequestParams = { | ||
tokenInAddress: from.isNative ? 'PLS' : from.address, | ||
tokenInChainId: blockchainId[from.blockchain], | ||
tokenOutAddress: toToken.isNative ? 'PLS' : toToken.address, | ||
tokenOutChainId: blockchainId[from.blockchain], | ||
amount: from.stringWeiAmount, | ||
allowedSlippage: 0.5, | ||
...(options?.fromAddress && { account: options.fromAddress }) | ||
}; | ||
|
||
const { fromWithoutFee, proxyFeeInfo } = await this.handleProxyContract(from, { | ||
...fullOptions | ||
}); | ||
|
||
const { destAmount, gasUseEstimate, methodParameters } = | ||
await PiteasApiService.fetchQuote(quoteRequestParams); | ||
|
||
const to = new PriceTokenAmount({ | ||
...toToken.asStruct, | ||
tokenAmount: Web3Pure.fromWei(destAmount, toToken.decimals) | ||
}); | ||
|
||
const tradeStruct: PiteasTradeStruct = { | ||
from, | ||
to, | ||
slippageTolerance: fullOptions.slippageTolerance, | ||
path: [from, to], | ||
gasFeeInfo: null, | ||
useProxy: fullOptions.useProxy, | ||
proxyFeeInfo, | ||
fromWithoutFee, | ||
withDeflation: fullOptions.withDeflation, | ||
usedForCrossChain: fullOptions.usedForCrossChain, | ||
methodParameters, | ||
gasUseEstimate | ||
}; | ||
|
||
const gasFeeInfo = | ||
options?.gasCalculation === 'calculate' | ||
? await this.getGasFeeInfo(tradeStruct, piteasRouterAddress) | ||
: null; | ||
|
||
return new PiteasTrade( | ||
{ | ||
...tradeStruct, | ||
gasFeeInfo | ||
}, | ||
fullOptions.providerAddress, | ||
quoteRequestParams | ||
); | ||
} catch (err) { | ||
return { | ||
type: ON_CHAIN_TRADE_TYPE.PITEAS, | ||
error: err | ||
}; | ||
} | ||
} | ||
|
||
protected async getGasFeeInfo( | ||
tradeStruct: PiteasTradeStruct, | ||
providerGateway: string | ||
): Promise<GasFeeInfo | null> { | ||
try { | ||
const gasPriceInfo = await getGasPriceInfo(tradeStruct.from.blockchain); | ||
const gasLimit = | ||
(await PiteasTrade.getGasLimit( | ||
tradeStruct, | ||
providerGateway, | ||
tradeStruct.methodParameters | ||
)) || new BigNumber(tradeStruct.gasUseEstimate); | ||
return getGasFeeInfo(gasLimit, gasPriceInfo); | ||
} catch { | ||
return null; | ||
} | ||
} | ||
} |
141 changes: 141 additions & 0 deletions
141
src/features/on-chain/calculation-manager/providers/aggregators/piteas/piteas-trade.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import BigNumber from 'bignumber.js'; | ||
import { RubicSdkError } from 'src/common/errors'; | ||
import { parseError } from 'src/common/utils/errors'; | ||
import { EvmEncodeConfig } from 'src/core/blockchain/web3-pure/typed-web3-pure/evm-web3-pure/models/evm-encode-config'; | ||
import { Injector } from 'src/core/injector/injector'; | ||
import { EncodeTransactionOptions } from 'src/features/common/models/encode-transaction-options'; | ||
import { rubicProxyContractAddress } from 'src/features/cross-chain/calculation-manager/providers/common/constants/rubic-proxy-contract-address'; | ||
import { piteasRouterAddress } from 'src/features/on-chain/calculation-manager/providers/aggregators/piteas/constants/piteas-router-address'; | ||
import { | ||
PiteasMethodParameters, | ||
PiteasQuoteRequestParams | ||
} from 'src/features/on-chain/calculation-manager/providers/aggregators/piteas/models/piteas-quote'; | ||
import { PiteasTradeStruct } from 'src/features/on-chain/calculation-manager/providers/aggregators/piteas/models/piteas-trade-struct'; | ||
import { PiteasApiService } from 'src/features/on-chain/calculation-manager/providers/aggregators/piteas/piteas-api-service'; | ||
import { | ||
ON_CHAIN_TRADE_TYPE, | ||
OnChainTradeType | ||
} from 'src/features/on-chain/calculation-manager/providers/common/models/on-chain-trade-type'; | ||
import { AggregatorEvmOnChainTrade } from 'src/features/on-chain/calculation-manager/providers/common/on-chain-aggregator/aggregator-evm-on-chain-trade-abstract'; | ||
import { GetToAmountAndTxDataResponse } from 'src/features/on-chain/calculation-manager/providers/common/on-chain-aggregator/models/aggregator-on-chain-types'; | ||
import { EvmOnChainTradeStruct } from 'src/features/on-chain/calculation-manager/providers/common/on-chain-trade/evm-on-chain-trade/models/evm-on-chain-trade-struct'; | ||
|
||
export class PiteasTrade extends AggregatorEvmOnChainTrade { | ||
public static async getGasLimit( | ||
tradeStruct: EvmOnChainTradeStruct, | ||
providerGateway: string, | ||
methodParameters: PiteasMethodParameters | ||
): Promise<BigNumber | null> { | ||
const fromBlockchain = tradeStruct.from.blockchain; | ||
const walletAddress = | ||
Injector.web3PrivateService.getWeb3PrivateByBlockchain(fromBlockchain).address; | ||
if (!walletAddress) { | ||
return null; | ||
} | ||
|
||
try { | ||
const web3Public = Injector.web3PublicService.getWeb3Public(fromBlockchain); | ||
const gasLimit = await web3Public.getEstimatedGasByData( | ||
walletAddress, | ||
providerGateway, | ||
{ | ||
data: methodParameters.calldata, | ||
value: methodParameters.value | ||
} | ||
); | ||
|
||
if (!gasLimit?.isFinite()) { | ||
return null; | ||
} | ||
return gasLimit; | ||
} catch (err) { | ||
console.debug(err); | ||
return null; | ||
} | ||
} | ||
|
||
public readonly type: OnChainTradeType = ON_CHAIN_TRADE_TYPE.PITEAS; | ||
|
||
public readonly providerGateway = piteasRouterAddress; | ||
|
||
private readonly quoteRequestParams: PiteasQuoteRequestParams; | ||
|
||
protected get spenderAddress(): string { | ||
return this.useProxy | ||
? rubicProxyContractAddress[this.from.blockchain].gateway | ||
: this.providerGateway; | ||
} | ||
|
||
public get dexContractAddress(): string { | ||
return piteasRouterAddress; | ||
} | ||
|
||
constructor( | ||
tradeStruct: PiteasTradeStruct, | ||
providerAddress: string, | ||
quoteRequestParams: PiteasQuoteRequestParams | ||
) { | ||
super(tradeStruct, providerAddress); | ||
|
||
this.quoteRequestParams = quoteRequestParams; | ||
} | ||
|
||
public async encodeDirect(options: EncodeTransactionOptions): Promise<EvmEncodeConfig> { | ||
await this.checkFromAddress(options.fromAddress, true); | ||
await this.checkReceiverAddress(options.receiverAddress); | ||
|
||
try { | ||
const transactionData = await this.getTxConfigAndCheckAmount( | ||
options.receiverAddress, | ||
options.fromAddress, | ||
options.directTransaction | ||
); | ||
|
||
const { gas, gasPrice } = this.getGasParams(options, { | ||
gasLimit: transactionData.gas, | ||
gasPrice: transactionData.gasPrice | ||
}); | ||
|
||
return { | ||
to: transactionData.to, | ||
data: transactionData.data, | ||
value: transactionData.value, | ||
gas, | ||
gasPrice | ||
}; | ||
} catch (error) { | ||
throw parseError(error); | ||
} | ||
} | ||
|
||
public async getToAmountAndTxData( | ||
receiverAddress?: string, | ||
fromAddress?: string | ||
): Promise<GetToAmountAndTxDataResponse> { | ||
const account = receiverAddress || fromAddress; | ||
try { | ||
const { destAmount, gasUseEstimate, methodParameters } = | ||
await PiteasApiService.fetchQuote({ | ||
...this.quoteRequestParams, | ||
account | ||
}); | ||
|
||
const tx: EvmEncodeConfig = { | ||
to: piteasRouterAddress, | ||
data: methodParameters.calldata, | ||
value: methodParameters.value, | ||
gas: gasUseEstimate.toString() | ||
}; | ||
|
||
return { | ||
tx, | ||
toAmount: destAmount | ||
}; | ||
} catch (error) { | ||
if ('statusCode' in error && 'message' in error) { | ||
throw new RubicSdkError(error.message); | ||
} | ||
throw error; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters