mirror of
https://github.com/orionprotocol/sdk.git
synced 2026-03-27 16:17:47 +03:00
Semantics improvements
This commit is contained in:
125
src/Unit/Exchange/withdraw.ts
Normal file
125
src/Unit/Exchange/withdraw.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
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 {
|
||||
INTERNAL_PROTOCOL_PRECISION, NATIVE_CURRENCY_PRECISION, WITHDRAW_GAS_LIMIT,
|
||||
} 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 WithdrawParams = {
|
||||
asset: string
|
||||
amount: BigNumber.Value
|
||||
signer: ethers.Signer
|
||||
unit: Unit
|
||||
}
|
||||
|
||||
export default async function withdraw({
|
||||
asset,
|
||||
amount,
|
||||
signer,
|
||||
unit,
|
||||
}: WithdrawParams) {
|
||||
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(),
|
||||
sources: ['exchange'],
|
||||
});
|
||||
|
||||
const unsignedTx = await exchangeContract.populateTransaction.withdraw(
|
||||
assetAddress,
|
||||
normalizeNumber(amount, INTERNAL_PROTOCOL_PRECISION, BigNumber.ROUND_FLOOR),
|
||||
);
|
||||
unsignedTx.gasLimit = ethers.BigNumber.from(WITHDRAW_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);
|
||||
const txResponse = await provider.sendTransaction(signedTx);
|
||||
console.log(`Withdraw tx sent: ${txResponse.hash}. Waiting for confirmation...`);
|
||||
try {
|
||||
const txReceipt = await txResponse.wait();
|
||||
if (txReceipt.status !== undefined) {
|
||||
console.log('Withdraw tx confirmed');
|
||||
} else {
|
||||
console.log('Withdraw tx failed');
|
||||
}
|
||||
} catch (e) {
|
||||
if (!(e instanceof Error)) throw new Error('e is not an Error');
|
||||
console.error(`Deposit tx failed: ${e.message}`, {
|
||||
unsignedTx,
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user