Merge remote-tracking branch origin/main into OP-5070-visible-assets

This commit is contained in:
Kirill Litvinov
2024-06-10 10:36:17 +03:00
11 changed files with 38 additions and 50 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "@orionprotocol/sdk", "name": "@orionprotocol/sdk",
"version": "0.20.76-rc110", "version": "0.22.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@orionprotocol/sdk", "name": "@orionprotocol/sdk",
"version": "0.20.76-rc110", "version": "0.22.0",
"hasInstallScript": true, "hasInstallScript": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@orionprotocol/sdk", "name": "@orionprotocol/sdk",
"version": "0.20.61-rc5", "version": "0.20.61-rc6",
"description": "Orion Protocol SDK", "description": "Orion Protocol SDK",
"main": "./lib/index.cjs", "main": "./lib/index.cjs",
"module": "./lib/index.js", "module": "./lib/index.js",

View File

@@ -8,7 +8,6 @@ import type { BlockchainService } from '../../services/BlockchainService/index.j
import { calculateFeeInFeeAsset, denormalizeNumber, getNativeCryptocurrencyName } from '../../utils/index.js'; import { calculateFeeInFeeAsset, denormalizeNumber, getNativeCryptocurrencyName } from '../../utils/index.js';
export type GetSwapInfoParams = { export type GetSwapInfoParams = {
type: 'exactSpend' | 'exactReceive'
assetIn: string assetIn: string
assetOut: string assetOut: string
amount: BigNumber.Value amount: BigNumber.Value
@@ -18,12 +17,12 @@ export type GetSwapInfoParams = {
options?: { options?: {
instantSettlement?: boolean instantSettlement?: boolean
poolOnly?: boolean poolOnly?: boolean
}, }
walletAddress?: string, walletAddress?: string
isTradeBuy?: boolean
} }
export default async function getSwapInfo({ export default async function getSwapInfo({
type,
assetIn, assetIn,
assetOut, assetOut,
amount, amount,
@@ -32,6 +31,7 @@ export default async function getSwapInfo({
aggregator, aggregator,
options, options,
walletAddress, walletAddress,
isTradeBuy = false,
}: GetSwapInfoParams) { }: GetSwapInfoParams) {
if (amount === '') throw new Error('Amount can not be empty'); if (amount === '') throw new Error('Amount can not be empty');
if (assetIn === '') throw new Error('AssetIn can not be empty'); if (assetIn === '') throw new Error('AssetIn can not be empty');
@@ -61,7 +61,6 @@ export default async function getSwapInfo({
} }
const swapInfo = await simpleFetch(aggregator.getSwapInfo)( const swapInfo = await simpleFetch(aggregator.getSwapInfo)(
type,
assetIn, assetIn,
assetOut, assetOut,
amountBN.toString(), amountBN.toString(),
@@ -69,6 +68,7 @@ export default async function getSwapInfo({
options?.poolOnly !== undefined && options.poolOnly options?.poolOnly !== undefined && options.poolOnly
? 'pools' ? 'pools'
: undefined, : undefined,
isTradeBuy,
); );
const { exchanges: swapExchanges } = swapInfo; const { exchanges: swapExchanges } = swapInfo;
@@ -76,16 +76,6 @@ export default async function getSwapInfo({
const poolExchangesList = factories !== undefined ? Object.keys(factories) : []; const poolExchangesList = factories !== undefined ? Object.keys(factories) : [];
const [firstSwapExchange] = swapExchanges; const [firstSwapExchange] = swapExchanges;
// if (swapInfo.type === 'exactReceive' && amountBN.lt(swapInfo.minAmountOut)) {
// throw new Error(`Amount is too low. Min amountOut is ${swapInfo.minAmountOut} ${assetOut}`);
// }
// if (swapInfo.type === 'exactSpend' && amountBN.lt(swapInfo.minAmountIn)) {
// throw new Error(`Amount is too low. Min amountIn is ${swapInfo.minAmountIn} ${assetIn}`);
// }
// if (swapInfo.orderInfo === null) throw new Error(swapInfo.executionInfo);
let route: 'pool' | 'aggregator'; let route: 'pool' | 'aggregator';
if (options?.poolOnly !== undefined && options.poolOnly) { if (options?.poolOnly !== undefined && options.poolOnly) {
route = 'pool'; route = 'pool';

View File

@@ -18,7 +18,6 @@ import type { SingleSwap } from '../../types.js';
import { must, safeGet } from '../../utils/safeGetters.js'; import { must, safeGet } from '../../utils/safeGetters.js';
export type SwapLimitParams = { export type SwapLimitParams = {
type: 'exactSpend' | 'exactReceive'
assetIn: string assetIn: string
assetOut: string assetOut: string
price: BigNumber.Value price: BigNumber.Value
@@ -35,6 +34,7 @@ export type SwapLimitParams = {
route?: 'aggregator' | 'pool' route?: 'aggregator' | 'pool'
} }
} }
isTradeBuy?: boolean
} }
type AggregatorOrder = { type AggregatorOrder = {
@@ -58,7 +58,6 @@ const isValidSingleSwap = (singleSwap: Omit<SingleSwap, 'factory'> & { factory:
} }
export default async function swapLimit({ export default async function swapLimit({
type,
assetIn, assetIn,
assetOut, assetOut,
price, price,
@@ -67,6 +66,7 @@ export default async function swapLimit({
signer, signer,
unit, unit,
options, options,
isTradeBuy = false,
}: SwapLimitParams): Promise<Swap> { }: SwapLimitParams): Promise<Swap> {
if (options?.developer) options.logger?.('YOU SPECIFIED A DEVELOPER OPTIONS. BE CAREFUL!'); if (options?.developer) options.logger?.('YOU SPECIFIED A DEVELOPER OPTIONS. BE CAREFUL!');
if (amount === '') throw new Error('Amount can not be empty'); if (amount === '') throw new Error('Amount can not be empty');
@@ -138,7 +138,6 @@ export default async function swapLimit({
); );
const swapInfo = await simpleFetch(aggregator.getSwapInfo)( const swapInfo = await simpleFetch(aggregator.getSwapInfo)(
type,
assetIn, assetIn,
assetOut, assetOut,
amountBN.toString(), amountBN.toString(),
@@ -146,6 +145,7 @@ export default async function swapLimit({
options?.poolOnly !== undefined && options.poolOnly options?.poolOnly !== undefined && options.poolOnly
? 'pools' ? 'pools'
: undefined, : undefined,
isTradeBuy,
); );
const { exchanges: swapExchanges, exchangeContractPath } = swapInfo; const { exchanges: swapExchanges, exchangeContractPath } = swapInfo;
@@ -154,11 +154,11 @@ export default async function swapLimit({
if (swapExchanges.length > 0) options?.logger?.(`Swap exchanges: ${swapExchanges.join(', ')}`); if (swapExchanges.length > 0) options?.logger?.(`Swap exchanges: ${swapExchanges.join(', ')}`);
if (swapInfo.type === 'exactReceive' && amountBN.lt(swapInfo.minAmountOut)) { if (swapInfo?.isTradeBuy && amountBN.lt(swapInfo.minAmountOut)) {
throw new Error(`Amount is too low. Min amountOut is ${swapInfo.minAmountOut} ${assetOut}`); throw new Error(`Amount is too low. Min amountOut is ${swapInfo.minAmountOut} ${assetOut}`);
} }
if (swapInfo.type === 'exactSpend' && amountBN.lt(swapInfo.minAmountIn)) { if (!(swapInfo?.isTradeBuy) && amountBN.lt(swapInfo.minAmountIn)) {
throw new Error(`Amount is too low. Min amountIn is ${swapInfo.minAmountIn} ${assetIn}`); throw new Error(`Amount is too low. Min amountIn is ${swapInfo.minAmountIn} ${assetIn}`);
} }
@@ -200,9 +200,9 @@ export default async function swapLimit({
options?.logger?.(`Safe price is ${swapInfo.orderInfo.safePrice} ${quoteAssetName}`); options?.logger?.(`Safe price is ${swapInfo.orderInfo.safePrice} ${quoteAssetName}`);
// BTEMP — better than or equal market price // BTEMP — better than or equal market price
const priceIsBTEMP = type === 'exactSpend' const priceIsBTEMP = isTradeBuy
? priceBN.lte(swapInfo.orderInfo.safePrice) ? priceBN.gte(swapInfo.orderInfo.safePrice)
: priceBN.gte(swapInfo.orderInfo.safePrice); : priceBN.lte(swapInfo.orderInfo.safePrice);
options?.logger?.(`Your price ${priceBN.toString()} is ${priceIsBTEMP ? 'better than or equal' : 'worse than'} market price ${swapInfo.orderInfo.safePrice}`); options?.logger?.(`Your price ${priceBN.toString()} is ${priceIsBTEMP ? 'better than or equal' : 'worse than'} market price ${swapInfo.orderInfo.safePrice}`);
@@ -246,7 +246,7 @@ export default async function swapLimit({
if (factoryAddress !== undefined) options?.logger?.(`Factory address is ${factoryAddress}. Exchange is ${firstSwapExchange}`); if (factoryAddress !== undefined) options?.logger?.(`Factory address is ${factoryAddress}. Exchange is ${firstSwapExchange}`);
} }
const amountSpend = swapInfo.type === 'exactSpend' const amountSpend = !(swapInfo?.isTradeBuy)
? swapInfo.amountIn ? swapInfo.amountIn
: new BigNumber(swapInfo.orderInfo.amount).multipliedBy(swapInfo.orderInfo.safePrice) : new BigNumber(swapInfo.orderInfo.amount).multipliedBy(swapInfo.orderInfo.safePrice)
@@ -261,7 +261,7 @@ export default async function swapLimit({
sources: getAvailableSources('amount', assetInAddress, 'pool'), sources: getAvailableSources('amount', assetInAddress, 'pool'),
}); });
const amountReceive = swapInfo.type === 'exactReceive' const amountReceive = swapInfo?.isTradeBuy
? swapInfo.amountOut ? swapInfo.amountOut
: new BigNumber(swapInfo.orderInfo.amount).multipliedBy(swapInfo.orderInfo.safePrice) : new BigNumber(swapInfo.orderInfo.amount).multipliedBy(swapInfo.orderInfo.safePrice)
const amountSpendBlockchainParam = normalizeNumber( const amountSpendBlockchainParam = normalizeNumber(

View File

@@ -37,13 +37,11 @@ type PoolSwap = {
export type Swap = AggregatorOrder | PoolSwap; export type Swap = AggregatorOrder | PoolSwap;
const isValidSingleSwap = (singleSwap: Omit<SingleSwap, 'factory'> & { factory: string }): singleSwap is SingleSwap => { const isValidSingleSwap = (singleSwap: Omit<SingleSwap, 'factory'> & { factory: string }): singleSwap is SingleSwap => {
return isValidFactory(singleSwap.factory); return isValidFactory(singleSwap.factory);
} }
export default async function swapMarket({ export default async function swapMarket({
type,
assetIn, assetIn,
assetOut, assetOut,
amount, amount,
@@ -52,6 +50,7 @@ export default async function swapMarket({
signer, signer,
unit, unit,
options, options,
isTradeBuy = false,
}: SwapMarketParams): Promise<Swap> { }: SwapMarketParams): Promise<Swap> {
if (options?.developer) options.logger?.('YOU SPECIFIED A DEVELOPER OPTIONS. BE CAREFUL!'); if (options?.developer) options.logger?.('YOU SPECIFIED A DEVELOPER OPTIONS. BE CAREFUL!');
@@ -125,7 +124,6 @@ export default async function swapMarket({
); );
const swapInfo = await simpleFetch(aggregator.getSwapInfo)( const swapInfo = await simpleFetch(aggregator.getSwapInfo)(
type,
assetIn, assetIn,
assetOut, assetOut,
amountBN.toString(), amountBN.toString(),
@@ -133,6 +131,7 @@ export default async function swapMarket({
options?.poolOnly !== undefined && options.poolOnly options?.poolOnly !== undefined && options.poolOnly
? 'pools' ? 'pools'
: undefined, : undefined,
isTradeBuy,
); );
const { exchanges: swapExchanges, exchangeContractPath } = swapInfo; const { exchanges: swapExchanges, exchangeContractPath } = swapInfo;
@@ -141,11 +140,11 @@ export default async function swapMarket({
if (swapExchanges.length > 0) options?.logger?.(`Swap exchanges: ${swapExchanges.join(', ')}`); if (swapExchanges.length > 0) options?.logger?.(`Swap exchanges: ${swapExchanges.join(', ')}`);
if (swapInfo.type === 'exactReceive' && amountBN.lt(swapInfo.minAmountOut)) { if (swapInfo?.isTradeBuy && amountBN.lt(swapInfo.minAmountOut)) {
throw new Error(`Amount is too low. Min amountOut is ${swapInfo.minAmountOut} ${assetOut}`); throw new Error(`Amount is too low. Min amountOut is ${swapInfo.minAmountOut} ${assetOut}`);
} }
if (swapInfo.type === 'exactSpend' && amountBN.lt(swapInfo.minAmountIn)) { if (!(swapInfo?.isTradeBuy) && amountBN.lt(swapInfo.minAmountIn)) {
throw new Error(`Amount is too low. Min amountIn is ${swapInfo.minAmountIn} ${assetIn}`); throw new Error(`Amount is too low. Min amountIn is ${swapInfo.minAmountIn} ${assetIn}`);
} }
@@ -203,7 +202,7 @@ export default async function swapMarket({
.multipliedBy(new BigNumber(1).plus(percent)) .multipliedBy(new BigNumber(1).plus(percent))
.toString(); .toString();
const amountSpend = swapInfo.type === 'exactSpend' ? swapInfo.amountIn : amountInWithSlippage; const amountSpend = swapInfo?.isTradeBuy ? amountInWithSlippage : swapInfo.amountIn;
balanceGuard.registerRequirement({ balanceGuard.registerRequirement({
reason: 'Amount spend', reason: 'Amount spend',
@@ -216,7 +215,7 @@ export default async function swapMarket({
sources: getAvailableSources('amount', assetInAddress, 'pool'), sources: getAvailableSources('amount', assetInAddress, 'pool'),
}); });
const amountReceive = swapInfo.type === 'exactReceive' ? swapInfo.amountOut : amountOutWithSlippage; const amountReceive = swapInfo?.isTradeBuy ? amountOutWithSlippage : swapInfo.amountOut;
const amountSpendBlockchainParam = normalizeNumber( const amountSpendBlockchainParam = normalizeNumber(
amountSpend, amountSpend,
INTERNAL_PROTOCOL_PRECISION, INTERNAL_PROTOCOL_PRECISION,

View File

@@ -263,21 +263,22 @@ class Aggregator {
); );
getSwapInfo = ( getSwapInfo = (
type: 'exactSpend' | 'exactReceive',
assetIn: string, assetIn: string,
assetOut: string, assetOut: string,
amount: string, amount: string,
instantSettlement?: boolean, instantSettlement?: boolean,
exchanges?: string[] | 'cex' | 'pools', exchanges?: string[] | 'cex' | 'pools',
isTradeBuy?: boolean,
) => { ) => {
const url = new URL(`${this.apiUrl}/api/v1/swap`); const url = new URL(`${this.apiUrl}/api/v1/swap`);
url.searchParams.append('assetIn', assetIn); url.searchParams.append('assetIn', assetIn);
url.searchParams.append('assetOut', assetOut); url.searchParams.append('assetOut', assetOut);
if (type === 'exactSpend') { if (isTradeBuy !== true) {
url.searchParams.append('amountIn', amount); url.searchParams.append('amountIn', amount);
} else { } else {
url.searchParams.append('amountOut', amount); url.searchParams.append('amountOut', amount);
} }
if (exchanges !== undefined) { if (exchanges !== undefined) {
if (Array.isArray(exchanges)) { if (Array.isArray(exchanges)) {
exchanges.forEach((exchange) => { exchanges.forEach((exchange) => {

View File

@@ -61,7 +61,7 @@ const swapInfoByAmountIn = swapInfoBase.extend({
marketAmountIn: z.null(), marketAmountIn: z.null(),
}).transform((val) => ({ }).transform((val) => ({
...val, ...val,
type: 'exactSpend' as const, isTradeBuy: false as const,
})); }));
const swapInfoByAmountOut = swapInfoBase.extend({ const swapInfoByAmountOut = swapInfoBase.extend({
@@ -71,7 +71,7 @@ const swapInfoByAmountOut = swapInfoBase.extend({
marketAmountIn: z.number().nullable(), marketAmountIn: z.number().nullable(),
}).transform((val) => ({ }).transform((val) => ({
...val, ...val,
type: 'exactReceive' as const, isTradeBuy: true as const,
})); }));
const swapInfoSchema = swapInfoByAmountIn.or(swapInfoByAmountOut); const swapInfoSchema = swapInfoByAmountIn.or(swapInfoByAmountOut);

View File

@@ -572,19 +572,19 @@ class AggregatorWS {
autoSlippage: json.sl, autoSlippage: json.sl,
}; };
switch (json.k) { // kind switch (json.tb) { // isTradeBuy
case 'exactSpend': case false:
this.subscriptions[SubscriptionType.SWAP_SUBSCRIBE]?.[json.S]?.callback({ this.subscriptions[SubscriptionType.SWAP_SUBSCRIBE]?.[json.S]?.callback({
kind: json.k, isTradeBuy: false,
marketAmountOut: json.mo, marketAmountOut: json.mo,
availableAmountIn: json.aa, availableAmountIn: json.aa,
...baseSwapInfo, ...baseSwapInfo,
}); });
break; break;
case 'exactReceive': case true:
this.subscriptions[SubscriptionType.SWAP_SUBSCRIBE]?.[json.S]?.callback({ this.subscriptions[SubscriptionType.SWAP_SUBSCRIBE]?.[json.S]?.callback({
kind: json.k, isTradeBuy: true,
...baseSwapInfo, ...baseSwapInfo,
marketAmountIn: json.mi, marketAmountIn: json.mi,
availableAmountOut: json.aao, availableAmountOut: json.aao,

View File

@@ -59,7 +59,7 @@ const swapInfoSchemaByAmountIn = swapInfoSchemaBase.extend({
aa: z.number(), // available amount in aa: z.number(), // available amount in
}).transform((content) => ({ }).transform((content) => ({
...content, ...content,
k: 'exactSpend' as const, tb: false as const, // isTradeBuy
})); }));
const swapInfoSchemaByAmountOut = swapInfoSchemaBase.extend({ const swapInfoSchemaByAmountOut = swapInfoSchemaBase.extend({
@@ -67,7 +67,7 @@ const swapInfoSchemaByAmountOut = swapInfoSchemaBase.extend({
aao: z.number(), // available amount out aao: z.number(), // available amount out
}).transform((content) => ({ }).transform((content) => ({
...content, ...content,
k: 'exactReceive' as const, tb: true as const, // isTradeBuy
})); }));
const swapInfoSchema = z.union([ const swapInfoSchema = z.union([

View File

@@ -219,13 +219,13 @@ export type SwapInfoBase = {
} }
export type SwapInfoByAmountIn = SwapInfoBase & { export type SwapInfoByAmountIn = SwapInfoBase & {
kind: 'exactSpend' isTradeBuy: false
availableAmountIn?: number | undefined availableAmountIn?: number | undefined
marketAmountOut?: number | undefined marketAmountOut?: number | undefined
} }
export type SwapInfoByAmountOut = SwapInfoBase & { export type SwapInfoByAmountOut = SwapInfoBase & {
kind: 'exactReceive' isTradeBuy: true
marketAmountIn?: number | undefined marketAmountIn?: number | undefined
availableAmountOut?: number | undefined availableAmountOut?: number | undefined
} }

View File

@@ -8,7 +8,6 @@ const swapThroughOrionPoolSchema = z.object({
z.bigint(), // amount_spend z.bigint(), // amount_spend
z.bigint(), // amount_receive z.bigint(), // amount_receive
z.string().refine(ethers.isAddress).array().nonempty(), // path z.string().refine(ethers.isAddress).array().nonempty(), // path
z.boolean(), // is_exact_spend
]), ]),
}).transform((data) => ({ }).transform((data) => ({
name: data.name, name: data.name,
@@ -16,7 +15,6 @@ const swapThroughOrionPoolSchema = z.object({
amount_spend: data.args[0], amount_spend: data.args[0],
amount_receive: data.args[1], amount_receive: data.args[1],
path: data.args[2], path: data.args[2],
is_exact_spend: data.args[3],
}, },
})); }));