Display Functions
Vault Status
getVaultStatus
const getVaultStatus = async ({ vaultKey, chainId }: VaultStatusParams) => {
const normalizedChainId =
typeof chainId === 'string' ? Number(chainId) : chainId;
const vault = await getVaultByKey(vaultKey);
if (!vault) {
throw new Error(`Vault not found: ${vaultKey}`);
}
const tellerAddress = vault.contracts.teller;
const accountantAddress = vault.contracts.accountant;
const [tellerStatus, accountantStatus] = await getPausedStates({
accountantAddress,
tellerAddress,
chainId: normalizedChainId,
});
if (tellerStatus.status === 'failure') {
throw new Error(tellerStatus.error.message);
}
if (accountantStatus.status === 'failure') {
throw new Error(accountantStatus.error.message);
}
if (tellerStatus.result === true || accountantStatus.result[7] === true) {
return {
isPaused: true,
};
}
return {
isPaused: false,
};
};
Approvals
isDepositSpendApproved
const isDepositSpendApproved = async ({
vaultKey,
sourceChainId,
depositTokenSymbol,
userAddress,
}: {
vaultKey: VaultKey;
sourceChainId: number;
userAddress: Address;
depositTokenSymbol: string;
}) => {
const {
data: vault,
error: vaultError,
success: vaultSuccess,
} = await tryCatch(getVaultByKey(vaultKey));
if (!vaultSuccess) {
throw new Error(`Vault not found for ${vaultKey}: ${vaultError.message}`);
}
if (!vault.contracts) {
throw new Error(`Contracts not found: ${vaultKey}`);
}
const normalizedSourceChainId =
typeof sourceChainId === 'string' ? Number(sourceChainId) : sourceChainId;
const {
data: depositAssetAddress,
error: depositAssetAddressError,
success: depositAssetAddressSuccess,
} = await tryCatch(
getTokenAddress(normalizedSourceChainId, depositTokenSymbol)
);
if (!depositAssetAddressSuccess) {
throw new Error(
`Deposit asset address not found: ${depositAssetAddressError.message}`
);
}
const { deposit } = vault;
const { sourceChains } = deposit;
const sourceChain = sourceChains[sourceChainId];
if (!sourceChain) {
throw new Error(`Source chain not found: ${sourceChainId}`);
}
const [allowance, decimals] = await getErc20AllowanceWithDecimals({
chainId: sourceChainId,
tokenAddress: depositAssetAddress,
userAddress: userAddress,
spenderAddress: vault.contracts.boringVault,
});
if (allowance.status === 'failure' || decimals.status === 'failure') {
return {
isApproved: false,
allowance: '0',
allowanceAsBigInt: '0',
decimals: '0',
error: allowance.error || decimals.error,
};
}
return {
isApproved: allowance.result > 0n,
allowance: formatUnits(allowance.result, decimals.result),
allowanceAsBigInt: allowance.result.toString(),
decimals: decimals.result,
error: null,
};
};
isWithdrawalSpendApproved
const isWithdrawalSpendApproved = async ({
vaultKey,
destinationChainId,
userAddress,
error,
}: {
vaultKey: VaultKey;
destinationChainId: number;
userAddress: Address;
error: string;
}) => {
const {
data: vault,
error: vaultError,
success: vaultSuccess,
} = await tryCatch(getVaultByKey(vaultKey));
if (!vaultSuccess) {
throw new Error(`Vault not found for ${vaultKey}: ${vaultError.message}`);
}
if (!vault.contracts) {
throw new Error(`Contracts not found for ${vaultKey}`);
}
const boringVaultAddress = vault.contracts.boringVault;
const [allowance, decimals] = await getErc20AllowanceWithDecimals({
chainId: destinationChainId,
tokenAddress: boringVaultAddress,
userAddress: userAddress,
spenderAddress: ATOMIC_QUEUE_CONTRACT_ADDRESS,
});
if (allowance.status === 'failure' || decimals.status === 'failure') {
return {
isApproved: false,
allowance: '0',
allowanceAsBigInt: '0',
decimals: '0',
error: allowance.error || decimals.error,
};
}
return {
isApproved: allowance.result > 0n,
allowance: formatUnits(allowance.result, decimals.result),
allowanceAsBigInt: allowance.result.toString(),
decimals: decimals.result,
error: null,
};
};
Exchange Rates
getDepositExchangeRate
interface GetDepositExchangeRateParams {
vaultKey: VaultKey;
sourceChainId: number | string;
depositTokenSymbol: string;
minimumFractionDigits?: number;
maximumFractionDigits?: number;
}
const getDepositExchangeRate = async ({
vaultKey,
sourceChainId,
depositTokenSymbol,
minimumFractionDigits,
maximumFractionDigits = 3,
}: GetDepositExchangeRateParams) => {
const vault = await getVaultByKey(vaultKey);
const chainId =
typeof sourceChainId === 'string' ? Number(sourceChainId) : sourceChainId;
const tokenAddress = await getTokenAddress(chainId, depositTokenSymbol);
if (!tokenAddress || tokenAddress === null) {
return;
}
const rateAndDecimalsResults = await getRateInQuoteWithAssetDecimals({
assetAddress: tokenAddress,
accountantAddress: vault.contracts.accountant,
chainId: sourceChainId,
});
const [decimals, rate] = rateAndDecimalsResults;
if (rate.status === 'failure') {
return new Error(rate.error.message);
}
if (decimals.status === 'failure') {
return new Error(decimals.error.message);
}
const depositExchangeRate = bigIntToNumberAsString(rate.result, {
decimals: decimals.result,
minimumFractionDigits,
maximumFractionDigits,
});
return depositExchangeRate;
};
getWithdrawExchangeRate
interface GetWithdrawExchangeRateParams {
vaultKey: VaultKey;
sourceChainId: number | string;
wantTokenSymbol: string;
minimumFractionDigits?: number;
maximumFractionDigits?: number;
}
const getWithdrawExchangeRate = async ({
vaultKey,
sourceChainId,
wantTokenSymbol,
minimumFractionDigits,
maximumFractionDigits = 3,
}: GetWithdrawExchangeRateParams) => {
const vault = await getVaultByKey(vaultKey);
const chainId =
typeof sourceChainId === 'string' ? Number(sourceChainId) : sourceChainId;
const tokenAddress = await getTokenAddress(chainId, wantTokenSymbol);
if (!tokenAddress || tokenAddress === null) {
return;
}
const rateAndDecimalsResults = await getRateInQuoteWithAssetDecimals({
assetAddress: tokenAddress,
accountantAddress: vault.contracts.accountant,
chainId: sourceChainId,
});
const [decimals, rate] = rateAndDecimalsResults;
if (rate.status === 'failure') {
return new Error(rate.error.message);
}
if (decimals.status === 'failure') {
return new Error(decimals.error.message);
}
const withdrawExchangeRate = bigIntToNumberAsString(rate.result, {
decimals: decimals.result,
minimumFractionDigits,
maximumFractionDigits,
});
return withdrawExchangeRate;
};
Bridge
getBridgeFee
interface GetPreviewFeeParams {
vaultKey: VaultKey;
bridgeAmount: bigint;
sourceChainId: number | string;
destinationChainId: number | string;
userAddress: Address;
nativeTokenForBridgeFee?: Address;
}
const getBridgeFee = async ({
vaultKey,
bridgeAmount,
sourceChainId,
destinationChainId,
userAddress,
nativeTokenForBridgeFee = NATIVE_TOKEN_FOR_BRIDGE_FEE,
}: GetPreviewFeeParams) => {
const vault = await getVaultByKey(vaultKey);
if (!vault) {
throw new Error(`Invalid vault key: ${vaultKey}`);
}
if (!vault.contracts) {
throw new Error(`Contracts not configured for vault ${vaultKey}`);
}
if (!vault.contracts.boringVault) {
throw new Error(
`BoringVault contract not configured for vault ${vaultKey}`
);
}
if (!vault.contracts.accountant) {
throw new Error(`Accountant contract not configured for vault ${vaultKey}`);
}
if (!vault.contracts.teller) {
throw new Error(`Teller contract not configured for vault ${vaultKey}`);
}
const sourceChainIdString = sourceChainId.toString();
const sourceChain = vault.withdraw.sourceChains[sourceChainIdString];
if (!sourceChain) {
throw new Error(`Source chain not configured for vault ${vaultKey}`);
}
const destinationChain = sourceChain.destinationChains[destinationChainId];
if (!destinationChain) {
throw new Error(`Destination chain not configured for vault ${vaultKey}`);
}
const bridgeChainIdentifier = destinationChain.bridge.chainIdentifier;
const bridgeContractArg = prepareBridgeContractArg({
bridgeChainIdentifier,
userAddress,
nativeTokenForBridgeFee,
});
const previewFee = await getPreviewFee({
shareAmount: bridgeAmount,
bridgeData: bridgeContractArg,
contractAddress: vault.contracts.teller,
chainId: sourceChainId,
});
// TODO: use native currency from chains object returned from API
return previewFee;
};
Last updated