@descent-protocol/sdk
Version:
A Typescript library for interacting with the Descent Protocol
98 lines (82 loc) • 3.43 kB
text/typescript
import { InterfaceAbi, TransactionRequest, ethers } from 'ethers';
import { DescentClass } from '..';
export interface GetTransactionConfigParams {
from: NonNullable<TransactionRequest['from']>;
to: NonNullable<TransactionRequest['to']>;
data: NonNullable<TransactionRequest['data']>;
value?: TransactionRequest['value'];
gasLimit?: TransactionRequest['gasLimit'];
gasPrice?: TransactionRequest['gasPrice'];
nonce?: TransactionRequest['nonce'];
maxPriorityFeePerGas?: TransactionRequest['maxPriorityFeePerGas'];
maxFeePerGas?: TransactionRequest['maxFeePerGas'];
}
export type EstimateGasParams = {
abi: InterfaceAbi;
args: any;
} & Required<Pick<TransactionRequest, 'from' | 'to' | 'value'>>;
export class Internal {
constructor(private descent: DescentClass) {}
/**
* Returns TransactionObject for any calls.
*
* Parameter `gasPrice` must be defined in mode `node` and is optional in mode `browser`.
*
* Parameter `nonce` only takes effect in mode `node`.
*
* @param params.from
* @param params.to
* @param params.callData
* @param params.value (optional)
* @param params.gasLimit (optional)
* @param params.gasPrice (optional only for "browser" mode)
* @param params.nonce (optional) mostly for "node" mode
* @param params.maxFeePerGas (optional only for "browser" mode)
* @param params.maxPriorityFeePerGas (optional only for "browser" mode)
*/
getTransactionConfig = async (params: GetTransactionConfigParams) => {
if (!params.from) throw new Error("Parameter 'from' is not defined.");
if (!params.to) throw new Error("Parameter 'to' is not defined.");
if (!params.data) throw new Error("Parameter 'data' is not defined.");
const from = params.from;
const to = params.to;
const data = params.data !== '0x' ? params.data : '0x';
const value = params.value ?? 0;
const gasLimit = params.gasLimit ?? (await this.getGas({ from, to, data, value }));
const transactionConfig: TransactionRequest = { from, to, data, value, gasLimit };
if (params.gasPrice) {
transactionConfig.gasPrice = params.gasPrice;
}
if (params.maxFeePerGas) {
transactionConfig.maxFeePerGas = params.maxFeePerGas;
}
if (params.maxPriorityFeePerGas) {
transactionConfig.maxPriorityFeePerGas = params.maxPriorityFeePerGas;
}
if (this.descent.configMode === 'node') {
if (!(params.maxFeePerGas && params.maxPriorityFeePerGas) && !params.gasPrice) {
throw new Error(
"Parameter 'gasPrice' or `maxFeePerGas` and `maxPriorityFeePerGas` must be defined when using mode 'node'.",
);
}
transactionConfig.nonce = params.nonce ?? (await this.getNonce(String(from)));
} else if (!!params.nonce) {
transactionConfig.nonce = params.nonce;
}
return transactionConfig;
};
private getNonce = async (from: string | number) => {
return await this.descent.signer.provider?.getTransactionCount(String(from));
};
private getGas = async (transactionConfig: TransactionRequest) => {
// @ts-ignore
return (await this.descent.signer.estimateGas(transactionConfig)) * BigInt(2); // increasing gas cost by 20% for margin
};
/**
* Returns the ABI interface for any Descent Protocol contract.
*/
getInterface = (abiItems: InterfaceAbi) => {
const abiItem = new ethers.Interface(abiItems);
return abiItem;
};
}