@q-dev/q-ts-gdk-sdk
Version:
Typescript Library to interact with GDK Contracts
87 lines (73 loc) • 2.92 kB
text/typescript
import Web3 from "web3";
import { AbiItem } from "web3-utils";
import { QNonPayableTx, QPayableTx, SubmitTransactionResponse } from "../types";
import { Web3Adapter } from "../utils/web3-adapter";
import { BaseContract, NonPayableTransactionObject, PayableTransactionObject } from "../web3-contracts/types";
/**
* Base contract instance for all instances
*/
export class BaseContractInstance<T extends BaseContract> {
/**
* @field contract interface
*/
public instance: T;
protected adapter: Web3Adapter;
/**
* @field default to estimate - 1.3 would mean 30% above estimate
* @example BaseContractInstance.DEFAULT_GASBUFFER = 1.3
*/
public static DEFAULT_GASBUFFER = 1;
/**
* @field https://web3js.readthedocs.io/en/v1.8.1/web3-eth.html?highlight=handleRevert#handlerevert
* @example BaseContractInstance.HANDLE_REVERT = true
*/
public static HANDLE_REVERT = false;
/**
* Constructor
* @param web3 web3 instance
* @param abi abi object
* @param address contract address
*/
constructor(web3: Web3, abi: AbiItem[], public readonly address: string) {
this.adapter = new Web3Adapter(web3);
this.instance = new web3.eth.Contract(abi, address) as unknown as T;
this.instance.handleRevert = BaseContractInstance.HANDLE_REVERT;
}
async getBalance(convertToQ?: boolean): Promise<string> {
return await this.adapter.getBalance(this.address, convertToQ);
}
async submitTransaction<T>(
txObject: NonPayableTransactionObject<T> | PayableTransactionObject<T>,
txOptions?: QNonPayableTx | QPayableTx
): Promise<SubmitTransactionResponse> {
await this.refreshTxDefaultOptions();
if (!txOptions) txOptions = {};
await this.processTxOptions(txObject, txOptions);
return { promiEvent: txObject.send(txOptions) };
}
async processTxOptions<T>(
txObject: NonPayableTransactionObject<T> | PayableTransactionObject<T>,
txOptions: QNonPayableTx | QPayableTx
): Promise<void> {
// Note: this must be done before the estimateGas call, below
await this.processPayableTxOptions(txOptions as QPayableTx);
if (!txOptions.gas) {
// no explicit gas Limit
const gasBuffer = Number(txOptions.gasBuffer || BaseContractInstance.DEFAULT_GASBUFFER);
const estimate = await txObject.estimateGas(txOptions);
txOptions.gas = Math.floor(estimate * gasBuffer);
}
}
async processPayableTxOptions(txOptions: QPayableTx): Promise<void> {
if (!txOptions) return;
if (txOptions.qAmount) {
if (txOptions.value) throw new Error("QPayableTx must specify either value (in wei) OR qAmount, but not both");
txOptions.value = this.adapter.web3.utils.toWei(txOptions.qAmount.toString());
}
}
async refreshTxDefaultOptions(): Promise<void> {
if (!this.instance.options.from) {
this.instance.options.from = await this.adapter.getDefaultAccount();
}
}
}