@q-dev/q-ts-gdk-sdk
Version:
Typescript Library to interact with GDK Contracts
116 lines (91 loc) • 3.38 kB
text/typescript
import HDWalletProvider from "@truffle/hdwallet-provider";
import Web3 from "web3";
import { AddressWithBalance } from "../types";
import { version } from "./version.json";
import { QSdkProvider } from "./web3-factory";
export { Web3 };
export interface ConnectionInfo {
networkId: number;
nodeInfo: string;
rpcUrl: string;
}
export class Web3Adapter {
constructor(public readonly web3: Web3) {}
public readonly ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
public readonly SDK_VERSION: string = version;
toWei = this.web3.utils.toWei;
fromWei = this.web3.utils.fromWei;
toBN = this.web3.utils.toBN;
startProviderEngine(): boolean {
if (!(this.web3.currentProvider instanceof HDWalletProvider)) return false;
this.web3.currentProvider.engine.start();
return true;
}
stopProviderEngine(): boolean {
if (!(this.web3.currentProvider instanceof HDWalletProvider)) return false;
this.web3.currentProvider.engine.stop();
return true;
}
getRpcUrl(): string {
const provider = this.web3.currentProvider;
if (provider instanceof QSdkProvider) {
return provider.hdWalletConfig.providerOrUrl as string;
}
const guessRpc = provider["host"] || provider["_host"];
return guessRpc || "n.a.";
}
async getConnectionInfo(): Promise<ConnectionInfo> {
const networkId = await this.web3.eth.getChainId();
const nodeInfo = await this.web3.eth.getNodeInfo();
const rpcUrl = this.getRpcUrl();
return { networkId, nodeInfo, rpcUrl };
}
async getDefaultAccount(): Promise<string> {
const accounts = await this.getAccounts();
return accounts[0];
}
async getAccounts(): Promise<string[]> {
return this.web3.eth.getAccounts();
}
async getTotalQInExistence(): Promise<number> {
const initialQ = 1e10; // 10 billion Q
const blockSubsidy = 15; // 15 Q per Block
const blockNumber = await this.web3.eth.getBlockNumber();
return initialQ + blockNumber * blockSubsidy;
}
async getBalance(address: string, convertToQ = true): Promise<string> {
const balance = await this.web3.eth.getBalance(address);
if (!convertToQ) return balance;
return this.web3.utils.fromWei(balance);
}
async getBalances(addresses: string[], convertToQ = true): Promise<AddressWithBalance[]> {
const getBalanceOperation = async (address: string): Promise<AddressWithBalance> => {
const balance = await this.getBalance(address, convertToQ);
return {
address,
balance,
};
};
return this.forEachAddress(addresses, getBalanceOperation);
}
async forEachAddress<T>(addresses: string[], operation: (address: string, i?: number) => Promise<T>): Promise<T[]> {
const values = [];
const errors = [];
const robustOperation = async (address: string, i: number): Promise<void> => {
try {
const value = await operation(address, i);
values[i] = value;
} catch (error) {
const reason = error.message ?? error.toString();
errors.push({ address, reason });
}
};
const promises = addresses.map(robustOperation);
await Promise.all(promises);
if (errors.length > 0) {
const msg = errors.map((e) => `operation rejected for address ${e.address}: ${e.reason}`).join("\n");
throw new Error(msg);
}
return values;
}
}