essential-eth 0.1.1 โ†’ 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/lib/cjs/ether-to-wei.d.ts +2 -0
  2. package/lib/cjs/ether-to-wei.js +15 -0
  3. package/lib/cjs/index.d.ts +6 -0
  4. package/lib/cjs/index.js +14 -0
  5. package/lib/cjs/rpc/get-block.test.d.ts +1 -0
  6. package/lib/cjs/rpc/get-block.test.js +66 -0
  7. package/lib/cjs/rpc/index.d.ts +6 -0
  8. package/lib/cjs/rpc/index.js +36 -0
  9. package/lib/cjs/rpc/utils/clean-block.d.ts +2 -0
  10. package/lib/cjs/rpc/utils/clean-block.js +38 -0
  11. package/lib/cjs/rpc/utils/clean-transaction.d.ts +2 -0
  12. package/lib/cjs/rpc/utils/clean-transaction.js +33 -0
  13. package/lib/cjs/rpc/utils/fetchers.d.ts +7 -0
  14. package/lib/cjs/rpc/utils/fetchers.js +26 -0
  15. package/lib/cjs/rpc/utils/hex-to-decimal.d.ts +1 -0
  16. package/lib/cjs/rpc/utils/hex-to-decimal.js +7 -0
  17. package/lib/cjs/shared/tiny-big/helpers.d.ts +1 -0
  18. package/lib/cjs/shared/tiny-big/helpers.js +62 -0
  19. package/lib/cjs/shared/tiny-big/helpers.test.d.ts +1 -0
  20. package/lib/cjs/shared/tiny-big/helpers.test.js +31 -0
  21. package/lib/cjs/shared/tiny-big/tiny-big.d.ts +7 -0
  22. package/lib/cjs/shared/tiny-big/tiny-big.js +27 -0
  23. package/lib/cjs/shared/validate-type.d.ts +3 -0
  24. package/lib/cjs/shared/validate-type.js +9 -0
  25. package/lib/cjs/to-checksum-address.d.ts +1 -0
  26. package/lib/cjs/to-checksum-address.js +25 -0
  27. package/lib/cjs/types/block.types.d.ts +47 -0
  28. package/lib/cjs/types/block.types.js +2 -0
  29. package/lib/cjs/types/transaction.types.d.ts +34 -0
  30. package/lib/cjs/types/transaction.types.js +2 -0
  31. package/lib/cjs/wei-to-ether.d.ts +1 -0
  32. package/lib/cjs/wei-to-ether.js +15 -0
  33. package/lib/esm/index.d.ts +2 -1
  34. package/lib/esm/index.js +2 -1
  35. package/lib/esm/rpc/get-block.test.d.ts +1 -0
  36. package/lib/esm/rpc/get-block.test.js +61 -0
  37. package/lib/esm/rpc/index.d.ts +6 -0
  38. package/lib/esm/rpc/index.js +32 -0
  39. package/lib/esm/rpc/utils/clean-block.d.ts +2 -0
  40. package/lib/esm/rpc/utils/clean-block.js +34 -0
  41. package/lib/esm/rpc/utils/clean-transaction.d.ts +2 -0
  42. package/lib/esm/rpc/utils/clean-transaction.js +29 -0
  43. package/lib/esm/rpc/utils/fetchers.d.ts +7 -0
  44. package/lib/esm/rpc/utils/fetchers.js +18 -0
  45. package/lib/esm/rpc/utils/hex-to-decimal.d.ts +1 -0
  46. package/lib/esm/rpc/utils/hex-to-decimal.js +3 -0
  47. package/lib/esm/shared/tiny-big/tiny-big.d.ts +1 -2
  48. package/lib/esm/shared/tiny-big/tiny-big.js +7 -4
  49. package/lib/esm/to-checksum-address.js +14 -8
  50. package/lib/esm/types/block.types.d.ts +47 -0
  51. package/lib/esm/types/block.types.js +1 -0
  52. package/lib/esm/types/transaction.types.d.ts +34 -0
  53. package/lib/esm/types/transaction.types.js +1 -0
  54. package/package.json +32 -16
  55. package/readme.md +89 -2
