mirror of
https://github.com/orionprotocol/sdk.git
synced 2026-03-14 14:12:35 +03:00
Added deposit
This commit is contained in:
@@ -30,7 +30,7 @@ const wallet = new Wallet(privateKey);
|
||||
const orionUnit = initOrionUnit(chain, env);
|
||||
|
||||
// Make market swap
|
||||
orionUnit
|
||||
orionUnit.exchange
|
||||
.swapMarket({
|
||||
type: "exactSpend",
|
||||
assetIn: "ORN",
|
||||
@@ -153,7 +153,7 @@ orionUnit.orionAggregator.ws.subscribe(
|
||||
d: swapRequestId, // generated by client
|
||||
i: assetIn, // asset in
|
||||
o: assetOut, // asset out
|
||||
e: true, // true when type of swap is exactSpend, can be omitted (true bu default)
|
||||
e: true, // true when type of swap is exactSpend, can be omitted (true by default)
|
||||
a: 5.62345343, // amount
|
||||
},
|
||||
// Handle data update in your way
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@orionprotocol/sdk",
|
||||
"version": "1.0.85-new-balances",
|
||||
"version": "0.2.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@orionprotocol/sdk",
|
||||
"version": "1.0.85-new-balances",
|
||||
"version": "0.2.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@ethersproject/abstract-signer": "^5.6.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@orionprotocol/sdk",
|
||||
"version": "0.1.1",
|
||||
"version": "0.2.0",
|
||||
"description": "Orion Protocol SDK",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/index.d.ts",
|
||||
|
||||
@@ -4,41 +4,9 @@ import clone from 'just-clone';
|
||||
import { contracts, utils } from '.';
|
||||
import { APPROVE_ERC20_GAS_LIMIT, NATIVE_CURRENCY_PRECISION } from './constants';
|
||||
import {
|
||||
AggregatedBalanceRequirement, Asset, BalanceIssue, BalanceRequirement, Source,
|
||||
AggregatedBalanceRequirement, Approve, Asset, BalanceIssue, BalanceRequirement, Source,
|
||||
} from './types';
|
||||
|
||||
const arrayEquals = (a: unknown[], b: unknown[]) => a.length === b.length
|
||||
&& a.every((value, index) => value === b[index]);
|
||||
|
||||
// By asset + sources + spender
|
||||
const aggregateBalanceRequirements = (requirements: BalanceRequirement[]) => requirements
|
||||
.reduce<AggregatedBalanceRequirement[]>((prev, curr) => {
|
||||
const aggregatedBalanceRequirement = prev.find(
|
||||
(item) => item.asset.address === curr.asset.address
|
||||
&& arrayEquals(item.sources, curr.sources)
|
||||
&& item.spenderAddress === curr.spenderAddress,
|
||||
);
|
||||
|
||||
if (aggregatedBalanceRequirement) {
|
||||
aggregatedBalanceRequirement.items = {
|
||||
...aggregatedBalanceRequirement.items,
|
||||
[curr.reason]: curr.amount,
|
||||
};
|
||||
return prev;
|
||||
}
|
||||
return [
|
||||
...prev,
|
||||
{
|
||||
asset: curr.asset,
|
||||
sources: curr.sources,
|
||||
spenderAddress: curr.spenderAddress,
|
||||
items: {
|
||||
[curr.reason]: curr.amount,
|
||||
},
|
||||
},
|
||||
|
||||
];
|
||||
}, []);
|
||||
import arrayEquals from './utils/arrayEquals';
|
||||
|
||||
export default class BalanceGuard {
|
||||
private readonly balances: Partial<
|
||||
@@ -56,18 +24,18 @@ export default class BalanceGuard {
|
||||
|
||||
private readonly provider: ethers.providers.Provider;
|
||||
|
||||
private readonly walletAddress: string;
|
||||
private readonly signer: ethers.Signer;
|
||||
|
||||
constructor(
|
||||
balances: Partial<Record<string, Record<'exchange' | 'wallet' | 'allowance', BigNumber>>>,
|
||||
nativeCryptocurrency: Asset,
|
||||
provider: ethers.providers.Provider,
|
||||
walletAddress: string,
|
||||
signer: ethers.Signer,
|
||||
) {
|
||||
this.balances = balances;
|
||||
this.nativeCryptocurrency = nativeCryptocurrency;
|
||||
this.provider = provider;
|
||||
this.walletAddress = walletAddress;
|
||||
this.signer = signer;
|
||||
}
|
||||
|
||||
registerRequirement(expense: BalanceRequirement) {
|
||||
@@ -84,8 +52,8 @@ export default class BalanceGuard {
|
||||
private async checkResetRequired(
|
||||
assetAddress: string,
|
||||
spenderAddress: string,
|
||||
walletAddress: string,
|
||||
) {
|
||||
const walletAddress = await this.signer.getAddress();
|
||||
const tokenContract = contracts.ERC20__factory
|
||||
.connect(assetAddress, this.provider);
|
||||
const unsignedTx = await tokenContract.populateTransaction
|
||||
@@ -103,9 +71,97 @@ export default class BalanceGuard {
|
||||
return resetRequired;
|
||||
}
|
||||
|
||||
async check() {
|
||||
// By asset + sources + spender
|
||||
static aggregateBalanceRequirements(requirements: BalanceRequirement[]) {
|
||||
return requirements
|
||||
.reduce<AggregatedBalanceRequirement[]>((prev, curr) => {
|
||||
const aggregatedBalanceRequirement = prev.find(
|
||||
(item) => item.asset.address === curr.asset.address
|
||||
&& arrayEquals(item.sources, curr.sources)
|
||||
&& item.spenderAddress === curr.spenderAddress,
|
||||
);
|
||||
|
||||
if (aggregatedBalanceRequirement) {
|
||||
aggregatedBalanceRequirement.items = {
|
||||
...aggregatedBalanceRequirement.items,
|
||||
[curr.reason]: curr.amount,
|
||||
};
|
||||
return prev;
|
||||
}
|
||||
return [
|
||||
...prev,
|
||||
{
|
||||
asset: curr.asset,
|
||||
sources: curr.sources,
|
||||
spenderAddress: curr.spenderAddress,
|
||||
items: {
|
||||
[curr.reason]: curr.amount,
|
||||
},
|
||||
},
|
||||
|
||||
];
|
||||
}, []);
|
||||
}
|
||||
|
||||
private fixAllAutofixableBalanceIssues = async (
|
||||
balanceIssues: BalanceIssue[],
|
||||
) => {
|
||||
const fixBalanceIssue = async (issue: BalanceIssue) => {
|
||||
const tokenContract = contracts.ERC20__factory.connect(issue.asset.address, this.provider);
|
||||
const approve = async ({ spenderAddress, targetAmount }: Approve) => {
|
||||
const bnTargetAmount = new BigNumber(targetAmount);
|
||||
const unsignedApproveTx = await tokenContract
|
||||
.populateTransaction
|
||||
.approve(
|
||||
spenderAddress,
|
||||
bnTargetAmount.isZero()
|
||||
? '0' // Reset
|
||||
: ethers.constants.MaxUint256, // Infinite approve
|
||||
);
|
||||
|
||||
const walletAddress = await this.signer.getAddress();
|
||||
const nonce = await this.provider.getTransactionCount(walletAddress, 'pending');
|
||||
const gasPrice = await this.provider.getGasPrice();
|
||||
const network = await this.provider.getNetwork();
|
||||
|
||||
unsignedApproveTx.chainId = network.chainId;
|
||||
unsignedApproveTx.gasPrice = gasPrice;
|
||||
unsignedApproveTx.nonce = nonce;
|
||||
unsignedApproveTx.from = walletAddress;
|
||||
const gasLimit = await this.provider.estimateGas(unsignedApproveTx);
|
||||
unsignedApproveTx.gasLimit = gasLimit;
|
||||
|
||||
const signedTx = await this.signer.signTransaction(unsignedApproveTx);
|
||||
const txResponse = await this.provider.sendTransaction(signedTx);
|
||||
console.log(`${issue.asset.name} approve transaction sent ${txResponse.hash}. Waiting for confirmation...`);
|
||||
await txResponse.wait();
|
||||
console.log(`${issue.asset.name} approve transaction confirmed.`);
|
||||
};
|
||||
await issue.approves?.reduce(async (promise, item) => {
|
||||
await promise;
|
||||
return approve(item);
|
||||
}, Promise.resolve());
|
||||
};
|
||||
|
||||
const autofixableBalanceIssues = balanceIssues.filter((balanceIssue) => balanceIssue.approves);
|
||||
|
||||
await autofixableBalanceIssues.reduce(async (promise, item) => {
|
||||
await promise;
|
||||
return fixBalanceIssue(item);
|
||||
}, Promise.resolve());
|
||||
|
||||
return balanceIssues.filter((item) => !autofixableBalanceIssues.includes(item));
|
||||
};
|
||||
|
||||
async check(fixAutofixable?: boolean) {
|
||||
console.log(`Balance requirements: ${this.requirements
|
||||
.map((requirement) => `${requirement.amount} ${requirement.asset.name} `
|
||||
+ `for '${requirement.reason}' `
|
||||
+ `from [${requirement.sources.join(' + ')}]`)
|
||||
.join(', ')}`);
|
||||
|
||||
const remainingBalances = clone(this.balances);
|
||||
const aggregatedRequirements = aggregateBalanceRequirements(this.requirements);
|
||||
const aggregatedRequirements = BalanceGuard.aggregateBalanceRequirements(this.requirements);
|
||||
|
||||
// Balance absorption order is important!
|
||||
// 1. Exchange-contract only
|
||||
@@ -193,7 +249,6 @@ export default class BalanceGuard {
|
||||
const resetRequired = await this.checkResetRequired(
|
||||
asset.address,
|
||||
spenderAddress,
|
||||
this.walletAddress,
|
||||
);
|
||||
const gasPriceWei = await this.provider.getGasPrice();
|
||||
const approveTransactionCost = ethers.BigNumber
|
||||
@@ -269,7 +324,6 @@ export default class BalanceGuard {
|
||||
const resetRequired = await this.checkResetRequired(
|
||||
asset.address,
|
||||
spenderAddress,
|
||||
this.walletAddress,
|
||||
);
|
||||
const gasPriceWei = await this.provider.getGasPrice();
|
||||
const approveTransactionCost = ethers.BigNumber
|
||||
@@ -332,6 +386,11 @@ export default class BalanceGuard {
|
||||
}
|
||||
});
|
||||
|
||||
return balanceIssues;
|
||||
if (fixAutofixable) {
|
||||
const unfixed = await this.fixAllAutofixableBalanceIssues(balanceIssues);
|
||||
if (unfixed.length > 0) throw new Error(`Balance issues: ${unfixed.map((issue, i) => `${i + 1}. ${issue.message}`).join('\n')}`);
|
||||
} else if (balanceIssues.length > 0) {
|
||||
throw new Error(`Balance issues: ${balanceIssues.map((issue, i) => `${i + 1}. ${issue.message}`).join('\n')}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
136
src/OrionUnit/Exchange/deposit.ts
Normal file
136
src/OrionUnit/Exchange/deposit.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
/* eslint-disable max-len */
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { ethers } from 'ethers';
|
||||
import getBalances from '../../utils/getBalances';
|
||||
import BalanceGuard from '../../BalanceGuard';
|
||||
import OrionUnit from '..';
|
||||
import { contracts, utils } from '../..';
|
||||
import {
|
||||
DEPOSIT_ERC20_GAS_LIMIT, DEPOSIT_ETH_GAS_LIMIT, INTERNAL_ORION_PRECISION, NATIVE_CURRENCY_PRECISION,
|
||||
} from '../../constants';
|
||||
import { normalizeNumber } from '../../utils';
|
||||
|
||||
export type DepositParams = {
|
||||
asset: string,
|
||||
amount: BigNumber.Value,
|
||||
signer: ethers.Signer,
|
||||
orionUnit: OrionUnit,
|
||||
}
|
||||
|
||||
export default async function deposit({
|
||||
asset,
|
||||
amount,
|
||||
signer,
|
||||
orionUnit,
|
||||
}: DepositParams) {
|
||||
if (asset === '') throw new Error('Asset can not be empty');
|
||||
|
||||
const amountBN = new BigNumber(amount);
|
||||
if (amountBN.isNaN()) throw new Error(`Amount '${amount.toString()}' is not a number`);
|
||||
if (amountBN.lte(0)) throw new Error(`Amount '${amount.toString()}' should be greater than 0`);
|
||||
|
||||
const walletAddress = await signer.getAddress();
|
||||
|
||||
const {
|
||||
orionBlockchain, orionAggregator, provider, chainId,
|
||||
} = orionUnit;
|
||||
const {
|
||||
exchangeContractAddress,
|
||||
assetToAddress,
|
||||
} = await orionBlockchain.getInfo();
|
||||
const addressToAsset = Object
|
||||
.entries(assetToAddress)
|
||||
.reduce<Partial<Record<string, string>>>((prev, [assetName, address]) => {
|
||||
if (!address) return prev;
|
||||
return {
|
||||
...prev,
|
||||
[address]: assetName,
|
||||
};
|
||||
}, {});
|
||||
|
||||
const nativeCryptocurrency = addressToAsset[ethers.constants.AddressZero];
|
||||
if (!nativeCryptocurrency) throw new Error('Native cryptocurrency asset is not found');
|
||||
|
||||
const exchangeContract = contracts.Exchange__factory.connect(exchangeContractAddress, provider);
|
||||
const gasPriceWei = await orionBlockchain.getGasPriceWei();
|
||||
|
||||
const assetAddress = assetToAddress[asset];
|
||||
if (!assetAddress) throw new Error(`Asset '${asset}' not found`);
|
||||
|
||||
const balances = await getBalances(
|
||||
{
|
||||
[asset]: assetAddress,
|
||||
[nativeCryptocurrency]: ethers.constants.AddressZero,
|
||||
},
|
||||
orionAggregator,
|
||||
walletAddress,
|
||||
exchangeContract,
|
||||
provider,
|
||||
);
|
||||
|
||||
const balanceGuard = new BalanceGuard(
|
||||
balances,
|
||||
{
|
||||
name: nativeCryptocurrency,
|
||||
address: ethers.constants.AddressZero,
|
||||
},
|
||||
provider,
|
||||
signer,
|
||||
);
|
||||
|
||||
balanceGuard.registerRequirement({
|
||||
reason: 'Amount',
|
||||
asset: {
|
||||
name: asset,
|
||||
address: assetAddress,
|
||||
},
|
||||
amount: amount.toString(),
|
||||
spenderAddress: exchangeContractAddress,
|
||||
sources: ['wallet'],
|
||||
});
|
||||
|
||||
let unsignedTx: ethers.PopulatedTransaction;
|
||||
if (asset === nativeCryptocurrency) {
|
||||
unsignedTx = await exchangeContract.populateTransaction.deposit();
|
||||
unsignedTx.value = normalizeNumber(amount, NATIVE_CURRENCY_PRECISION, BigNumber.ROUND_CEIL);
|
||||
unsignedTx.gasLimit = ethers.BigNumber.from(DEPOSIT_ETH_GAS_LIMIT);
|
||||
} else {
|
||||
unsignedTx = await exchangeContract.populateTransaction.depositAsset(
|
||||
assetAddress,
|
||||
normalizeNumber(amount, INTERNAL_ORION_PRECISION, BigNumber.ROUND_CEIL),
|
||||
);
|
||||
unsignedTx.gasLimit = ethers.BigNumber.from(DEPOSIT_ERC20_GAS_LIMIT);
|
||||
}
|
||||
|
||||
const transactionCost = ethers.BigNumber.from(unsignedTx.gasLimit).mul(gasPriceWei);
|
||||
const denormalizedTransactionCost = utils.denormalizeNumber(transactionCost, NATIVE_CURRENCY_PRECISION);
|
||||
|
||||
balanceGuard.registerRequirement({
|
||||
reason: 'Network fee',
|
||||
asset: {
|
||||
name: nativeCryptocurrency,
|
||||
address: ethers.constants.AddressZero,
|
||||
},
|
||||
amount: denormalizedTransactionCost.toString(),
|
||||
sources: ['wallet'],
|
||||
});
|
||||
|
||||
unsignedTx.chainId = parseInt(chainId, 16);
|
||||
unsignedTx.gasPrice = ethers.BigNumber.from(gasPriceWei);
|
||||
unsignedTx.from = walletAddress;
|
||||
|
||||
await balanceGuard.check(true);
|
||||
|
||||
const nonce = await provider.getTransactionCount(walletAddress, 'pending');
|
||||
unsignedTx.nonce = nonce;
|
||||
|
||||
const signedTx = await signer.signTransaction(unsignedTx);
|
||||
const txResponse = await provider.sendTransaction(signedTx);
|
||||
console.log(`Deposit tx sent: ${txResponse.hash}. Waiting for confirmation...`);
|
||||
const txReceipt = await txResponse.wait();
|
||||
if (txReceipt.status) {
|
||||
console.log('Deposit tx confirmed');
|
||||
} else {
|
||||
console.log('Deposit tx failed');
|
||||
}
|
||||
}
|
||||
28
src/OrionUnit/Exchange/index.ts
Normal file
28
src/OrionUnit/Exchange/index.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import OrionUnit from '..';
|
||||
import deposit, { DepositParams } from './deposit';
|
||||
import swapMarket, { SwapMarketParams } from './swapMarket';
|
||||
|
||||
type PureSwapMarketParams= Omit<SwapMarketParams, 'orionUnit'>
|
||||
type PureDepositParams= Omit<DepositParams, 'orionUnit'>
|
||||
|
||||
export default class Exchange {
|
||||
private readonly orionUnit: OrionUnit;
|
||||
|
||||
constructor(orionUnit: OrionUnit) {
|
||||
this.orionUnit = orionUnit;
|
||||
}
|
||||
|
||||
public swapMarket(params: PureSwapMarketParams) {
|
||||
return swapMarket({
|
||||
...params,
|
||||
orionUnit: this.orionUnit,
|
||||
});
|
||||
}
|
||||
|
||||
public deposit(params: PureDepositParams) {
|
||||
return deposit({
|
||||
...params,
|
||||
orionUnit: this.orionUnit,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
/* eslint-disable max-len */
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { ethers } from 'ethers';
|
||||
import getBalances from '../utils/getBalances';
|
||||
import BalanceGuard from '../BalanceGuard';
|
||||
import getAvailableSources from '../utils/getAvailableFundsSources';
|
||||
import { Approve, BalanceIssue } from '../types';
|
||||
import OrionUnit from '.';
|
||||
import { contracts, crypt, utils } from '..';
|
||||
import { INTERNAL_ORION_PRECISION, NATIVE_CURRENCY_PRECISION, SWAP_THROUGH_ORION_POOL_GAS_LIMIT } from '../constants';
|
||||
import getBalances from '../../utils/getBalances';
|
||||
import BalanceGuard from '../../BalanceGuard';
|
||||
import getAvailableSources from '../../utils/getAvailableFundsSources';
|
||||
import OrionUnit from '..';
|
||||
import { contracts, crypt, utils } from '../..';
|
||||
import { INTERNAL_ORION_PRECISION, NATIVE_CURRENCY_PRECISION, SWAP_THROUGH_ORION_POOL_GAS_LIMIT } from '../../constants';
|
||||
|
||||
export type SwapMarketParams = {
|
||||
type: 'exactSpend' | 'exactReceive',
|
||||
@@ -56,6 +55,7 @@ export default async function swapMarket({
|
||||
|
||||
const amountBN = new BigNumber(amount);
|
||||
if (amountBN.isNaN()) throw new Error(`Amount '${amount.toString()}' is not a number`);
|
||||
if (amountBN.lte(0)) throw new Error(`Amount '${amount.toString()}' should be greater than 0`);
|
||||
|
||||
const slippagePercentBN = new BigNumber(slippagePercent);
|
||||
if (slippagePercentBN.isNaN()) throw new Error(`Slippage percent '${slippagePercent.toString()}' is not a number`);
|
||||
@@ -117,7 +117,7 @@ export default async function swapMarket({
|
||||
address: ethers.constants.AddressZero,
|
||||
},
|
||||
provider,
|
||||
walletAddress,
|
||||
signer,
|
||||
);
|
||||
|
||||
const swapInfo = await orionAggregator.getSwapInfo(type, assetIn, assetOut, amount.toString());
|
||||
@@ -134,40 +134,6 @@ export default async function swapMarket({
|
||||
|
||||
const percent = new BigNumber(slippagePercent).div(100);
|
||||
|
||||
const fixBalanceIssue = async (issue: BalanceIssue) => {
|
||||
const tokenContract = contracts.ERC20__factory.connect(issue.asset.address, provider);
|
||||
const approve = async ({ spenderAddress, targetAmount }: Approve) => {
|
||||
const bnTargetAmount = new BigNumber(targetAmount);
|
||||
const unsignedApproveTx = await tokenContract
|
||||
.populateTransaction
|
||||
.approve(
|
||||
spenderAddress,
|
||||
bnTargetAmount.isZero()
|
||||
? '0' // Reset
|
||||
: ethers.constants.MaxUint256, // Infinite approve
|
||||
);
|
||||
|
||||
const nonce = await provider.getTransactionCount(walletAddress, 'pending');
|
||||
|
||||
unsignedApproveTx.chainId = parseInt(chainId, 16);
|
||||
unsignedApproveTx.gasPrice = ethers.BigNumber.from(gasPriceWei);
|
||||
unsignedApproveTx.nonce = nonce;
|
||||
unsignedApproveTx.from = walletAddress;
|
||||
const gasLimit = await provider.estimateGas(unsignedApproveTx);
|
||||
unsignedApproveTx.gasLimit = gasLimit;
|
||||
|
||||
const signedTx = await signer.signTransaction(unsignedApproveTx);
|
||||
const txResponse = await provider.sendTransaction(signedTx);
|
||||
options?.logger?.(`${issue.asset.name} approve transaction sent ${txResponse.hash}. Waiting for confirmation...`);
|
||||
await txResponse.wait();
|
||||
options?.logger?.(`${issue.asset.name} approve transaction confirmed.`);
|
||||
};
|
||||
await issue.approves?.reduce(async (promise, item) => {
|
||||
await promise;
|
||||
return approve(item);
|
||||
}, Promise.resolve());
|
||||
};
|
||||
|
||||
if (swapInfo.isThroughPoolOptimal) {
|
||||
options?.logger?.('Swap through pool');
|
||||
const pathAddresses = swapInfo.path.map((name) => {
|
||||
@@ -252,25 +218,7 @@ export default async function swapMarket({
|
||||
});
|
||||
}
|
||||
|
||||
options?.logger?.(`Balance requirements: ${balanceGuard.requirements
|
||||
.map((requirement) => `${requirement.amount} ${requirement.asset.name} `
|
||||
+ `for '${requirement.reason}' `
|
||||
+ `from [${requirement.sources.join(' + ')}]`)
|
||||
.join(', ')}`);
|
||||
|
||||
const balanceIssues = await balanceGuard.check();
|
||||
const autofixableBalanceIssues = balanceIssues.filter((balanceIssue) => balanceIssue.approves);
|
||||
const allBalanceIssuesIsAutofixable = autofixableBalanceIssues.length === balanceIssues.length;
|
||||
if (!allBalanceIssuesIsAutofixable) options?.logger?.('Some balance issues is not autofixable');
|
||||
|
||||
if (!allBalanceIssuesIsAutofixable || (options !== undefined && !options.autoApprove)) {
|
||||
throw new Error(`Balance issues: ${balanceIssues.map((issue, i) => `${i + 1}. ${issue.message}`).join('\n')}`);
|
||||
}
|
||||
|
||||
await autofixableBalanceIssues.reduce(async (promise, item) => {
|
||||
await promise;
|
||||
return fixBalanceIssue(item);
|
||||
}, Promise.resolve());
|
||||
await balanceGuard.check(options?.autoApprove);
|
||||
|
||||
const nonce = await provider.getTransactionCount(walletAddress, 'pending');
|
||||
unsignedSwapThroughOrionPoolTx.nonce = nonce;
|
||||
@@ -374,25 +322,7 @@ export default async function swapMarket({
|
||||
sources: getAvailableSources('orion_fee', feeAssetAddress, 'aggregator'),
|
||||
});
|
||||
|
||||
options?.logger?.(`Balance requirements: ${balanceGuard.requirements
|
||||
.map((requirement) => `${requirement.amount} ${requirement.asset.name} `
|
||||
+ `for '${requirement.reason}' `
|
||||
+ `from [${requirement.sources.join(' + ')}]`)
|
||||
.join(', ')}`);
|
||||
|
||||
const balanceIssues = await balanceGuard.check();
|
||||
const autofixableBalanceIssues = balanceIssues.filter((balanceIssue) => balanceIssue.approves);
|
||||
const allBalanceIssuesIsAutofixable = autofixableBalanceIssues.length === balanceIssues.length;
|
||||
if (!allBalanceIssuesIsAutofixable) options?.logger?.('Some balance issues is not autofixable');
|
||||
|
||||
if (!allBalanceIssuesIsAutofixable || (options !== undefined && !options.autoApprove)) {
|
||||
throw new Error(`Balance issues: ${balanceIssues.map((issue, i) => `${i + 1}. ${issue.message}`).join('\n')}`);
|
||||
}
|
||||
|
||||
await autofixableBalanceIssues.reduce(async (promise, item) => {
|
||||
await promise;
|
||||
return fixBalanceIssue(item);
|
||||
}, Promise.resolve());
|
||||
await balanceGuard.check(options?.autoApprove);
|
||||
|
||||
const signedOrder = await crypt.signOrder(
|
||||
baseAssetAddress,
|
||||
@@ -2,10 +2,9 @@ import { ethers } from 'ethers';
|
||||
import { OrionAggregator } from '../services/OrionAggregator';
|
||||
import { OrionBlockchain } from '../services/OrionBlockchain';
|
||||
import { PriceFeed } from '../services/PriceFeed';
|
||||
import swapMarket, { SwapMarketParams } from './swapMarket';
|
||||
import { SupportedChainId } from '../types';
|
||||
import Exchange from './Exchange';
|
||||
|
||||
type PureSwapMarketParams= Omit<SwapMarketParams, 'orionUnit'>
|
||||
export default class OrionUnit {
|
||||
public readonly env: string;
|
||||
|
||||
@@ -19,6 +18,8 @@ export default class OrionUnit {
|
||||
|
||||
public readonly priceFeed: PriceFeed;
|
||||
|
||||
public readonly exchange: Exchange;
|
||||
|
||||
public readonly apiUrl: string;
|
||||
|
||||
constructor(
|
||||
@@ -35,12 +36,6 @@ export default class OrionUnit {
|
||||
this.orionBlockchain = new OrionBlockchain(apiUrl, chainId);
|
||||
this.orionAggregator = new OrionAggregator(apiUrl, chainId);
|
||||
this.priceFeed = new PriceFeed(apiUrl);
|
||||
}
|
||||
|
||||
public swapMarket(params: PureSwapMarketParams) {
|
||||
return swapMarket({
|
||||
...params,
|
||||
orionUnit: this,
|
||||
});
|
||||
this.exchange = new Exchange(this);
|
||||
}
|
||||
}
|
||||
|
||||
4
src/utils/arrayEquals.ts
Normal file
4
src/utils/arrayEquals.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
const arrayEquals = (a: unknown[], b: unknown[]) => a.length === b.length
|
||||
&& a.every((value, index) => value === b[index]);
|
||||
|
||||
export default arrayEquals;
|
||||
Reference in New Issue
Block a user