@qso-soft/shared
Version:
Shared library for QSO-soft
118 lines • 4.61 kB
JavaScript
import { createPublicClient, createWalletClient, fallback, formatEther, http, } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { convertPrivateKey, decimalToInt, getAllRPCs, getExplorerLinkByNetwork, getFeePerGasOptions, getRpc, } from '../helpers';
import { defaultTokenAbi } from './abi';
const TRANSPORT_RETRY_CONFIG = {};
const WAIT_TX_CONFIG = {
pollingInterval: 30000,
timeout: 90000,
};
export class DefaultClient {
constructor(privateKey, chainData, logger, network) {
this.logger = logger;
this.chainData = chainData;
this.privateKey = convertPrivateKey(privateKey);
this.network = network;
this.explorerLink = getExplorerLinkByNetwork(network);
this.rpcs = getAllRPCs(network);
this.currentRpc = getRpc(network);
this.walletClient = this.getWalletClient();
this.publicClient = this.getPublicClient();
this.walletAddress = this.walletClient.account.address;
}
getTransport(rpc, index = 0) {
return http(rpc, {
batch: true,
fetchOptions: {},
key: `${this.chainData.name}-${index}`,
...TRANSPORT_RETRY_CONFIG,
});
}
getFallbackTransport() {
const currentRpcs = this.rpcs?.sort((prev, cur) => {
if (prev === this.currentRpc) {
return -1;
}
if (cur === this.currentRpc) {
return 1;
}
return 0;
}) || [];
const transports = currentRpcs.map((rpc, index) => this.getTransport(rpc, index));
return fallback(transports, TRANSPORT_RETRY_CONFIG);
}
getPublicClient() {
return createPublicClient({ chain: this.chainData, transport: this.getTransport(this.currentRpc) });
}
getWalletClient() {
return createWalletClient({
chain: this.chainData,
account: privateKeyToAccount(this.privateKey),
transport: this.getTransport(this.currentRpc),
});
}
async getNativeBalance() {
const weiBalance = await this.publicClient.getBalance({ address: this.walletAddress });
const intBalance = Number(formatEther(weiBalance));
const decimals = this.chainData.nativeCurrency.decimals;
return { wei: weiBalance, int: intBalance, decimals };
}
async getBalanceByContract(contractInfo) {
const weiBalance = (await this.publicClient.readContract({
address: contractInfo.address,
abi: contractInfo.abi,
functionName: 'balanceOf',
args: [this.walletAddress],
}));
const decimals = (await this.publicClient.readContract({
address: contractInfo.address,
abi: contractInfo.abi,
functionName: 'decimals',
}));
const intBalance = decimalToInt({ amount: weiBalance, decimals });
return { wei: weiBalance, int: intBalance, decimals };
}
async getSymbolByContract(contractInfo) {
return (await this.publicClient.readContract({
address: contractInfo.address,
abi: contractInfo.abi,
functionName: 'symbol',
}));
}
async approve(tokenContract, projectContract, amount, gweiRange) {
const allowanceAmount = await this.publicClient.readContract({
address: tokenContract,
abi: defaultTokenAbi,
functionName: 'allowance',
args: [this.walletAddress, projectContract],
});
if (allowanceAmount < amount) {
this.logger.info('Starting an approve transaction');
const txHash = await this.walletClient.writeContract({
address: tokenContract,
abi: defaultTokenAbi,
functionName: 'approve',
args: [projectContract, amount],
...getFeePerGasOptions(gweiRange),
});
await this.waitTxReceipt(txHash);
if (txHash) {
this.logger.success('Approve transaction was confirmed');
}
}
else {
this.logger.info(`Contract was already approved for ${allowanceAmount}`);
}
}
async waitTxReceipt(txHash) {
const txReceipt = await this.publicClient.waitForTransactionReceipt({
hash: txHash,
...WAIT_TX_CONFIG,
});
if (!txReceipt.transactionHash) {
throw new Error('transactionHash was not found');
}
return txReceipt;
}
}
//# sourceMappingURL=default-client.js.map