namillum
Version:
Bubble Protocol SDK
290 lines (255 loc) • 9.82 kB
text/typescript
import { toBech32Address, fromBech32Address } from '@zilliqa-js/crypto';
import { Explorer, NetworkURL, Network, TransactionType, AccountType, Constants, OperationStatus } from './enum';
import Alert from '../components/alert';
import { ZilSigner } from '../zilliqa-signer';
import { getBlockchainExplorer } from './config-json-helper';
import { SsnStats } from './interface';
import { ZilSdk } from '../zilliqa-api';
const { BN, validation, units } = require('@zilliqa-js/util');
const BigNumber = require('bignumber.js');
// config.js from public folder
const blockchain_explorer_config = getBlockchainExplorer();
export const bech32ToChecksum = (address: string) => {
if (validation.isAddress(address)) {
// convert to checksum format
return fromBech32Address(toBech32Address(address))
}
if (validation.isBech32(address)) {
return fromBech32Address(address);
}
return address;
};
export const convertBase16ToBech32 = (address: string) => {
if (validation.isAddress(address)) {
return toBech32Address(address);
}
return address;
}
export const convertZilToQa = (amount: string) => {
return units.toQa(amount, units.Units.Zil);
};
// convert from sdk "float" representation to percentage
// sdk "float" is represented in 1e7 format
export const convertToProperCommRate = (rate: string) => {
if (!rate) {
return 0;
}
let commRate = new BigNumber(rate).dividedBy(10**7);
return commRate;
};
// compute the total stake amount using the list of ssnlist stake
// used for ssn-table because if we depend on the totalstakeamount fetch from the saga
// the update would delay, causing a issue where totalstakeamount is 0
export const computeTotalStakeAmt = (ssnlist: SsnStats[]) => {
let totalStakeAmt = new BigNumber(0);
for (const ssnstats of ssnlist) {
totalStakeAmt = totalStakeAmt.plus(new BigNumber(ssnstats.stakeAmt));
}
return totalStakeAmt;
}
// compute the stake amount as a percentage of total stake amount
// returns a BigNumber
export const computeStakeAmtPercent = (inputStake: string, totalStake: string) => {
if (!inputStake || !totalStake || totalStake === '0') {
return 0;
}
const inputStakeBN = new BigNumber(inputStake);
const totalStakeBN = new BigNumber(totalStake);
const stakePercentage = inputStakeBN.dividedBy(totalStakeBN).times(100);
return stakePercentage;
}
// checks if input contains only postive numbers
// returns true if so, otherwise returns false
export const isDigits = (input: string) => {
return /^\d+$/.test(input);
}
export const computeGasFees = (gasPrice: string, gasLimit: string) => {
// console.log("compute gas fees util: ", gasPrice);
// console.log("compute gas limit util: ", gasLimit);
return new BN(gasPrice.toString()).mul(new BN(gasLimit.toString()));
}
// convert commission rate from percentage to contract comm rate
// userInputRate is a float
// returns a big number
export const percentToContractCommRate = (userInputRate: string) => {
if (!userInputRate) {
return 0;
}
let scillaFloat = new BigNumber(userInputRate).times(10**7);
return scillaFloat;
};
// convert balances and other numbers into string
// with commas as thousand separators and decimals places
export const convertQaToCommaStr = (inputVal: string) => {
let zil = units.fromQa(new BN(inputVal), units.Units.Zil);
let zilProperDecimalStr = new BigNumber(zil).toFixed(3);
const splitAmt = zilProperDecimalStr.split('.');
// add comma separator to front part
let frontAmt = splitAmt[0].replace(/(.)(?=(\d{3})+$)/g,'$1,')
let backAmt = splitAmt[1];
return frontAmt + "." + backAmt;
}
// show the full zil amount
export const convertQaToZilFull = (amount: string) => {
let result = "0.00";
try {
result = units.fromQa(new BN(amount), units.Units.Zil);
} catch (err) {
result = "0.00";
}
return result;
}
// convert gzil amount in 15 decimal places to a comma represented string
export const convertGzilToCommaStr = (inputVal: string) => {
const gzil = new BigNumber(inputVal).shiftedBy(-15).toFixed(3);
const splitAmt = gzil.split('.');
// add comma separator to front part
let frontAmt = splitAmt[0].replace(/(.)(?=(\d{3})+$)/g,'$1,')
let backAmt = splitAmt[1];
return frontAmt + "." + backAmt;
}
export const convertNetworkUrlToLabel = (url: string) => {
let label = '';
switch (url) {
case NetworkURL.MAINNET:
label = Network.MAINNET;
break;
case NetworkURL.TESTNET:
label = Network.TESTNET;
break;
default:
label = Network.TESTNET;
break;
}
return label;
}
export const getTxnLink = (txnId: string, networkURL: string) => {
let link = "";
if (blockchain_explorer_config === Explorer.VIEWBLOCK) {
if (networkURL === NetworkURL.MAINNET) {
link = "https://viewblock.io/zilliqa/tx/0x" + txnId
} else {
link = "https://viewblock.io/zilliqa/tx/0x" + txnId + "?network=testnet"
}
} else {
// devex
link = "https://devex.zilliqa.com/tx/0x" + txnId + "?network=" + networkURL;
}
return link;
}
export const getAddressLink = (address: string, networkURL: string) => {
let link = "";
if (blockchain_explorer_config === Explorer.VIEWBLOCK) {
if (networkURL === NetworkURL.MAINNET) {
link = "https://viewblock.io/zilliqa/address/" + address
} else {
link = "https://viewblock.io/zilliqa/address/" + address + "?network=testnet"
}
} else {
// devex
link = "https://devex.zilliqa.com/address/" + address + "?network=" + networkURL;
}
return link;
}
export const getZillionExplorerLink = (address: string) => {
let domain = window.location.origin;
return domain + "/address/" + address;
}
// returns the zil address with '...'
export const getTruncatedAddress = (address: string) => {
if (!address) {
return "";
}
const addressLen = address.length;
const front = address.substring(0, 6);
const end = address.substring(addressLen-4);
return front.concat("...", end);
}
export const getTransactionText = (txnType: TransactionType) => {
switch (txnType) {
case TransactionType.CLAIM_REWARDS:
return "Claim Rewards";
case TransactionType.COMPLETE_STAKE_WITHDRAW:
return "Complete Stake Withdrawal";
case TransactionType.DELEGATE_STAKE:
return "Delegate Stake";
case TransactionType.INITIATE_STAKE_WITHDRAW:
return "Initiate Stake Withdrawal";
case TransactionType.TRANSFER_STAKE:
return "Transfer Stake";
case TransactionType.UPDATE_COMM_RATE:
return "Update Commission Rate";
case TransactionType.UPDATE_RECV_ADDR:
return "Update Receiving Address";
case TransactionType.WITHDRAW_COMM:
return "Withdraw Commission";
case TransactionType.REQUEST_DELEG_SWAP:
return "Request Delegator Swap";
case TransactionType.REVOKE_DELEG_SWAP:
return "Revoke Delegator Swap";
case TransactionType.CONFIRM_DELEG_SWAP:
return "Accept Swap Request";
case TransactionType.REJECT_DELEG_SWAP:
return "Reject Swap Request";
default:
return "Error";
}
}
// show information to prompt users
// for used during contract calls
export const showWalletsPrompt = (accountType: string) => {
if (accountType === AccountType.LEDGER) {
Alert('info', "Info", "Accessing the ledger device for keys.");
Alert('info', "Info", "Please follow the instructions on the device.");
return;
}
if (accountType === AccountType.ZILPAY) {
Alert('info', "Info", "Please follow the instructions on ZilPay.");
return;
}
}
// check if wallet has sufficient balance to pay for gas fees
// for used during contract calls
// @param address wallet address in base16
// returns true if balance is greater than or equal to gas fees; otherwise returns false
export const validateBalance = async (address: string) => {
// fetch a new balance in case, user's balance is not updated on frontend
const balance = await ZilSdk.getBalance(address);
const gasFees = ZilSigner.getGasFees();
// console.log("user bal: ", balance);
// console.log("gasFees: ", gasFees.toString());
if (new BN(balance.toString()).gte(new BN(gasFees.toString()))) {
return true;
}
return false;
}
export const calculateBlockRewardCountdown = (blockNum: number, currentNetworkURL: string) => {
let sampleRewardBlockNum = 0;
let rewardBlockCount = 0;
if (currentNetworkURL === NetworkURL.MAINNET) {
sampleRewardBlockNum = Constants.SAMPLE_REWARD_BLOCK_MAINNET;
rewardBlockCount = Constants.REWARD_BLOCK_COUNT_MAINNET;
} else {
sampleRewardBlockNum = Constants.SAMPLE_REWARD_BLOCK_TESTNET;
rewardBlockCount = Constants.REWARD_BLOCK_COUNT_TESTNET;
}
const blockDiff = blockNum - sampleRewardBlockNum;
const blockTraverse = blockDiff % rewardBlockCount;
const blockCountdown = rewardBlockCount - blockTraverse;
return blockCountdown;
}
/**
* used by saga to check if response from fetching a contract state has any errors
* @param obj the contract result
* @returns true if response has no errors, false otherwise
*/
export const isRespOk = (obj: any): boolean => {
if (
obj !== undefined &&
obj !== null &&
obj !== OperationStatus.ERROR
) {
return true;
}
return false;
}