uniswap-v2-loader 1.5.0 → 2.0.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.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const { all, count, clear_cache } = require('../index')
2
+ const { load, count, clear_cache } = require('../index')
3
3
  const rl = require('readline')
4
4
 
5
5
  const progress = (c, t) => {
@@ -16,4 +16,4 @@ if (process.argv[2] == '-c' || process.argv[2] == '--count')
16
16
  else if (process.argv[2] == '--clear')
17
17
  clear_cache()
18
18
  else
19
- all({progress})
19
+ load({progress})
package/index.js CHANGED
@@ -4,19 +4,30 @@ const os = require('os')
4
4
  const path = require('path')
5
5
  const { parseAbiItem, createPublicClient, http } = require('viem')
6
6
  const { mainnet } = require('viem/chains')
7
- const default_filename = require('./default_cache_filename')
8
- const workers = os.cpus().length - 1
9
- const missed = Array(workers).fill(null).map(() => [])
10
- const key = process.env.KEY || 'FZBvlPrOxtgaKBBkry3SH0W1IqH4Y5tu'
11
- const factory = '0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f'
12
- const client = createPublicClient({
13
- chain: mainnet,
14
- transport: http('https://eth-mainnet.g.alchemy.com/v2/' + key)
15
- })
7
+ const default_cache_filename = require('./default_cache_filename')
8
+ const max_workers = os.cpus().length - 1
9
+ const debug_key = process.env.KEY || 'FZBvlPrOxtgaKBBkry3SH0W1IqH4Y5tu'
10
+ const uniswap_v2_factory = '0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f'
16
11
 
17
- const load = params => {
18
- const {filename = default_filename, to, from = 0, multicall_size = 50, progress, count, multicore = true} = params
19
- const pairs = params.pairs || fs.existsSync(filename)
12
+ const load = (params = {}) => {
13
+ var {
14
+ key = debug_key,
15
+ factory = uniswap_v2_factory,
16
+ filename = default_cache_filename,
17
+ multicall_size = 50,
18
+ from = 0,
19
+ to,
20
+ progress,
21
+ count,
22
+ workers = max_workers,
23
+ pairs,
24
+ } = params
25
+ const client = createPublicClient({
26
+ chain: mainnet,
27
+ transport: http('https://eth-mainnet.g.alchemy.com/v2/' + key)
28
+ })
29
+
30
+ pairs ??= fs.existsSync(filename)
20
31
  ? fs.readFileSync(filename).toString().trim().split('\n')
21
32
  .reduce((pairs, line) => {
22
33
  line = line.split(',')
@@ -52,8 +63,6 @@ const load = params => {
52
63
  : 0
53
64
  var progress_i = 0
54
65
  const progress_end = all_pairs_length - start_loading_from
55
-
56
- missed.forEach(_ => _.length = 0)
57
66
 
58
67
  const onpair = pair => {
59
68
  pairs[pair.id] = pair
@@ -67,18 +76,23 @@ const load = params => {
67
76
  }
68
77
  }
69
78
 
70
- if (workers == 0 || multicore == false) {
79
+ if (!workers) {
71
80
  const ids = []
72
81
  for (var i = start_loading_from; i < all_pairs_length; i++)
73
82
  ids.push(i)
74
83
  return require('./loader')({ ids, factory, key, multicall_size }, onpair)
75
84
 
76
85
  }
77
- for (var i = start_loading_from, rr = 0; i < all_pairs_length; i++) {
78
- missed[rr].push(i)
79
- if (missed[rr].length % multicall_size == 0)
80
- rr = (rr + 1) % workers
86
+
87
+ const missed = []
88
+ for (var i = start_loading_from, ids; i < all_pairs_length; i++) {
89
+ if (!ids || ids.length % multicall_size == 0) {
90
+ ids = []
91
+ missed.push(ids)
92
+ }
93
+ ids.push(i)
81
94
  }
95
+
82
96
  cluster.setupPrimary({ exec: path.join(__dirname, 'loader.js') })
83
97
 
84
98
  return Promise.all(
@@ -95,14 +109,16 @@ const load = params => {
95
109
  }
96
110
 
97
111
 
98
- module.exports.clear_cache = () =>
99
- fs.unlinkSync(default_filename)
112
+ module.exports.clear_cache = () => {
113
+ if (fs.existsSync(default_cache_filename))
114
+ fs.unlinkSync(default_cache_filename)
115
+ }
100
116
 
101
- module.exports.all = (params = {}) =>
117
+ module.exports.load = (params = {}) =>
102
118
  load(params)
103
119
 
104
- module.exports.count = () =>
105
- load({count: true})
120
+ module.exports.count = (params = {}) =>
121
+ load({count: true, ...params})
106
122
 
107
123
  module.exports.onupdate = function onupdate(callback, params = {}) {
108
124
  params.update_timeout ??= 5000
@@ -134,4 +150,4 @@ module.exports.onupdate = function onupdate(callback, params = {}) {
134
150
  subscribe = false
135
151
  if (timeout) clearTimeout(timeout)
136
152
  }
137
- }
153
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uniswap-v2-loader",
3
- "version": "1.5.0",
3
+ "version": "2.0.0",
4
4
  "description": "Uniswap v2 protocol loader",
5
5
  "keywords": [
6
6
  "uniswap-v2",
@@ -9,13 +9,13 @@
9
9
  "crypto",
10
10
  "ethereum"
11
11
  ],
12
- "homepage": "https://github.com/calp-pro/uniswap-v2#readme",
12
+ "homepage": "https://github.com/calp-pro/uniswap-v2-loader#readme",
13
13
  "bugs": {
14
- "url": "https://github.com/calp-pro/uniswap-v2/issues"
14
+ "url": "https://github.com/calp-pro/uniswap-v2-loader/issues"
15
15
  },
16
16
  "repository": {
17
17
  "type": "git",
18
- "url": "git+https://github.com/calp-pro/uniswap-v2.git"
18
+ "url": "git+https://github.com/calp-pro/uniswap-v2-loader.git"
19
19
  },
20
20
  "license": "MIT",
21
21
  "author": "Vladimir Spirin (spirin.vladimir@gmail.com)",
package/test.js CHANGED
@@ -1,54 +1,67 @@
1
1
  const fs = require('fs')
2
- const { test } = require('node:test')
2
+ const { describe, before, it } = require('node:test')
3
3
  const assert = require('node:assert/strict')
4
- const uniswap_v2_loader = require('./index')
4
+ const {clear_cache, load, onupdate} = require('./index')
5
5
 
6
- test('Exist USDC/USDP pair', () =>
7
- uniswap_v2_loader.all({to: 14})
8
- .then(pairs => {
9
- assert.equal(pairs.length, 14)
10
- const i = pairs.findIndex(({id}) => id == 1)
11
- assert.ok(i != -1)
12
- if (i != -1) {
13
- const {pair, token0, token1} = pairs[i]
14
- assert.equal(pair, '0x3139ffc91b99aa94da8a2dc13f1fc36f9bdc98ee')
15
- assert.equal(token0, '0x8e870d67f660d95d5be530380d0ec0bd388289e1')
16
- assert.equal(token1, '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48')
17
- }
6
+ describe('Uniswap V2', () => {
7
+ before(() => clear_cache())
8
+
9
+ it('Exist USDC/USDP pair', () =>
10
+ load({to: 2})
11
+ .then(pairs => {
12
+ assert.equal(pairs.length, 2)
13
+ const i = pairs.findIndex(({id}) => id == 1)
14
+ assert.ok(i != -1)
15
+ if (i != -1) {
16
+ const {pair, token0, token1} = pairs[i]
17
+ assert.equal(pair, '0x3139Ffc91B99aa94DA8A2dc13f1fC36F9BDc98eE')
18
+ assert.equal(token0, '0x8E870D67F660D95d5be530380D0eC0bd388289E1')
19
+ assert.equal(token1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48')
20
+ }
21
+ })
22
+ )
23
+
24
+
25
+ it('Re-load first two pairs to custom CSV file', () => {
26
+ // If user specify a filename then
27
+ // a cache data will be taken from
28
+ // the filename provided. If file is empty then
29
+ // data will be uploaded again from network.
30
+ const filename = Date.now() + '.csv'
31
+ return load({to: 2, filename})
32
+ .then(() => {
33
+ const lines = fs.readFileSync(filename).toString().trim().split('\n')
34
+ assert.equal(lines.length, 2)
35
+ })
36
+ .finally(() =>
37
+ fs.unlinkSync(filename)
38
+ )
18
39
  })
19
- )
20
40
 
21
- test('Load first two pairs to file', () => {
22
- const filename = Date.now() + '.csv'
23
- return uniswap_v2_loader.all({to: 2, filename})
24
- .then(() => {
25
- const lines = fs.readFileSync(filename).toString().trim().split('\n')
26
- assert.equal(lines.length, 2)
41
+ it('onupdate should call provided callback with 2 pairs for a current moment (from cache)', () => {
42
+ return new Promise(y => {
43
+ const unsubscribe = onupdate(pairs => {
44
+ assert.equal(pairs.length, 2)
45
+ unsubscribe()
46
+ y()
47
+ }, {to: 2})
48
+ })
27
49
  })
28
- .finally(() =>
29
- fs.unlinkSync(filename)
30
- )
31
- })
32
50
 
33
- test('onupdate should call provided callback with 2 pairs for a current moment (from cache)', () => {
34
- return new Promise(y => {
35
- const unsubscribe = uniswap_v2_loader.onupdate(pairs => {
36
- assert.equal(pairs.length, 2)
37
- unsubscribe()
38
- y()
39
- }, {to: 2})
40
- })
41
- })
51
+ it('Multi-core test 2 workers load 2 pools using multicall', () =>
52
+ // There are already 2 pools loaded from previous test
53
+ // 6 - 2 = 4. Rest 4 will be loaded by 2 workers. Each load 2.
54
+ // Multicall size is 2.
55
+ load({to: 6, multicall_size: 2, workers: 2 })
56
+ .then(pairs => {
57
+ assert.equal(pairs.length, 6)
58
+ })
59
+ )
42
60
 
43
- test('Heavy test load first 3000 pairs', () =>
44
- uniswap_v2_loader.all({to: 3000})
45
- .then(pairs => {
46
- assert.equal(pairs.length, 3000)
61
+ it('Each line at CSV cache file should be orderd by pair id (factory id)', () => {
62
+ const lines = fs.readFileSync(require('./default_cache_filename'), 'utf8').trim().split('\n')
63
+ for (var i = 0; i < lines.length; i++)
64
+ assert.equal(i, +lines[i].split(',').shift())
47
65
  })
48
- )
49
66
 
50
- test('Each line at CSV cache file should be orderd by pair id (factory id)', () => {
51
- const lines = fs.readFileSync(require('./default_cache_filename'), 'utf8').trim().split('\n')
52
- for (var i = 0; i < lines.length; i++)
53
- assert.equal(i, +lines[i].split(',').shift())
54
67
  })