mirror of
https://github.com/orionprotocol/sdk.git
synced 2026-03-14 06:02:36 +03:00
135 lines
4.2 KiB
TypeScript
135 lines
4.2 KiB
TypeScript
import { BigNumber } from 'bignumber.js';
|
|
import { ethers } from 'ethers';
|
|
import { Exchange__factory } from '@orionprotocol/contracts/lib/ethers-v5/index.js';
|
|
import getBalances from '../../utils/getBalances.js';
|
|
import BalanceGuard from '../../BalanceGuard.js';
|
|
import type Unit from '../index.js';
|
|
import {
|
|
DEPOSIT_ERC20_GAS_LIMIT, DEPOSIT_ETH_GAS_LIMIT, INTERNAL_PROTOCOL_PRECISION, NATIVE_CURRENCY_PRECISION,
|
|
} from '../../constants/index.js';
|
|
import { denormalizeNumber, normalizeNumber } from '../../utils/index.js';
|
|
import getNativeCryptocurrencyName from '../../utils/getNativeCryptocurrencyName.js';
|
|
import { simpleFetch } from 'simple-typed-fetch';
|
|
|
|
export type DepositParams = {
|
|
asset: string
|
|
amount: BigNumber.Value
|
|
signer: ethers.Signer
|
|
unit: Unit
|
|
}
|
|
|
|
export default async function deposit({
|
|
asset,
|
|
amount,
|
|
signer,
|
|
unit,
|
|
}: DepositParams) {
|
|
if (asset === '') throw new Error('Asset can not be empty');
|
|
|
|
const amountBN = new BigNumber(amount);
|
|
if (amountBN.isNaN()) throw new Error(`Amount '${amountBN.toString()}' is not a number`);
|
|
if (amountBN.lte(0)) throw new Error(`Amount '${amountBN.toString()}' should be greater than 0`);
|
|
|
|
const walletAddress = await signer.getAddress();
|
|
|
|
const {
|
|
blockchainService, aggregator, provider, chainId,
|
|
} = unit;
|
|
const {
|
|
exchangeContractAddress,
|
|
assetToAddress,
|
|
} = await simpleFetch(blockchainService.getInfo)();
|
|
|
|
const nativeCryptocurrency = getNativeCryptocurrencyName(assetToAddress);
|
|
|
|
const exchangeContract = Exchange__factory.connect(exchangeContractAddress, provider);
|
|
const gasPriceWei = await simpleFetch(blockchainService.getGasPriceWei)();
|
|
|
|
const assetAddress = assetToAddress[asset];
|
|
if (assetAddress === undefined) throw new Error(`Asset '${asset}' not found`);
|
|
|
|
const balances = await getBalances(
|
|
{
|
|
[asset]: assetAddress,
|
|
[nativeCryptocurrency]: ethers.constants.AddressZero,
|
|
},
|
|
aggregator,
|
|
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: amountBN.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_PROTOCOL_PRECISION, BigNumber.ROUND_CEIL),
|
|
);
|
|
unsignedTx.gasLimit = ethers.BigNumber.from(DEPOSIT_ERC20_GAS_LIMIT);
|
|
}
|
|
|
|
const transactionCost = ethers.BigNumber.from(unsignedTx.gasLimit).mul(gasPriceWei);
|
|
const denormalizedTransactionCost = 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, 10);
|
|
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);
|
|
try {
|
|
const txResponse = await provider.sendTransaction(signedTx);
|
|
console.log(`Deposit tx sent: ${txResponse.hash}. Waiting for confirmation...`);
|
|
const txReceipt = await txResponse.wait();
|
|
if (txReceipt.status !== undefined) {
|
|
console.log('Deposit tx confirmed');
|
|
} else {
|
|
console.log('Deposit tx failed');
|
|
}
|
|
} catch (e) {
|
|
if (!(e instanceof Error)) throw new Error('e is not an Error');
|
|
console.error(`Deposit tx failed: ${e.message}`, {
|
|
unsignedTx,
|
|
});
|
|
}
|
|
}
|