mirror of
https://github.com/orionprotocol/sdk.git
synced 2026-03-14 22:22:35 +03:00
200 lines
6.9 KiB
TypeScript
200 lines
6.9 KiB
TypeScript
import { ERC20__factory, Exchange__factory, type Exchange } from "@orionprotocol/contracts/lib/ethers-v6/index.js";
|
|
import type { BigNumber } from "bignumber.js";
|
|
import { ZeroAddress, ethers } from "ethers";
|
|
import { INTERNAL_PROTOCOL_PRECISION, NATIVE_CURRENCY_PRECISION } from "../constants/index.js";
|
|
import type { Aggregator } from "../services/Aggregator/index.js";
|
|
import denormalizeNumber from "./denormalizeNumber.js";
|
|
import type { AddressLike } from "ethers";
|
|
import { addressLikeToString } from "./addressLikeToString.js";
|
|
|
|
export default async function getBalance(
|
|
aggregator: Aggregator,
|
|
assetName: string,
|
|
assetAddress: string,
|
|
walletAddress: string,
|
|
exchangeContract: Exchange,
|
|
provider: ethers.Provider
|
|
) {
|
|
const assetIsNativeCryptocurrency = assetAddress === ethers.ZeroAddress;
|
|
|
|
let assetWalletBalance: bigint | undefined;
|
|
|
|
let denormalizedAssetInWalletBalance: BigNumber | undefined;
|
|
|
|
if (!assetIsNativeCryptocurrency) {
|
|
const assetContract = ERC20__factory.connect(assetAddress, provider);
|
|
const assetDecimals = await assetContract.decimals();
|
|
assetWalletBalance = await assetContract.balanceOf(walletAddress);
|
|
|
|
denormalizedAssetInWalletBalance = denormalizeNumber(assetWalletBalance, assetDecimals);
|
|
} else {
|
|
assetWalletBalance = await provider.getBalance(walletAddress);
|
|
denormalizedAssetInWalletBalance = denormalizeNumber(assetWalletBalance, BigInt(NATIVE_CURRENCY_PRECISION));
|
|
}
|
|
const assetContractBalance = await exchangeContract.getBalance(assetAddress, walletAddress);
|
|
const denormalizedAssetInContractBalance = denormalizeNumber(
|
|
assetContractBalance,
|
|
BigInt(INTERNAL_PROTOCOL_PRECISION)
|
|
);
|
|
const denormalizedAssetLockedBalanceResult = await aggregator.getLockedBalance(walletAddress, assetName);
|
|
if (denormalizedAssetLockedBalanceResult.isErr()) {
|
|
throw new Error(denormalizedAssetLockedBalanceResult.error.message);
|
|
}
|
|
|
|
return {
|
|
exchange: denormalizedAssetInContractBalance.minus(denormalizedAssetLockedBalanceResult.value.data[assetName] ?? 0),
|
|
wallet: denormalizedAssetInWalletBalance,
|
|
};
|
|
}
|
|
|
|
async function getExchangeBalanceERC20(
|
|
tokenAddress: AddressLike,
|
|
walletAddress: AddressLike,
|
|
exchangeAddress: AddressLike,
|
|
provider: ethers.Provider,
|
|
convertToNativeDecimals = true
|
|
) {
|
|
walletAddress = await addressLikeToString(walletAddress);
|
|
exchangeAddress = await addressLikeToString(exchangeAddress);
|
|
tokenAddress = await addressLikeToString(tokenAddress);
|
|
|
|
const exchange = <Exchange>Exchange__factory.connect(exchangeAddress, provider);
|
|
const exchangeBalance = await exchange.getBalance(tokenAddress, walletAddress);
|
|
|
|
if (convertToNativeDecimals) {
|
|
const tokenContract = ERC20__factory.connect(tokenAddress, provider);
|
|
const decimals = await tokenContract.decimals();
|
|
const convertedExchangeBalance = (exchangeBalance * BigInt(10) ** decimals) / BigInt(10) ** 8n;
|
|
return convertedExchangeBalance;
|
|
}
|
|
|
|
return exchangeBalance;
|
|
}
|
|
|
|
async function getExchangeBalanceNative(
|
|
walletAddress: AddressLike,
|
|
exchangeAddress: AddressLike,
|
|
provider: ethers.Provider,
|
|
convertToNativeDecimals = true
|
|
) {
|
|
walletAddress = await addressLikeToString(walletAddress);
|
|
exchangeAddress = await addressLikeToString(exchangeAddress);
|
|
const exchange = <Exchange>Exchange__factory.connect(exchangeAddress, provider);
|
|
const exchangeBalance = await exchange.getBalance(ZeroAddress, walletAddress);
|
|
|
|
if (convertToNativeDecimals) {
|
|
const convertedExchangeBalance = (exchangeBalance * BigInt(10) ** 18n) / BigInt(10) ** 8n;
|
|
return convertedExchangeBalance;
|
|
}
|
|
|
|
return exchangeBalance;
|
|
}
|
|
|
|
export async function getExchangeBalance(
|
|
tokenAddress: AddressLike,
|
|
walletAddress: AddressLike,
|
|
exchangeAddress: AddressLike,
|
|
provider: ethers.Provider,
|
|
convertToNativeDecimals = true
|
|
) {
|
|
walletAddress = await addressLikeToString(walletAddress);
|
|
tokenAddress = await addressLikeToString(tokenAddress);
|
|
|
|
if (typeof tokenAddress === "string" && tokenAddress === ZeroAddress) {
|
|
return getExchangeBalanceNative(walletAddress, exchangeAddress, provider, convertToNativeDecimals);
|
|
} else {
|
|
return getExchangeBalanceERC20(tokenAddress, walletAddress, exchangeAddress, provider, convertToNativeDecimals);
|
|
}
|
|
}
|
|
|
|
export async function getExchangeAllowance(
|
|
tokenAddress: AddressLike,
|
|
walletAddress: AddressLike,
|
|
exchangeAddress: AddressLike,
|
|
provider: ethers.Provider
|
|
) {
|
|
if (typeof tokenAddress === "string" && tokenAddress === ZeroAddress) {
|
|
return 0n;
|
|
} else {
|
|
walletAddress = await addressLikeToString(walletAddress);
|
|
tokenAddress = await addressLikeToString(tokenAddress);
|
|
|
|
const tokenContract = ERC20__factory.connect(tokenAddress, provider);
|
|
let allowance = await tokenContract.allowance(walletAddress, exchangeAddress);
|
|
|
|
return allowance;
|
|
}
|
|
}
|
|
|
|
async function getWalletBalanceERC20(
|
|
tokenAddress: AddressLike,
|
|
walletAddress: AddressLike,
|
|
provider: ethers.Provider,
|
|
convertToExchangeDecimals = false
|
|
) {
|
|
walletAddress = await addressLikeToString(walletAddress);
|
|
tokenAddress = await addressLikeToString(tokenAddress);
|
|
|
|
const tokenContract = ERC20__factory.connect(tokenAddress, provider);
|
|
let walletBalance = await tokenContract.balanceOf(walletAddress);
|
|
|
|
if (convertToExchangeDecimals) {
|
|
const tokenContract = ERC20__factory.connect(tokenAddress, provider);
|
|
const decimals = await tokenContract.decimals();
|
|
const convertedNativeBalance = (walletBalance * BigInt(10) ** 8n) / BigInt(10) ** decimals;
|
|
return convertedNativeBalance;
|
|
}
|
|
return walletBalance;
|
|
}
|
|
|
|
async function getWalletBalanceNative(
|
|
walletAddress: AddressLike,
|
|
provider: ethers.Provider,
|
|
convertToExchangeDecimals = false
|
|
) {
|
|
walletAddress = await addressLikeToString(walletAddress);
|
|
const nativeBalance = await provider.getBalance(walletAddress);
|
|
|
|
if (convertToExchangeDecimals) {
|
|
const convertedNativeBalance = (nativeBalance * BigInt(10) ** 8n) / BigInt(10) ** 18n;
|
|
return convertedNativeBalance;
|
|
}
|
|
|
|
return nativeBalance;
|
|
}
|
|
|
|
export async function getWalletBalance(
|
|
tokenAddress: AddressLike,
|
|
walletAddress: AddressLike,
|
|
provider: ethers.Provider,
|
|
convertToExchangeDecimals = false
|
|
) {
|
|
if (typeof tokenAddress === "string" && tokenAddress === ZeroAddress) {
|
|
return getWalletBalanceNative(walletAddress, provider, convertToExchangeDecimals);
|
|
} else {
|
|
return getWalletBalanceERC20(tokenAddress, walletAddress, provider, convertToExchangeDecimals);
|
|
}
|
|
}
|
|
|
|
export async function getTotalBalance(
|
|
tokenAddress: AddressLike,
|
|
walletAddress: AddressLike,
|
|
exchangeAddress: AddressLike,
|
|
provider: ethers.Provider,
|
|
convertToNativeDecimals = true
|
|
) {
|
|
const walletBalance = await getWalletBalance(tokenAddress, walletAddress, provider, !convertToNativeDecimals);
|
|
const exchangeBalance = await getExchangeBalance(
|
|
tokenAddress,
|
|
walletAddress,
|
|
exchangeAddress,
|
|
provider,
|
|
convertToNativeDecimals
|
|
);
|
|
return {
|
|
walletBalance,
|
|
exchangeBalance,
|
|
totalBalance: walletBalance + exchangeBalance
|
|
}
|
|
}
|