@atomiqlabs/chain-evm
Version:
EVM specific base implementation
143 lines (142 loc) • 5.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.EVMTokens = void 0;
const EVMModule_1 = require("../EVMModule");
const ethers_1 = require("ethers");
const ERC20Abi_1 = require("./ERC20Abi");
const EVMAddresses_1 = require("./EVMAddresses");
const EVMFees_1 = require("./EVMFees");
class EVMTokens extends EVMModule_1.EVMModule {
getContract(address) {
return new ethers_1.Contract(address, ERC20Abi_1.ERC20Abi, this.root.provider);
}
///////////////////
//// Tokens
/**
* Checks if the provided string is a valid starknet token
*
* @param token
*/
isValidToken(token) {
return EVMAddresses_1.EVMAddresses.isValidAddress(token);
}
/**
* Returns the token balance of the address
*
* @param address
* @param token
*/
async getTokenBalance(address, token) {
let balance;
if (token === "0x0000000000000000000000000000000000000000") {
balance = await this.provider.getBalance(address);
}
else {
const erc20 = this.getContract(token);
balance = await erc20.balanceOf(address);
}
this.logger.debug("getTokenBalance(): token balance fetched, token: " + token +
" address: " + address + " amount: " + balance.toString(10));
return balance;
}
/**
* Returns the authorized allowance of specific address towards a spender contract
*
* @param spender A contract trying to spend user's erc20 balance
* @param address Wallet address
* @param token ERC-20 token
*/
async getTokenAllowance(spender, address, token) {
if (token === "0x0000000000000000000000000000000000000000")
return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn;
const erc20 = this.getContract(token);
return await erc20.allowance(address, spender);
}
/**
* Returns the native currency address
*/
getNativeCurrencyAddress() {
return "0x0000000000000000000000000000000000000000";
}
///////////////////
//// Transfers
/**
* Creates transactions for sending the over the tokens
*
* @param signer
* @param token token to send
* @param amount amount of the token to send
* @param recipient recipient's address
* @param feeRate fee rate to use for the transactions
* @private
*/
async Transfer(signer, token, amount, recipient, feeRate) {
let tx;
if (token === this.getNativeCurrencyAddress()) {
tx = {
to: recipient,
value: amount
};
}
else {
tx = await this.getContract(token).transfer.populateTransaction(recipient, amount);
}
tx.from = signer;
EVMFees_1.EVMFees.applyFeeRate(tx, EVMTokens.GasCosts.TRANSFER, feeRate ?? await this.root.Fees.getFeeRate());
this.logger.debug("txsTransfer(): transfer TX created, recipient: " + recipient.toString() +
" token: " + token.toString() + " amount: " + amount.toString(10));
return tx;
}
///////////////////
//// Approval
/**
* Creates transactions for approving spending of tokens
*
* @param signer
* @param token token to send
* @param amount amount of the token to send
* @param spender recipient's address
* @param feeRate fee rate to use for the transactions
* @private
*/
async Approve(signer, token, amount, spender, feeRate) {
if (token === this.getNativeCurrencyAddress())
return null;
const tx = await this.getContract(token).approve.populateTransaction(spender, amount);
tx.from = signer;
EVMFees_1.EVMFees.applyFeeRate(tx, EVMTokens.GasCosts.APPROVE, feeRate ?? await this.root.Fees.getFeeRate());
this.logger.debug("txsTransfer(): approve TX created, spender: " + spender.toString() +
" token: " + token.toString() + " amount: " + amount.toString(10));
return tx;
}
/**
* Checks whether an approve transaction is required for a given token and either returns the tx
* or null in case the approve is not required
*
* @param signer
* @param token token to approve for
* @param amount amount of the token to send
* @param spender spending contract address
* @param feeRate fee rate to use for the transactions
*/
async checkAndGetApproveTx(signer, token, amount, spender, feeRate) {
const alreadyApproved = await this.getTokenAllowance(spender, signer, token);
if (alreadyApproved >= amount)
return null;
return await this.Approve(signer, token, amount, spender, feeRate);
}
async getApproveFee(feeRate) {
feeRate ?? (feeRate = await this.root.Fees.getFeeRate());
return EVMFees_1.EVMFees.getGasFee(EVMTokens.GasCosts.APPROVE, feeRate);
}
async getTransferFee(feeRate) {
feeRate ?? (feeRate = await this.root.Fees.getFeeRate());
return EVMFees_1.EVMFees.getGasFee(EVMTokens.GasCosts.APPROVE, feeRate);
}
}
exports.EVMTokens = EVMTokens;
EVMTokens.ETH_ADDRESS = "0x0000000000000000000000000000000000000000";
EVMTokens.GasCosts = {
TRANSFER: 80000 + 21000,
APPROVE: 80000 + 21000
};