jcc-ethereum-utils
Version:
Toolkit of crossing chain from Ethereum to SWTC chain
492 lines • 17.7 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
/// <reference path = "./types/transaction.ts" />
var bignumber_js_1 = require("bignumber.js");
var ethWallet = require("jcc_wallet/lib/eth");
var web3 = require("web3");
var contractClass = require("web3-eth-contract");
/**
* Toolkit of Ethereum
*
* @export
* @class Ethereum
*/
var Ethereum = /** @class */ (function () {
/**
* Creates an instance of Ethereum
* @param {string} node http node
* @memberof Ethereum
*/
function Ethereum(node) {
this._web3 = null;
this._node = node;
this._gasLimit = 200000;
this._minGasPrice = 5 * Math.pow(10, 9);
this._defaultGasPrice = Math.pow(10, 10);
}
Object.defineProperty(Ethereum.prototype, "gasLimit", {
/**
* set & get _gasLimit
*
* @type {number}
* @memberof Ethereum
*/
get: function () {
return this._gasLimit;
},
set: function (gas) {
this._gasLimit = gas;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Ethereum.prototype, "minGasPrice", {
/**
* set & get _minGasPrice
*
* @type {number}
* @memberof Ethereum
*/
get: function () {
return this._minGasPrice;
},
set: function (value) {
this._minGasPrice = value;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Ethereum.prototype, "defaultGasPrice", {
get: function () {
return this._defaultGasPrice;
},
/**
* set & get _defaultGasPrice
*
* @memberof Ethereum
*/
set: function (v) {
this._defaultGasPrice = v;
},
enumerable: false,
configurable: true
});
/**
* validate ethereum address
*
* @static
* @param {string} address ethereum address
* @returns {boolean} return true if the address is valid
* @memberof Ethereum
*/
Ethereum.isValidAddress = function (address) {
return ethWallet.isValidAddress(address);
};
/**
* validate ethereum secret
*
* @static
* @param {string} secret ethereum secret
* @returns {boolean} return true if the secret is valid
* @memberof Ethereum
*/
Ethereum.isValidSecret = function (secret) {
return ethWallet.isValidSecret(secret);
};
/**
* retrieve ethereum address via secret
*
* @static
* @param {string} secret ethereum secret
* @returns {string} return address if the secret is valid, otherwise return null
* @memberof Ethereum
*/
Ethereum.getAddress = function (secret) {
return ethWallet.getAddress(secret);
};
/**
* create ethereum wallet
*
* @static
* @returns {IWalletModel}
* @memberof Ethereum
*/
Ethereum.createWallet = function () {
return ethWallet.createWallet();
};
/**
* prefix `0x` if the given string not start with `0x`
*
* @static
* @param {string} str
* @returns {string}
* @memberof Ethereum
*/
Ethereum.prefix0x = function (str) {
if (str && !str.startsWith("0x")) {
str = "0x" + str;
}
return str;
};
/**
* filter `0x` if the given string starts with `0x`
*
* @static
* @param {string} str
* @returns {string}
* @memberof Ethereum
*/
Ethereum.filter0x = function (str) {
if (typeof str !== "string") {
return str;
}
return str.startsWith("0x") ? str.substring(2) : str;
};
/**
* init instance of web3
*
* @memberof Ethereum
*/
Ethereum.prototype.initWeb3 = function () {
if (!this._web3 || !this._web3.currentProvider) {
this._web3 = new web3(new web3.providers.HttpProvider(this._node));
}
};
/**
* destroy instance of web3
*
* @memberof Ethereum
*/
Ethereum.prototype.destroyWeb3 = function () {
try {
this._web3.setProvider(null);
}
catch (error) {
/* istanbul ignore next */
}
finally {
this._web3 = null;
}
};
/**
* get instance of web3
*
* @memberof Ethereum
*/
Ethereum.prototype.getWeb3 = function () {
return this._web3;
};
/**
* request info of block
*
* @param {number|string} block number or string latest
* @returns {Promise<any>} resolve null if request failed, return block info
* @memberof Ethereum
*/
Ethereum.prototype.getBlock = function (block) {
return __awaiter(this, void 0, void 0, function () {
var blockInfo, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, this._web3.eth.getBlock(block)];
case 1:
blockInfo = _a.sent();
return [3 /*break*/, 3];
case 2:
error_1 = _a.sent();
blockInfo = null;
return [3 /*break*/, 3];
case 3: return [2 /*return*/, blockInfo];
}
});
});
};
/**
* request balance of ether
*
* @param {string} address ethereum address
* @returns {Promise<string>} resolve "0" if request failed
* @memberof Ethereum
*/
Ethereum.prototype.getBalance = function (address) {
return __awaiter(this, void 0, void 0, function () {
var wei, balance;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this._web3.eth.getBalance(address)];
case 1:
wei = _a.sent();
balance = this._web3.utils.fromWei(wei);
return [2 /*return*/, balance];
}
});
});
};
/**
* request current gas price
*
* @returns {Promise<number>} resolve gas price if success
* @memberof Ethereum
*/
Ethereum.prototype.getGasPrice = function () {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
return [2 /*return*/, new Promise(function (resolve) {
_this._web3.eth.getGasPrice(function (err, data) {
if (err) {
data = _this._defaultGasPrice;
}
var limit = _this._minGasPrice;
if (data < limit) {
data = limit;
}
return resolve(data);
});
})];
});
});
};
/**
* request nonce
*
* @param {string} address ethereum address
* @returns {Promise<number>} resolve nonce if success
* @memberof Ethereum
*/
Ethereum.prototype.getNonce = function (address) {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
address = Ethereum.prefix0x(address);
return [2 /*return*/, new Promise(function (resolve, reject) {
_this._web3.eth.getTransactionCount(address, function (err, res) {
if (err) {
return reject(err);
}
var ethCount = res;
_this._web3.currentProvider.send({
id: 1,
jsonrpc: "2.0",
method: "parity_nextNonce",
params: [address]
}, function (error, response) {
if (error) {
return reject(error);
}
var count = new bignumber_js_1.default(response.result).toNumber();
var nonce = count > ethCount ? count : ethCount;
return resolve(nonce);
});
});
})];
});
});
};
/**
* check if has pending transaction
*
* @param {string} address
* @returns {Promise<boolean>} resolve true if has pending transaction
* @memberof Ethereum
*/
Ethereum.prototype.hasPendingTransactions = function (address) {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
return [2 /*return*/, new Promise(function (resolve, reject) {
_this._web3.currentProvider.send({
id: 1,
jsonrpc: "2.0",
method: "parity_pendingTransactions",
params: []
}, function (err, res) {
if (err) {
return reject(err);
}
address = Ethereum.prefix0x(address).toLowerCase();
var i = 0;
var hasPending = false;
for (i = 0; i < res.result.length; i++) {
var pending = res.result[i];
if (address.includes(pending.from.toLowerCase())) {
hasPending = true;
break;
}
}
return resolve(hasPending);
});
})];
});
});
};
/**
* format transaction info
*
* @param {string} from sender address
* @param {string} to destination address
* @param {number} nonce nonce
* @param {number} gasLimit gas limit
* @param {number} gasPrice gas price
* @param {string} value value
* @param {string} calldata call data
* @returns {IEthereumTransaction}
* @memberof Ethereum
*/
Ethereum.prototype.getTx = function (from, to, nonce, gasLimit, gasPrice, value, calldata) {
var tx = {
data: !calldata ? "0x0" : calldata,
from: from,
gas: this._web3.utils.toHex(gasLimit),
gasPrice: this._web3.utils.toHex(gasPrice),
nonce: nonce,
to: to,
value: (value === null || value === void 0 ? void 0 : value.startsWith("0x")) ? value : this._web3.utils.toHex(this._web3.utils.toWei(value + ""))
};
return tx;
};
/**
* sign transaction with ethereum secret
*
* @param {IEthereumTransaction} tx transaction
* @param {string} secret ethereum secret
* @returns {Promise<string>} return signed info
* @memberof Ethereum
*/
Ethereum.prototype.signTransaction = function (tx, secret) {
return __awaiter(this, void 0, void 0, function () {
var signed;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this._web3.eth.accounts.signTransaction(tx, secret)];
case 1:
signed = _a.sent();
return [2 /*return*/, signed.rawTransaction];
}
});
});
};
/**
* send signed transaction
*
* @param {string} sign
* @returns {Promise<string>} resolve hash if success
* @memberof Ethereum
*/
Ethereum.prototype.sendSignedTransaction = function (sign) {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
// TODO: https://web3js.readthedocs.io/en/v1.2.4/callbacks-promises-events.html#promievent
// sendSignedTransaction会自动绑定receipt等事件,在销毁实例时会抛出错误
return [2 /*return*/, new Promise(function (resolve, reject) {
_this._web3.eth.sendSignedTransaction(sign, function (err, hash) {
if (err) {
return reject(err);
}
return resolve(hash);
});
})];
});
});
};
/**
* get transaction
*
* @param {string} hash transaction hash
* @returns {any} null or transaction object
* @memberof Ethereum
*/
Ethereum.prototype.getTransaction = function (hash) {
var _this = this;
return new Promise(function (resolve, reject) {
_this._web3.eth.getTransaction(hash, function (err, data) {
if (err) {
return reject(err);
}
return resolve(data);
});
});
};
/**
* get transaction receipt
*
* @param {string} hash transaction hash
* @returns {any} null or transaction receipt object
* @memberof Ethereum
*/
Ethereum.prototype.getTransactionReceipt = function (hash) {
var _this = this;
return new Promise(function (resolve, reject) {
_this._web3.eth.getTransactionReceipt(hash, function (err, data) {
if (err) {
return reject(err);
}
return resolve(data);
});
});
};
/**
* init instance of ethereum or erc20 contract
*
* @param {abitItem} abi definition of ethereum abi or erc20 abi
* @param {string} address
* @returns {Contract} return instance of ethereum or erc20 contract
* @memberof Ethereum
*/
Ethereum.prototype.contract = function (abi, address) {
return new this._web3.eth.Contract(abi, address);
};
/**
* check instance of contract if initialied
*
* @param {Contract} contract current contract instance
* @param {string} address current contract address
* @returns {boolean} return true if initialied
* @memberof Ethereum
*/
Ethereum.prototype.contractInitialied = function (contract, address) {
return contract instanceof contractClass && contract.options.address.toLowerCase() === address.toLowerCase();
};
return Ethereum;
}());
exports.default = Ethereum;
//# sourceMappingURL=ethereum.js.map