UNPKG

@qso-soft/shared

Version:

Shared library for QSO-soft

118 lines 4.61 kB
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