@@ -0,0 +1,2 @@
1
+ import { TinyBig } from './shared/tiny-big/tiny-big';
2
+ export declare function etherToWei(etherQuantity: string | number): TinyBig;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.etherToWei = void 0;
7
+ const big_js_1 = __importDefault(require("big.js"));
8
+ const tiny_big_1 = require("./shared/tiny-big/tiny-big");
9
+ const validate_type_1 = require("./shared/validate-type");
10
+ function etherToWei(etherQuantity) {
11
+ (0, validate_type_1.validateType)(etherQuantity, ['string', 'number']);
12
+ const result = (0, big_js_1.default)(etherQuantity).times('1000000000000000000').toString();
13
+ return (0, tiny_big_1.tinyBig)(result);
14
+ }
15
+ exports.etherToWei = etherToWei;
@@ -0,0 +1,6 @@
1
+ import { etherToWei } from './ether-to-wei';
2
+ import { EssentialEth } from './rpc/index';
3
+ import { tinyBig, TinyBig } from './shared/tiny-big/tiny-big';
4
+ import { toChecksumAddress } from './to-checksum-address';
5
+ import { weiToEther } from './wei-to-ether';
6
+ export { toChecksumAddress, etherToWei, weiToEther, tinyBig, TinyBig, EssentialEth, };
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EssentialEth = exports.TinyBig = exports.tinyBig = exports.weiToEther = exports.etherToWei = exports.toChecksumAddress = void 0;
4
+ const ether_to_wei_1 = require("./ether-to-wei");
5
+ Object.defineProperty(exports, "etherToWei", { enumerable: true, get: function () { return ether_to_wei_1.etherToWei; } });
6
+ const index_1 = require("./rpc/index");
7
+ Object.defineProperty(exports, "EssentialEth", { enumerable: true, get: function () { return index_1.EssentialEth; } });
8
+ const tiny_big_1 = require("./shared/tiny-big/tiny-big");
9
+ Object.defineProperty(exports, "tinyBig", { enumerable: true, get: function () { return tiny_big_1.tinyBig; } });
10
+ Object.defineProperty(exports, "TinyBig", { enumerable: true, get: function () { return tiny_big_1.TinyBig; } });
11
+ const to_checksum_address_1 = require("./to-checksum-address");
12
+ Object.defineProperty(exports, "toChecksumAddress", { enumerable: true, get: function () { return to_checksum_address_1.toChecksumAddress; } });
13
+ const wei_to_ether_1 = require("./wei-to-ether");
14
+ Object.defineProperty(exports, "weiToEther", { enumerable: true, get: function () { return wei_to_ether_1.weiToEther; } });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const big_js_1 = __importDefault(require("big.js"));
16
+ const just_omit_1 = __importDefault(require("just-omit"));
17
+ const web3_1 = __importDefault(require("web3"));
18
+ const _1 = require(".");
19
+ const rpcUrl = 'https://free-eth-node.com/api/eth';
20
+ describe('matches web3', () => {
21
+ function testBlockEquality(block1, block2) {
22
+ expect((0, just_omit_1.default)(block1, ['totalDifficulty', 'difficulty'])).toStrictEqual((0, just_omit_1.default)(block2, ['totalDifficulty', 'difficulty']));
23
+ expect((0, big_js_1.default)(block1.difficulty).minus(block2.difficulty).abs().toNumber()).toBeLessThan(3);
24
+ expect((0, big_js_1.default)(block1.totalDifficulty)
25
+ .minus(block2.totalDifficulty)
26
+ .abs()
27
+ .toNumber()).toBeLessThan(4000000);
28
+ }
29
+ it('should allow default eth node to get latest block', () => __awaiter(void 0, void 0, void 0, function* () {
30
+ const essentialEth = new _1.EssentialEth();
31
+ const web3 = new web3_1.default(rpcUrl);
32
+ const [eeLatestBlock, web3LatestBlock] = yield Promise.all([
33
+ essentialEth.getBlock('latest'),
34
+ web3.eth.getBlock('latest'),
35
+ ]);
36
+ testBlockEquality(eeLatestBlock, web3LatestBlock);
37
+ }));
38
+ it('should get latest block', () => __awaiter(void 0, void 0, void 0, function* () {
39
+ const essentialEth = new _1.EssentialEth(rpcUrl);
40
+ const web3 = new web3_1.default(rpcUrl);
41
+ const [eeLatestBlock, web3LatestBlock] = yield Promise.all([
42
+ essentialEth.getBlock('latest'),
43
+ web3.eth.getBlock('latest'),
44
+ ]);
45
+ testBlockEquality(eeLatestBlock, web3LatestBlock);
46
+ }));
47
+ it('should get earliest block', () => __awaiter(void 0, void 0, void 0, function* () {
48
+ const essentialEth = new _1.EssentialEth(rpcUrl);
49
+ const web3 = new web3_1.default(rpcUrl);
50
+ const [eeEarliestBlock, web3EarliestBlock] = yield Promise.all([
51
+ essentialEth.getBlock('earliest'),
52
+ web3.eth.getBlock('earliest'),
53
+ ]);
54
+ testBlockEquality(eeEarliestBlock, web3EarliestBlock);
55
+ }));
56
+ const blockNumber = Math.floor(Math.random() * 13250630);
57
+ it(`should get random block as decimal integer. (block #${blockNumber})`, () => __awaiter(void 0, void 0, void 0, function* () {
58
+ const essentialEth = new _1.EssentialEth(rpcUrl);
59
+ const web3 = new web3_1.default(rpcUrl);
60
+ const [eeRandomBlock, web3RandomBlock] = yield Promise.all([
61
+ essentialEth.getBlock(blockNumber, true),
62
+ web3.eth.getBlock(blockNumber, true),
63
+ ]);
64
+ testBlockEquality(eeRandomBlock, web3RandomBlock);
65
+ }));
66
+ });
@@ -0,0 +1,6 @@
1
+ import { Block } from '../types/block.types';
2
+ export declare class EssentialEth {
3
+ _rpcUrl: string;
4
+ constructor(rpcUrl?: string);
5
+ getBlock(timeFrame: 'latest' | 'earliest' | 'pending' | number, returnTransactionObjects?: boolean): Promise<Block>;
6
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.EssentialEth = void 0;
13
+ const clean_block_1 = require("./utils/clean-block");
14
+ const fetchers_1 = require("./utils/fetchers");
15
+ class EssentialEth {
16
+ constructor(rpcUrl) {
17
+ this._rpcUrl = rpcUrl || 'https://free-eth-node.com/api/eth';
18
+ }
19
+ getBlock(timeFrame, returnTransactionObjects = false) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ let rpcTimeFrame;
22
+ if (typeof timeFrame === 'number') {
23
+ rpcTimeFrame = `0x${timeFrame.toString(16)}`;
24
+ }
25
+ else {
26
+ rpcTimeFrame = timeFrame;
27
+ }
28
+ const nodeResponse = yield (0, fetchers_1.post)(this._rpcUrl, (0, fetchers_1.buildRPCPostBody)('eth_getBlockByNumber', [
29
+ rpcTimeFrame,
30
+ returnTransactionObjects,
31
+ ])).then((data) => data.result);
32
+ return (0, clean_block_1.cleanBlock)(nodeResponse, returnTransactionObjects);
33
+ });
34
+ }
35
+ }
36
+ exports.EssentialEth = EssentialEth;
@@ -0,0 +1,2 @@
1
+ import { Block, RPCBlock } from '../../types/block.types';
2
+ export declare function cleanBlock(block: RPCBlock, returnTransactionObjects: boolean): Block;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cleanBlock = void 0;
4
+ const __1 = require("../..");
5
+ const clean_transaction_1 = require("./clean-transaction");
6
+ const hex_to_decimal_1 = require("./hex-to-decimal");
7
+ function cleanBlock(block, returnTransactionObjects) {
8
+ const cleanedBlock = Object.assign({}, block);
9
+ Object.keys(block).forEach((key) => {
10
+ if (!block[key])
11
+ return;
12
+ switch (key) {
13
+ case 'gasLimit':
14
+ case 'gasUsed':
15
+ case 'number':
16
+ case 'size':
17
+ case 'timestamp':
18
+ cleanedBlock[key] = Number((0, hex_to_decimal_1.hexToDecimal)(block[key]));
19
+ break;
20
+ case 'difficulty':
21
+ case 'totalDifficulty':
22
+ cleanedBlock[key] = (0, hex_to_decimal_1.hexToDecimal)(block[key]);
23
+ break;
24
+ case 'miner':
25
+ if (block[key]) {
26
+ cleanedBlock[key] = (0, __1.toChecksumAddress)(block[key]);
27
+ }
28
+ break;
29
+ }
30
+ });
31
+ if (returnTransactionObjects) {
32
+ cleanedBlock.transactions.forEach((transaction, index) => {
33
+ cleanedBlock.transactions[index] = (0, clean_transaction_1.cleanTransaction)(transaction);
34
+ });
35
+ }
36
+ return cleanedBlock;
37
+ }
38
+ exports.cleanBlock = cleanBlock;
@@ -0,0 +1,2 @@
1
+ import { RPCTransaction, Transaction } from '../../types/transaction.types';
2
+ export declare function cleanTransaction(transaction: RPCTransaction): Transaction;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cleanTransaction = void 0;
4
+ const __1 = require("../..");
5
+ const hex_to_decimal_1 = require("./hex-to-decimal");
6
+ function cleanTransaction(transaction) {
7
+ const cleanedTransaction = Object.assign({}, transaction);
8
+ Object.keys(transaction).forEach((key) => {
9
+ if (!transaction[key])
10
+ return;
11
+ switch (key) {
12
+ case 'blockNumber':
13
+ case 'gas':
14
+ case 'nonce':
15
+ case 'transactionIndex':
16
+ case 'type':
17
+ cleanedTransaction[key] = Number((0, hex_to_decimal_1.hexToDecimal)(transaction[key]));
18
+ break;
19
+ case 'gasPrice':
20
+ case 'value':
21
+ cleanedTransaction[key] = (0, hex_to_decimal_1.hexToDecimal)(transaction[key]);
22
+ break;
23
+ case 'from':
24
+ case 'to':
25
+ if (transaction[key]) {
26
+ cleanedTransaction[key] = (0, __1.toChecksumAddress)(transaction[key]);
27
+ }
28
+ break;
29
+ }
30
+ });
31
+ return cleanedTransaction;
32
+ }
33
+ exports.cleanTransaction = cleanTransaction;
@@ -0,0 +1,7 @@
1
+ export declare function post(url: string, body: Record<string, unknown>): Promise<any>;
2
+ export declare function buildRPCPostBody(method: 'eth_getBlockByNumber', params: any[]): {
3
+ jsonrpc: string;
4
+ id: number;
5
+ method: "eth_getBlockByNumber";
6
+ params: any[];
7
+ };
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildRPCPostBody = exports.post = void 0;
7
+ const isomorphic_unfetch_1 = __importDefault(require("isomorphic-unfetch"));
8
+ function post(url, body) {
9
+ return (0, isomorphic_unfetch_1.default)(url, {
10
+ method: 'POST',
11
+ headers: {
12
+ 'Content-Type': 'application/json',
13
+ },
14
+ body: JSON.stringify(body),
15
+ }).then((r) => r.json());
16
+ }
17
+ exports.post = post;
18
+ function buildRPCPostBody(method, params) {
19
+ return {
20
+ jsonrpc: '2.0',
21
+ id: 1,
22
+ method,
23
+ params,
24
+ };
25
+ }
26
+ exports.buildRPCPostBody = buildRPCPostBody;
@@ -0,0 +1 @@
1
+ export declare function hexToDecimal(hex: string): string;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hexToDecimal = void 0;
4
+ function hexToDecimal(hex) {
5
+ return BigInt(hex).toString();
6
+ }
7
+ exports.hexToDecimal = hexToDecimal;
@@ -0,0 +1 @@
1
+ export declare function scientificStrToDecimalStr(scientificString: string): string;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scientificStrToDecimalStr = void 0;
4
+ function stripTrailingZeroes(numberString) {
5
+ const isNegative = numberString.startsWith('-');
6
+ numberString = numberString.replace('-', '');
7
+ numberString = numberString.replace(/\.0*$/g, '');
8
+ numberString = numberString.replace(/^0+/, '');
9
+ if (numberString.includes('.')) {
10
+ numberString = numberString.replace(/0+$/, '');
11
+ }
12
+ if (numberString.startsWith('.')) {
13
+ numberString = `0${numberString}`;
14
+ }
15
+ return `${isNegative ? '-' : ''}${numberString}`;
16
+ }
17
+ function scientificStrToDecimalStr(scientificString) {
18
+ if (!scientificString.match(/e/i)) {
19
+ return stripTrailingZeroes(scientificString);
20
+ }
21
+ let [base, power] = scientificString.split(/e/i);
22
+ const isNegative = Number(base) < 0;
23
+ base = base.replace('-', '');
24
+ base = stripTrailingZeroes(base);
25
+ const [wholeNumber, fraction = ''] = base.split('.');
26
+ if (Number(power) === 0) {
27
+ return `${isNegative ? '-' : ''}${stripTrailingZeroes(base)}`;
28
+ }
29
+ else {
30
+ const includesDecimal = base.includes('.');
31
+ if (!includesDecimal) {
32
+ base = `${base}.`;
33
+ }
34
+ base = base.replace('.', '');
35
+ const baseLength = base.length;
36
+ let splitPaddedNumber;
37
+ if (Number(power) < 0) {
38
+ if (wholeNumber.length < Math.abs(Number(power))) {
39
+ base = base.padStart(baseLength + Math.abs(Number(power)) - wholeNumber.length, '0');
40
+ }
41
+ splitPaddedNumber = base.split('');
42
+ if (wholeNumber.length < Math.abs(Number(power))) {
43
+ splitPaddedNumber = ['.', ...splitPaddedNumber];
44
+ }
45
+ else {
46
+ splitPaddedNumber.splice(splitPaddedNumber.length - Math.abs(Number(power)), 0, '.');
47
+ }
48
+ }
49
+ else {
50
+ if (fraction.length < Math.abs(Number(power))) {
51
+ base = base.padEnd(baseLength + Math.abs(Number(power)) - fraction.length, '0');
52
+ }
53
+ splitPaddedNumber = base.split('');
54
+ if (fraction.length > Math.abs(Number(power))) {
55
+ splitPaddedNumber.splice(splitPaddedNumber.length - Math.abs(Number(power)), 0, '.');
56
+ }
57
+ }
58
+ const toReturn = stripTrailingZeroes(splitPaddedNumber.join(''));
59
+ return `${isNegative ? '-' : ''}${toReturn}`;
60
+ }
61
+ }
62
+ exports.scientificStrToDecimalStr = scientificStrToDecimalStr;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const helpers_1 = require("./helpers");
4
+ describe('scientificStrToDecimalStr', () => {
5
+ it('not even scientific', () => {
6
+ expect((0, helpers_1.scientificStrToDecimalStr)('010')).toStrictEqual('10');
7
+ expect((0, helpers_1.scientificStrToDecimalStr)('-010')).toStrictEqual('-10');
8
+ });
9
+ it('zero power', () => {
10
+ expect((0, helpers_1.scientificStrToDecimalStr)('10e0')).toStrictEqual('10');
11
+ expect((0, helpers_1.scientificStrToDecimalStr)('1.0e0')).toStrictEqual('1');
12
+ expect((0, helpers_1.scientificStrToDecimalStr)('-10e-0')).toStrictEqual('-10');
13
+ expect((0, helpers_1.scientificStrToDecimalStr)('-1.0e-0')).toStrictEqual('-1');
14
+ expect((0, helpers_1.scientificStrToDecimalStr)('-1.10e-0')).toStrictEqual('-1.1');
15
+ expect((0, helpers_1.scientificStrToDecimalStr)('-1.e-0')).toStrictEqual('-1');
16
+ expect((0, helpers_1.scientificStrToDecimalStr)('.10e-0')).toStrictEqual('0.1');
17
+ expect((0, helpers_1.scientificStrToDecimalStr)('00.0010e-0')).toStrictEqual('0.001');
18
+ });
19
+ it('negative power', () => {
20
+ expect((0, helpers_1.scientificStrToDecimalStr)('0100e-2')).toStrictEqual('1');
21
+ expect((0, helpers_1.scientificStrToDecimalStr)('0100e-4')).toStrictEqual('0.01');
22
+ expect((0, helpers_1.scientificStrToDecimalStr)('010.1e-3')).toStrictEqual('0.0101');
23
+ expect((0, helpers_1.scientificStrToDecimalStr)('-010.1e-3')).toStrictEqual('-0.0101');
24
+ expect((0, helpers_1.scientificStrToDecimalStr)('09.1e-51')).toStrictEqual(`0.${'0'.repeat(50)}91`);
25
+ });
26
+ it('positive power', () => {
27
+ expect((0, helpers_1.scientificStrToDecimalStr)('01e2')).toStrictEqual('100');
28
+ expect((0, helpers_1.scientificStrToDecimalStr)('-01e2')).toStrictEqual('-100');
29
+ expect((0, helpers_1.scientificStrToDecimalStr)('09.1e51')).toStrictEqual(`91${'0'.repeat(50)}`);
30
+ });
31
+ });
@@ -0,0 +1,7 @@
1
+ import Big from 'big.js';
2
+ export declare class TinyBig extends Big {
3
+ constructor(value: number | string);
4
+ toNumber(): number;
5
+ toString(): string;
6
+ }
7
+ export declare function tinyBig(value: number | string): TinyBig;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.tinyBig = exports.TinyBig = void 0;
7
+ const big_js_1 = __importDefault(require("big.js"));
8
+ const helpers_1 = require("./helpers");
9
+ class TinyBig extends big_js_1.default {
10
+ constructor(value) {
11
+ super(value);
12
+ }
13
+ toNumber() {
14
+ return Number((0, helpers_1.scientificStrToDecimalStr)(super.toString()));
15
+ }
16
+ toString() {
17
+ if (this.toNumber() === 0) {
18
+ return '0';
19
+ }
20
+ return (0, helpers_1.scientificStrToDecimalStr)(super.toString());
21
+ }
22
+ }
23
+ exports.TinyBig = TinyBig;
24
+ function tinyBig(value) {
25
+ return new TinyBig(value);
26
+ }
27
+ exports.tinyBig = tinyBig;
@@ -0,0 +1,3 @@
1
+ declare type JSPrimitiveTypes = 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function';
2
+ export declare const validateType: (value: unknown, allowedTypes: JSPrimitiveTypes[]) => void;
3
+ export {};
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateType = void 0;
4
+ const validateType = (value, allowedTypes) => {
5
+ if (!allowedTypes.includes(typeof value)) {
6
+ throw new Error(`${allowedTypes.join(' or ')} required. Received ${typeof value}`);
7
+ }
8
+ };
9
+ exports.validateType = validateType;
@@ -0,0 +1 @@
1
+ export declare function toChecksumAddress(address: string): string;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toChecksumAddress = void 0;
4
+ const sha3_1 = require("sha3");
5
+ const validate_type_1 = require("./shared/validate-type");
6
+ function toChecksumAddress(address) {
7
+ (0, validate_type_1.validateType)(address, ['string']);
8
+ if (!/^(0x)?[0-9a-f]{40}$/i.test(address)) {
9
+ throw new Error(`Invalid Ethereum address "${address}"`);
10
+ }
11
+ address = address.toLowerCase().replace(/^0x/i, '');
12
+ const keccak = new sha3_1.Keccak(256);
13
+ const addressHash = keccak.update(address).digest('hex').replace(/^0x/i, '');
14
+ let checksumAddress = '0x';
15
+ for (let i = 0; i < address.length; i++) {
16
+ if (parseInt(addressHash[i], 16) > 7) {
17
+ checksumAddress += address[i].toUpperCase();
18
+ }
19
+ else {
20
+ checksumAddress += address[i];
21
+ }
22
+ }
23
+ return checksumAddress;
24
+ }
25
+ exports.toChecksumAddress = toChecksumAddress;
@@ -0,0 +1,47 @@
1
+ import { RPCTransaction, Transaction } from './transaction.types';
2
+ export interface Block {
3
+ baseFeePerGas: string;
4
+ difficulty: number;
5
+ extraData: string;
6
+ gasLimit: number;
7
+ gasUsed: number;
8
+ hash: string;
9
+ logsBloom: string;
10
+ miner: string;
11
+ mixHash: string;
12
+ nonce: string;
13
+ number: number;
14
+ parentHash: string;
15
+ receiptsRoot: string;
16
+ sha3Uncles: string;
17
+ size: number;
18
+ stateRoot: string;
19
+ timestamp: number;
20
+ totalDifficulty: number;
21
+ transactions: string[] | Transaction[];
22
+ transactionsRoot: string;
23
+ uncles: unknown[];
24
+ }
25
+ export interface RPCBlock {
26
+ baseFeePerGas: string;
27
+ difficulty: string;
28
+ extraData: string;
29
+ gasLimit: string;
30
+ gasUsed: string;
31
+ hash: string;
32
+ logsBloom: string;
33
+ miner: string;
34
+ mixHash: string;
35
+ nonce: string;
36
+ number: string;
37
+ parentHash: string;
38
+ receiptsRoot: string;
39
+ sha3Uncles: string;
40
+ size: string;
41
+ stateRoot: string;
42
+ timestamp: string;
43
+ totalDifficulty: string;
44
+ transactions: Array<string> | Array<RPCTransaction>;
45
+ transactionsRoot: string;
46
+ uncles: unknown[];
47
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,34 @@
1
+ export interface Transaction {
2
+ blockHash: string;
3
+ blockNumber: number;
4
+ from: string;
5
+ gas: number;
6
+ gasPrice: string;
7
+ hash: string;
8
+ input: string;
9
+ nonce: number;
10
+ r: string;
11
+ s: string;
12
+ to: string;
13
+ transactionIndex: number;
14
+ type: number;
15
+ v: string;
16
+ value: string;
17
+ }
18
+ export interface RPCTransaction {
19
+ blockHash: string;
20
+ blockNumber: string;
21
+ from: string;
22
+ gas: string;
23
+ gasPrice: string;
24
+ hash: string;
25
+ input: string;
26
+ nonce: string;
27
+ r: string;
28
+ s: string;
29
+ to: string;
30
+ transactionIndex: string;
31
+ type: string;
32
+ v: string;
33
+ value: string;
34
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export declare function weiToEther(weiQuantity: string | number): import("./shared/tiny-big/tiny-big").TinyBig;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.weiToEther = void 0;
7
+ const big_js_1 = __importDefault(require("big.js"));
8
+ const tiny_big_1 = require("./shared/tiny-big/tiny-big");
9
+ const validate_type_1 = require("./shared/validate-type");
10
+ function weiToEther(weiQuantity) {
11
+ (0, validate_type_1.validateType)(weiQuantity, ['string', 'number']);
12
+ const result = (0, big_js_1.default)(weiQuantity).div('1000000000000000000').toString();
13
+ return (0, tiny_big_1.tinyBig)(result);
14
+ }
15
+ exports.weiToEther = weiToEther;
@@ -1,5 +1,6 @@
1
1
  import { etherToWei } from './ether-to-wei';
2
+ import { EssentialEth } from './rpc/index';
2
3
  import { tinyBig, TinyBig } from './shared/tiny-big/tiny-big';
3
4
  import { toChecksumAddress } from './to-checksum-address';
4
5
  import { weiToEther } from './wei-to-ether';
5
- export { toChecksumAddress, etherToWei, weiToEther, tinyBig, TinyBig };
6
+ export { toChecksumAddress, etherToWei, weiToEther, tinyBig, TinyBig, EssentialEth, };
package/lib/esm/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { etherToWei } from './ether-to-wei';
2
+ import { EssentialEth } from './rpc/index';
2
3
  import { tinyBig, TinyBig } from './shared/tiny-big/tiny-big';
3
4
  import { toChecksumAddress } from './to-checksum-address';
4
5
  import { weiToEther } from './wei-to-ether';
5
- export { toChecksumAddress, etherToWei, weiToEther, tinyBig, TinyBig };
6
+ export { toChecksumAddress, etherToWei, weiToEther, tinyBig, TinyBig, EssentialEth, };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,61 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import Big from 'big.js';
11
+ import omit from 'just-omit';
12
+ import Web3 from 'web3';
13
+ import { EssentialEth } from '.';
14
+ const rpcUrl = 'https://free-eth-node.com/api/eth';
15
+ describe('matches web3', () => {
16
+ function testBlockEquality(block1, block2) {
17
+ expect(omit(block1, ['totalDifficulty', 'difficulty'])).toStrictEqual(omit(block2, ['totalDifficulty', 'difficulty']));
18
+ expect(Big(block1.difficulty).minus(block2.difficulty).abs().toNumber()).toBeLessThan(3);
19
+ expect(Big(block1.totalDifficulty)
20
+ .minus(block2.totalDifficulty)
21
+ .abs()
22
+ .toNumber()).toBeLessThan(4000000);
23
+ }
24
+ it('should allow default eth node to get latest block', () => __awaiter(void 0, void 0, void 0, function* () {
25
+ const essentialEth = new EssentialEth();
26
+ const web3 = new Web3(rpcUrl);
27
+ const [eeLatestBlock, web3LatestBlock] = yield Promise.all([
28
+ essentialEth.getBlock('latest'),
29
+ web3.eth.getBlock('latest'),
30
+ ]);
31
+ testBlockEquality(eeLatestBlock, web3LatestBlock);
32
+ }));
33
+ it('should get latest block', () => __awaiter(void 0, void 0, void 0, function* () {
34
+ const essentialEth = new EssentialEth(rpcUrl);
35
+ const web3 = new Web3(rpcUrl);
36
+ const [eeLatestBlock, web3LatestBlock] = yield Promise.all([
37
+ essentialEth.getBlock('latest'),
38
+ web3.eth.getBlock('latest'),
39
+ ]);
40
+ testBlockEquality(eeLatestBlock, web3LatestBlock);
41
+ }));
42
+ it('should get earliest block', () => __awaiter(void 0, void 0, void 0, function* () {
43
+ const essentialEth = new EssentialEth(rpcUrl);
44
+ const web3 = new Web3(rpcUrl);
45
+ const [eeEarliestBlock, web3EarliestBlock] = yield Promise.all([
46
+ essentialEth.getBlock('earliest'),
47
+ web3.eth.getBlock('earliest'),
48
+ ]);
49
+ testBlockEquality(eeEarliestBlock, web3EarliestBlock);
50
+ }));
51
+ const blockNumber = Math.floor(Math.random() * 13250630);
52
+ it(`should get random block as decimal integer. (block #${blockNumber})`, () => __awaiter(void 0, void 0, void 0, function* () {
53
+ const essentialEth = new EssentialEth(rpcUrl);
54
+ const web3 = new Web3(rpcUrl);
55
+ const [eeRandomBlock, web3RandomBlock] = yield Promise.all([
56
+ essentialEth.getBlock(blockNumber, true),
57
+ web3.eth.getBlock(blockNumber, true),
58
+ ]);
59
+ testBlockEquality(eeRandomBlock, web3RandomBlock);
60
+ }));
61
+ });
@@ -0,0 +1,6 @@
1
+ import { Block } from '../types/block.types';
2
+ export declare class EssentialEth {
3
+ _rpcUrl: string;
4
+ constructor(rpcUrl?: string);
5
+ getBlock(timeFrame: 'latest' | 'earliest' | 'pending' | number, returnTransactionObjects?: boolean): Promise<Block>;
6
+ }
@@ -0,0 +1,32 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { cleanBlock } from './utils/clean-block';
11
+ import { buildRPCPostBody, post } from './utils/fetchers';
12
+ export class EssentialEth {
13
+ constructor(rpcUrl) {
14
+ this._rpcUrl = rpcUrl || 'https://free-eth-node.com/api/eth';
15
+ }
16
+ getBlock(timeFrame, returnTransactionObjects = false) {
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ let rpcTimeFrame;
19
+ if (typeof timeFrame === 'number') {
20
+ rpcTimeFrame = `0x${timeFrame.toString(16)}`;
21
+ }
22
+ else {
23
+ rpcTimeFrame = timeFrame;
24
+ }
25
+ const nodeResponse = yield post(this._rpcUrl, buildRPCPostBody('eth_getBlockByNumber', [
26
+ rpcTimeFrame,
27
+ returnTransactionObjects,
28
+ ])).then((data) => data.result);
29
+ return cleanBlock(nodeResponse, returnTransactionObjects);
30
+ });
31
+ }
32
+ }
@@ -0,0 +1,2 @@
1
+ import { Block, RPCBlock } from '../../types/block.types';
2
+ export declare function cleanBlock(block: RPCBlock, returnTransactionObjects: boolean): Block;
@@ -0,0 +1,34 @@
1
+ import { toChecksumAddress } from '../..';
2
+ import { cleanTransaction } from './clean-transaction';
3
+ import { hexToDecimal } from './hex-to-decimal';
4
+ export function cleanBlock(block, returnTransactionObjects) {
5
+ const cleanedBlock = Object.assign({}, block);
6
+ Object.keys(block).forEach((key) => {
7
+ if (!block[key])
8
+ return;
9
+ switch (key) {
10
+ case 'gasLimit':
11
+ case 'gasUsed':
12
+ case 'number':
13
+ case 'size':
14
+ case 'timestamp':
15
+ cleanedBlock[key] = Number(hexToDecimal(block[key]));
16
+ break;
17
+ case 'difficulty':
18
+ case 'totalDifficulty':
19
+ cleanedBlock[key] = hexToDecimal(block[key]);
20
+ break;
21
+ case 'miner':
22
+ if (block[key]) {
23
+ cleanedBlock[key] = toChecksumAddress(block[key]);
24
+ }
25
+ break;
26
+ }
27
+ });
28
+ if (returnTransactionObjects) {
29
+ cleanedBlock.transactions.forEach((transaction, index) => {
30
+ cleanedBlock.transactions[index] = cleanTransaction(transaction);
31
+ });
32
+ }
33
+ return cleanedBlock;
34
+ }
@@ -0,0 +1,2 @@
1
+ import { RPCTransaction, Transaction } from '../../types/transaction.types';
2
+ export declare function cleanTransaction(transaction: RPCTransaction): Transaction;
@@ -0,0 +1,29 @@
1
+ import { toChecksumAddress } from '../..';
2
+ import { hexToDecimal } from './hex-to-decimal';
3
+ export function cleanTransaction(transaction) {
4
+ const cleanedTransaction = Object.assign({}, transaction);
5
+ Object.keys(transaction).forEach((key) => {
6
+ if (!transaction[key])
7
+ return;
8
+ switch (key) {
9
+ case 'blockNumber':
10
+ case 'gas':
11
+ case 'nonce':
12
+ case 'transactionIndex':
13
+ case 'type':
14
+ cleanedTransaction[key] = Number(hexToDecimal(transaction[key]));
15
+ break;
16
+ case 'gasPrice':
17
+ case 'value':
18
+ cleanedTransaction[key] = hexToDecimal(transaction[key]);
19
+ break;
20
+ case 'from':
21
+ case 'to':
22
+ if (transaction[key]) {
23
+ cleanedTransaction[key] = toChecksumAddress(transaction[key]);
24
+ }
25
+ break;
26
+ }
27
+ });
28
+ return cleanedTransaction;
29
+ }
@@ -0,0 +1,7 @@
1
+ export declare function post(url: string, body: Record<string, unknown>): Promise<any>;
2
+ export declare function buildRPCPostBody(method: 'eth_getBlockByNumber', params: any[]): {
3
+ jsonrpc: string;
4
+ id: number;
5
+ method: "eth_getBlockByNumber";
6
+ params: any[];
7
+ };
@@ -0,0 +1,18 @@
1
+ import unfetch from 'isomorphic-unfetch';
2
+ export function post(url, body) {
3
+ return unfetch(url, {
4
+ method: 'POST',
5
+ headers: {
6
+ 'Content-Type': 'application/json',
7
+ },
8
+ body: JSON.stringify(body),
9
+ }).then((r) => r.json());
10
+ }
11
+ export function buildRPCPostBody(method, params) {
12
+ return {
13
+ jsonrpc: '2.0',
14
+ id: 1,
15
+ method,
16
+ params,
17
+ };
18
+ }
@@ -0,0 +1 @@
1
+ export declare function hexToDecimal(hex: string): string;
@@ -0,0 +1,3 @@
1
+ export function hexToDecimal(hex) {
2
+ return BigInt(hex).toString();
3
+ }
@@ -1,6 +1,5 @@
1
1
  import Big from 'big.js';
2
- export declare class TinyBig {
3
- __value: Big;
2
+ export declare class TinyBig extends Big {
4
3
  constructor(value: number | string);
5
4
  toNumber(): number;
6
5
  toString(): string;
@@ -1,14 +1,17 @@
1
1
  import Big from 'big.js';
2
2
  import { scientificStrToDecimalStr } from './helpers';
3
- export class TinyBig {
3
+ export class TinyBig extends Big {
4
4
  constructor(value) {
5
- this.__value = Big(value);
5
+ super(value);
6
6
  }
7
7
  toNumber() {
8
- return Number(scientificStrToDecimalStr(this.__value.toString()));
8
+ return Number(scientificStrToDecimalStr(super.toString()));
9
9
  }
10
10
  toString() {
11
- return scientificStrToDecimalStr(this.__value.toString());
11
+ if (this.toNumber() === 0) {
12
+ return '0';
13
+ }
14
+ return scientificStrToDecimalStr(super.toString());
12
15
  }
13
16
  }
14
17
  export function tinyBig(value) {
@@ -1,15 +1,21 @@
1
- import createKeccakHash from 'keccak';
1
+ import { Keccak } from 'sha3';
2
+ import { validateType } from './shared/validate-type';
2
3
  export function toChecksumAddress(address) {
3
- address = address.toLowerCase().replace('0x', '');
4
- const hash = createKeccakHash('keccak256').update(address).digest('hex');
5
- let ret = '0x';
4
+ validateType(address, ['string']);
5
+ if (!/^(0x)?[0-9a-f]{40}$/i.test(address)) {
6
+ throw new Error(`Invalid Ethereum address "${address}"`);
7
+ }
8
+ address = address.toLowerCase().replace(/^0x/i, '');
9
+ const keccak = new Keccak(256);
10
+ const addressHash = keccak.update(address).digest('hex').replace(/^0x/i, '');
11
+ let checksumAddress = '0x';
6
12
  for (let i = 0; i < address.length; i++) {
7
- if (parseInt(hash[i], 16) >= 8) {
8
- ret += address[i].toUpperCase();
13
+ if (parseInt(addressHash[i], 16) > 7) {
14
+ checksumAddress += address[i].toUpperCase();
9
15
  }
10
16
  else {
11
- ret += address[i];
17
+ checksumAddress += address[i];
12
18
  }
13
19
  }
14
- return ret;
20
+ return checksumAddress;
15
21
  }
@@ -0,0 +1,47 @@
1
+ import { RPCTransaction, Transaction } from './transaction.types';
2
+ export interface Block {
3
+ baseFeePerGas: string;
4
+ difficulty: number;
5
+ extraData: string;
6
+ gasLimit: number;
7
+ gasUsed: number;
8
+ hash: string;
9
+ logsBloom: string;
10
+ miner: string;
11
+ mixHash: string;
12
+ nonce: string;
13
+ number: number;
14
+ parentHash: string;
15
+ receiptsRoot: string;
16
+ sha3Uncles: string;
17
+ size: number;
18
+ stateRoot: string;
19
+ timestamp: number;
20
+ totalDifficulty: number;
21
+ transactions: string[] | Transaction[];
22
+ transactionsRoot: string;
23
+ uncles: unknown[];
24
+ }
25
+ export interface RPCBlock {
26
+ baseFeePerGas: string;
27
+ difficulty: string;
28
+ extraData: string;
29
+ gasLimit: string;
30
+ gasUsed: string;
31
+ hash: string;
32
+ logsBloom: string;
33
+ miner: string;
34
+ mixHash: string;
35
+ nonce: string;
36
+ number: string;
37
+ parentHash: string;
38
+ receiptsRoot: string;
39
+ sha3Uncles: string;
40
+ size: string;
41
+ stateRoot: string;
42
+ timestamp: string;
43
+ totalDifficulty: string;
44
+ transactions: Array<string> | Array<RPCTransaction>;
45
+ transactionsRoot: string;
46
+ uncles: unknown[];
47
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,34 @@
1
+ export interface Transaction {
2
+ blockHash: string;
3
+ blockNumber: number;
4
+ from: string;
5
+ gas: number;
6
+ gasPrice: string;
7
+ hash: string;
8
+ input: string;
9
+ nonce: number;
10
+ r: string;
11
+ s: string;
12
+ to: string;
13
+ transactionIndex: number;
14
+ type: number;
15
+ v: string;
16
+ value: string;
17
+ }
18
+ export interface RPCTransaction {
19
+ blockHash: string;
20
+ blockNumber: string;
21
+ from: string;
22
+ gas: string;
23
+ gasPrice: string;
24
+ hash: string;
25
+ input: string;
26
+ nonce: string;
27
+ r: string;
28
+ s: string;
29
+ to: string;
30
+ transactionIndex: string;
31
+ type: string;
32
+ v: string;
33
+ value: string;
34
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "essential-eth",
3
3
  "description": "Ultralight JS library for Ethereum utilities",
4
- "version": "0.1.1",
4
+ "version": "0.2.0",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,
7
7
  "main": "./lib/cjs/index.js",
@@ -9,44 +9,60 @@
9
9
  "files": [
10
10
  "lib/"
11
11
  ],
12
+ "bugs": {
13
+ "url": "https://github.com/dawsbot/essential-eth/issues"
14
+ },
15
+ "repository": "https://github.com/dawsbot/essential-eth.git",
16
+ "author": "@dawsbot",
12
17
  "scripts": {
13
- "test": "npm-run-all --parallel jest tsc lint",
18
+ "test": "npm-run-all --parallel jest compile lint",
14
19
  "lint": "eslint .",
15
- "tsc": "npm-run-all --parallel tsc:esm tsc:cjs",
20
+ "compile": "npm-run-all --parallel tsc:esm tsc:cjs",
16
21
  "tsc:esm": "tsc -p tsconfig.json",
17
22
  "tsc:cjs": "tsc -p tsconfig-cjs.json",
18
- "build": "rm -rf lib && tsc",
19
- "prepublishOnly": "npm run build && npm-run-all build:website build:website:new-version",
23
+ "build": "rm -rf lib && npm run compile",
24
+ "prepublishOnly": "npm run build && npm run build:website && npm run build:website:new-version",
20
25
  "jest": "jest",
21
- "build:website": "typedoc --options typedoc/options.js",
26
+ "build:website": "sh scripts/build-website.sh",
22
27
  "build:website:new-version": "typedoc --options typedoc/options-new-version.js"
23
28
  },
24
29
  "devDependencies": {
25
30
  "@ethersproject/keccak256": "^5.4.0",
26
31
  "@types/big.js": "^6.1.2",
32
+ "@types/body-parser": "^1.19.1",
33
+ "@types/eslint": "^7.28.0",
34
+ "@types/express": "^4.17.13",
27
35
  "@types/jest": "^27.0.1",
28
- "@types/keccak": "^3.0.1",
29
- "@types/node": "^16.9.1",
30
- "@typescript-eslint/eslint-plugin": "^4.31.0",
31
- "@typescript-eslint/parser": "^4.31.0",
36
+ "@types/jest-dev-server": "^5.0.0",
37
+ "@types/node": "^16.9.2",
38
+ "@types/prettier": "^2.3.2",
39
+ "@types/supertest": "^2.0.11",
40
+ "@typescript-eslint/eslint-plugin": "^4.31.1",
41
+ "@typescript-eslint/parser": "^4.31.1",
42
+ "body-parser": "^1.19.0",
32
43
  "eslint": "^7.32.0",
33
- "eslint-plugin-jest": "^24.4.0",
34
- "ethers": "^5.4.6",
44
+ "eslint-plugin-jest": "^24.4.2",
45
+ "ethers": "^5.4.7",
46
+ "express": "^4.17.1",
35
47
  "husky": "^4.3.0",
36
- "jest": "^27.1.1",
48
+ "jest": "^27.2.0",
49
+ "jest-dev-server": "^5.0.3",
50
+ "just-omit": "^1.2.0",
37
51
  "lint-staged": "^11.1.2",
38
52
  "npm-run-all": "^4.1.5",
39
- "prettier": "^2.4.0",
53
+ "prettier": "^2.4.1",
40
54
  "prettier-plugin-organize-imports": "^2.3.3",
55
+ "supertest": "^6.1.6",
41
56
  "ts-jest": "^27.0.5",
42
57
  "ts-node": "^10.2.1",
43
- "typedoc": "^0.22.2",
58
+ "typedoc": "^0.22.3",
44
59
  "typescript": "^4.4.3",
45
60
  "web3": "^1.5.2"
46
61
  },
47
62
  "dependencies": {
48
63
  "big.js": "^6.1.1",
49
- "keccak": "^3.0.2"
64
+ "isomorphic-unfetch": "^3.1.0",
65
+ "sha3": "^2.1.4"
50
66
  },
51
67
  "husky": {
52
68
  "hooks": {
package/readme.md CHANGED
@@ -1,4 +1,24 @@
1
- # Essential Eth
1
+ <p align="center">
2
+ <a><img src="https://blog.ethereum.org/img/2018/08/grants_eth_logo.png" title="Ethereum triangle" height="300"/></a>
3
+ </p>
4
+ <p align="center">
5
+ <b>
6
+ Essential Eth
7
+ </b>
8
+ <br>
9
+ <i>Ultralight Ethereum utilities for JS and TS</i>
10
+ <br>
11
+ </p>
12
+
13
+ ---
14
+
15
+ <p align="center">
16
+ <img src="https://user-images.githubusercontent.com/3408480/133322814-f3d18424-4ba8-4a37-8cbc-c5e6828354a3.png" title="Ethereum triangle" width="900"/>
17
+ </p>
18
+
19
+ ---
20
+
21
+ <br>
2
22
 
3
23
  ![](https://badgen.net/bundlephobia/minzip/essential-eth) ![](https://badgen.net/bundlephobia/tree-shaking/essential-eth)
4
24
 
@@ -6,10 +26,77 @@
6
26
  ![](https://badgen.net/bundlephobia/min/essential-eth)
7
27
  ![](https://badgen.net/bundlephobia/dependency-count/essential-eth)
8
28
 
29
+ ๐Ÿ‘จ๐Ÿปโ€๐Ÿ’ป Breaking changes will exist between minor versions until `1.0.0` (Versions go `major.minor.patch`)
30
+
9
31
  ## Features
10
32
 
11
33
  - โšก๏ธ A replacement for the utils in web3.js and ethers.js
12
34
  - ๐ŸŽ [The TINIEST code size possible](https://bundlephobia.com/package/essential-eth)
13
- - สฆ Fully typed with TypeScript
35
+ - สฆ Fully typed with TypeScript (also works with JavaScript)
14
36
  - ๐ŸŒฒ Tree-shaking and no side-effects
37
+ - ๐Ÿงช Tested heavily to match both web3 and ethers.js
15
38
  - ๐Ÿ‘ฉโ€โš–๏ธ MIT License
39
+
40
+ ## Install
41
+
42
+ ```sh
43
+ npm install --save essential-eth # TypeScript types load automatically
44
+
45
+ # or if you prefer yarn
46
+ yarn add essential-eth # TypeScript types load automatically
47
+ ```
48
+
49
+ ## Utils (do not require connecting to an Eth node)
50
+
51
+ ```typescript
52
+ import { etherToWei } from 'essential-eth';
53
+
54
+ // or in a non-import environment
55
+ const { etherToWei } = require('essential-eth');
56
+ ```
57
+
58
+ #### `etherToWei`
59
+
60
+ ```typescript
61
+ // convert ether to wei
62
+ etherToWei(etherQuantity: string | number): TinyBig
63
+ ```
64
+
65
+ #### `weiToEther`
66
+
67
+ ```typescript
68
+ // convert wei to ether
69
+ weiToEther(weiQuantity: string | number): TinyBig
70
+ ```
71
+
72
+ #### `toChecksumAddress`
73
+
74
+ ```typescript
75
+ // return proper mixed-case address
76
+ toChecksumAddress(address: string): string
77
+ ```
78
+
79
+ ## RPC
80
+
81
+ ```typescript
82
+ import { EssentialEth } from 'essential-eth';
83
+ const essentialEth = new EssentialEth('RPC URL HERE' /* Try POKT or Infura */);
84
+ // OR for very quick testing (limited to 500 requests)
85
+ const essentialEth = new EssentialEth();
86
+ ```
87
+
88
+ #### `getBlock`
89
+
90
+ Returns a [Block](src/types/block.types.ts)
91
+
92
+ ```typescript
93
+ // Same API as web3.eth.getBlock
94
+ getBlock(timeFrame: number | "latest" | "earliest" | "pending", returnTransactionObjects?: boolean): Promise<Block>
95
+ ```
96
+
97
+ <br/>
98
+ <br/>
99
+
100
+ - [๐Ÿ““ View full docs](https://essential-eth.vercel.app)
101
+ - [๐Ÿ““ View changelog (by looking at releases diff)](https://github.com/dawsbot/essential-eth/releases)
102
+ - [๐Ÿ““ View docs for an older version](https://essential-eth.vercel.app/versions)