@bitpay-labs/bitcore-wallet-service 11.5.2 → 11.6.2

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 (36) hide show
  1. package/package.json +4 -4
  2. package/src/externalservices/coingecko.ts +448 -368
  3. package/src/lib/common/utils.ts +37 -32
  4. package/src/lib/tss.ts +18 -10
  5. package/test/integration/externalservices/coinGecko.test.ts +811 -156
  6. package/test/utils.test.ts +5 -0
  7. package/ts_build/package.json +3 -3
  8. package/ts_build/src/externalservices/coingecko.d.ts +24 -20
  9. package/ts_build/src/externalservices/coingecko.d.ts.map +1 -1
  10. package/ts_build/src/externalservices/coingecko.js +356 -306
  11. package/ts_build/src/externalservices/coingecko.js.map +1 -1
  12. package/ts_build/src/lib/common/index.d.ts +2 -2
  13. package/ts_build/src/lib/common/utils.d.ts +2 -2
  14. package/ts_build/src/lib/common/utils.d.ts.map +1 -1
  15. package/ts_build/src/lib/common/utils.js +28 -29
  16. package/ts_build/src/lib/common/utils.js.map +1 -1
  17. package/ts_build/src/lib/tss.d.ts.map +1 -1
  18. package/ts_build/src/lib/tss.js +2 -10
  19. package/ts_build/src/lib/tss.js.map +1 -1
  20. package/ts_build/test/integration/externalservices/coinGecko.test.d.ts +1 -1
  21. package/ts_build/test/integration/externalservices/coinGecko.test.d.ts.map +1 -1
  22. package/ts_build/test/integration/externalservices/coinGecko.test.js +710 -149
  23. package/ts_build/test/integration/externalservices/coinGecko.test.js.map +1 -1
  24. package/ts_build/test/utils.test.js +4 -0
  25. package/ts_build/test/utils.test.js.map +1 -1
  26. package/scripts/delme.ts +0 -468
  27. package/scripts/findEmail.js +0 -32
  28. package/scripts/getSolStats2.js +0 -81
  29. package/scripts/walletStats.js +0 -290
  30. package/src/types/emailservice.d.ts +0 -11
  31. package/src/types/notifications.d.ts +0 -8
  32. package/src/types/pushnotificationservice.d.ts +0 -51
  33. package/ts_build/scripts/delme.d.ts +0 -2
  34. package/ts_build/scripts/delme.d.ts.map +0 -1
  35. package/ts_build/scripts/delme.js +0 -453
  36. package/ts_build/scripts/delme.js.map +0 -1
@@ -1,290 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from 'fs';
4
- import os from 'os';
5
- import readline from 'readline';
6
- import * as CWC from '@bitpay-labs/crypto-wallet-core';
7
- import Moralis from 'moralis';
8
- import request from 'request-promise-native';
9
- import { Storage } from '../../ts_build/src';
10
- import config from '../../ts_build/src/config';
11
- import { WalletService } from '../../ts_build/src/lib/server';
12
-
13
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
14
-
15
- let shuttingDown = false;
16
- process.on('SIGINT', function() {
17
- if (shuttingDown) {
18
- console.log('Forced exit');
19
- process.exit(1);
20
- }
21
- shuttingDown = true;
22
- });
23
-
24
- function usage(errMsg) {
25
- console.log('USAGE: ./walletStats.js [options]');
26
- console.log('OPTIONS:');
27
- console.log(' --start <value> Start month (MM/YYYY) (default: last month)');
28
- console.log(' --end <value> End month (MM/YYYY) - inclusive (default: last month)');
29
- console.log(' --chain <value> Chain (default: all)');
30
- console.log(' --network <value> Network (default: livenet)');
31
- console.log(' --out <value> Output file (default: stats-<date>.json)');
32
- console.log(' --config Only change the sleep config file (walletStats.config.json) and exit');
33
- console.log(' --sleep <value> Sleep time in milliseconds between iterations. Default: 250');
34
- console.log(' --every <value> Sleep for --sleep milliseconds every --every loop iteration. Default: 100');
35
- console.log(' ');
36
- if (errMsg) {
37
- console.log('\nERROR: ' + errMsg);
38
- }
39
- process.exit();
40
- };
41
-
42
- const args = process.argv.slice(2);
43
-
44
- if (args.includes('--help') || args.includes('-h')) {
45
- usage();
46
- }
47
-
48
-
49
- const sleepIdx = args.indexOf('--sleep');
50
- let sleepMs = sleepIdx > -1 ? parseInt(args[sleepIdx + 1]) : 250;
51
- const everyIdx = args.indexOf('--every');
52
- let nSleep = everyIdx > -1 ? parseInt(args[everyIdx + 1]) : 100;
53
- fs.writeFileSync('./walletStats.config.json', JSON.stringify({ sleepMs, nSleep }, null, 2));
54
- if (args.includes('--config')) {
55
- console.log('Config updated.');
56
- process.exit(0);
57
- }
58
-
59
-
60
- const yestermonth = new Date();
61
- yestermonth.setUTCMonth(yestermonth.getUTCMonth() - 1); // Default to last month
62
- const lastMonth = (yestermonth.getUTCMonth() + 1).toString().padStart(2, '0');
63
- const year = yestermonth.getUTCFullYear();
64
-
65
- const startIdx = args.indexOf('--start');
66
- if (startIdx > -1 && (!args[startIdx + 1] || !args[startIdx + 1].match(/^(0[1-9]|1[0-2])\/20[0-9]{2}$/))) {
67
- usage('Invalid start date format. Use MM/YYYY');
68
- }
69
- const start = startIdx > -1 ? args[startIdx + 1] : `${lastMonth}/${year}`;
70
-
71
- const endIdx = args.indexOf('--end');
72
- if (endIdx > -1 && (!args[endIdx + 1] || !args[endIdx + 1].match(/^(0[1-9]|1[0-2])\/20[0-9]{2}$/))) {
73
- usage('Invalid end date format. Use MM/YYYY');
74
- }
75
- const end = endIdx > -1 ? args[endIdx + 1] : `${lastMonth}/${year}`;
76
-
77
- const chainIdx = args.indexOf('--chain');
78
- const chain = (chainIdx > -1 && args[chainIdx + 1]?.toLowerCase()) || null;
79
-
80
- const networkIdx = args.indexOf('--network');
81
- const network = (networkIdx > -1 && args[networkIdx + 1]?.toLowerCase()) || 'livenet';
82
-
83
- const outIdx = args.indexOf('--out');
84
- let outFile = (outIdx > -1 && args[outIdx + 1]) || `stats-${new Date().toISOString()}.json`;
85
-
86
- if (outFile.startsWith('~')) {
87
- outFile = outFile.replace('~', os.homedir());
88
- }
89
- if (outFile.startsWith('$HOME')) {
90
- outFile = outFile.replace('$HOME', os.homedir());
91
- }
92
- if (!outFile.startsWith('/') && !outFile.startsWith('./') && !outFile.startsWith('../')) {
93
- outFile = __dirname + '/' + outFile;
94
- }
95
-
96
- const tokenChainMap = {
97
- WBTC: 'btc',
98
- WETH: 'eth',
99
- MATIC: 'matic'
100
- };
101
-
102
- const storage = new Storage();
103
- storage.connect(config.storageOpts, async (err) => {
104
- if (err) {
105
- console.log(err);
106
- return;
107
- }
108
- await new Promise((r, j) => WalletService.initialize(
109
- {
110
- ...config,
111
- storage,
112
- messageBroker: { onMessage: () => {} },
113
- fiatRateService: {}
114
- },
115
- (err) => {
116
- if (err) return j(err);
117
- return r();
118
- }
119
- ));
120
- const walletService = new WalletService();
121
-
122
- function done(err) {
123
- if (err) { console.log(err); }
124
- rl.close();
125
- WalletService.shutDown((err) => {
126
- if (err) { console.log(err); }
127
- fs.rmSync('./walletStats.config.json');
128
- console.log('done');
129
- });
130
- // storage.disconnect(() => { console.log('done'); });
131
- }
132
-
133
- try {
134
- // await Moralis.start({
135
- // apiKey: config.moralis.apiKey
136
- // });
137
- // Get all wallets
138
- const walletCnt = await storage.db.collection(Storage.collections.WALLETS).count({});
139
- const walletStream = storage.db.collection(Storage.collections.WALLETS).find({});
140
-
141
- console.log(` Found ${Intl.NumberFormat().format(walletCnt)} total wallets to scan`);
142
- console.log(` Output file: ${outFile}`);
143
- const ans = await new Promise(r => rl.question('Would you like to continue? (Y/n): ', r));
144
- if (ans?.toLowerCase() === 'n') {
145
- return done('Good bye.');
146
- }
147
-
148
- const retval = {};
149
- let count = 0;
150
- let relevantWallets = 0;
151
- let perfTime = Date.now();
152
- let perfCnt = 0;
153
-
154
-
155
- for await (const wallet of walletStream) {
156
- if (shuttingDown) {
157
- throw new Error('Interrupted by user');
158
- }
159
-
160
- count++;
161
- if (count % nSleep === 0) {
162
- const cntDiff = count - perfCnt;
163
- const timeDiff = Date.now() - perfTime;
164
- const rate = (cntDiff / timeDiff * 1000).toFixed(2); // wallets per second
165
- process.stdout.write(`Processed ${(count / walletCnt * 100).toFixed(4)}% wallets (${count} | ${relevantWallets}) - ${rate} wallets/sec\r`); // shows how fast things are working
166
- await new Promise(resolve => setTimeout(resolve, sleepMs)); // cooldown
167
- ({ nSleep, sleepMs } = JSON.parse(fs.readFileSync('./walletStats.config.json', 'utf8'))); // reload config
168
- perfTime = Date.now();
169
- perfCnt = count;
170
- }
171
-
172
- const wChain = wallet.chain || wallet.coin || 'btc';
173
- const [smonth, syear] = start.split('/');
174
- const startDate = new Date(`${syear}-${smonth}-01T00:00:00Z`);
175
-
176
-
177
- if (wallet.status !== 'complete') continue; // skip incomplete wallets
178
- if (!wallet.beAuthPrivateKey2) continue; // skip too old wallets
179
- if (chain && (
180
- (wallet.chain?.toLowerCase() !== chain && wallet.coin?.toLowerCase() !== chain) ||
181
- (!wallet.coin && chain !== 'btc') // legacy wallets default to btc
182
- )) continue; // skip non-matching chain
183
- if (wallet.network?.toLowerCase() !== network) continue;
184
-
185
- relevantWallets++;
186
-
187
- const [emonth, eyear] = end.split('/');
188
- const endDate = new Date(`${eyear}-${emonth}-01T00:00:00Z`);
189
-
190
- const tokenOpts = CWC.Constants[`${wChain.toUpperCase()}_TOKEN_OPTS`];
191
- const dateKey = startDate.toISOString().split('T')[0];
192
- if (!retval[dateKey]) {
193
- retval[dateKey] = {};
194
- }
195
- if (!retval[dateKey][wChain]) {
196
- retval[dateKey][wChain] = { wallets: 0n, totalBalance: 0n };
197
- }
198
-
199
- try {
200
- const bc = walletService._getBlockchainExplorer(wChain, wallet.network);
201
- const client = bc._getAuthClient(wallet);
202
- // todo: is there a quick check to see if the wallet has _any_ activity?
203
- while (startDate <= endDate) {
204
- let balance = 0;
205
- if (['btc', 'bch', 'ltc', 'doge', 'xrp'].includes(wChain)) {
206
- const query = '';
207
- const apiUrl = `${client.baseUrl}/wallet/${wallet.beAuthPublicKey2}/balance/${startDate.toISOString()}`;
208
- const url = apiUrl + query;
209
- const signature = client.sign({ method: 'GET', url });
210
- const response = await request.get(url, {
211
- headers: { 'x-signature': signature },
212
- json: true
213
- });
214
-
215
- if (!response.balance) {
216
- startDate.setUTCMonth(startDate.getUTCMonth() + 1);
217
- continue;
218
- }
219
- balance = response.balance;
220
- } else if (wChain === 'sol') {
221
- // todo
222
- continue;
223
- } else { // EVM
224
- const CHAIN_IDS = CWC.Constants.EVM_CHAIN_NETWORK_TO_CHAIN_ID;
225
- const chainKey = `${wChain.toUpperCase()}_${wallet.network === 'livenet' ? 'mainnet' : wallet.network}`;
226
- if (!CHAIN_IDS[chainKey]) {
227
- throw new Error(`Unsupported chain/network: ${chainKey}`);
228
- }
229
- const chainId = CHAIN_IDS[chainKey];
230
-
231
- const addresses = await storage.db.collection(Storage.collections.ADDRESSES).find({ walletId: wallet.id, createdOn: { $exists: true } }).toArray();
232
- if (!addresses[0]) {
233
- break; // no addresses, skip
234
- }
235
-
236
- const blkResponse = await Moralis.EvmApi.block.getDateToBlock({
237
- chain: chainId,
238
- date: startDate.toISOString()
239
- });
240
-
241
- const balResponse = await Moralis.EvmApi.wallets.getWalletTokenBalancesPrice({
242
- chain: chainId,
243
- toBlock: blkResponse.raw.block,
244
- excludeSpam: true,
245
- address: addresses[0].address // assume first address is representative of whole wallet
246
- });
247
-
248
- for (const token of balResponse.json.result) {
249
- if (token.native_token) {
250
- balance = BigInt(token.balance);
251
- } else {
252
- const tokenOpt = tokenOpts[token.token_address.toLowerCase()];
253
- const tChain = tokenChainMap[tokenOpt?.symbol];
254
- if (tChain) {
255
- retval[dateKey][tChain] = retval[dateKey][tChain] || { wallets: 0n, totalBalance: 0n };
256
- retval[dateKey][tChain].wallets++;
257
- retval[dateKey][tChain].totalBalance += BigInt(token.balance);
258
- } else {
259
- // record unknown/stablecoin token's USD values
260
- if (!retval[dateKey]['USD']) {
261
- retval[dateKey]['USD'] = { wallets: 0n, totalBalance: 0n };
262
- }
263
- retval[dateKey]['USD'].wallets++;
264
- retval[dateKey]['USD'].totalBalance += BigInt(Math.round(token.usd_value));
265
- }
266
- }
267
- }
268
- }
269
-
270
- retval[dateKey][wChain].wallets++;
271
- retval[dateKey][wChain].totalBalance += BigInt(balance);
272
-
273
- startDate.setUTCMonth(startDate.getUTCMonth() + 1);
274
- }
275
-
276
- fs.writeFileSync(outFile, JSON.stringify(retval, (k, v) => typeof v === 'bigint' ? v.toString() : v, 2));
277
- } catch (e) {
278
- console.log(`\nError fetching data for wallet ${wallet.id} (${wChain}/${wallet.network}): ${e.stack}`);
279
- }
280
- }
281
-
282
- process.stdout.write('\n');
283
-
284
- console.log(`Wrote stats for ${relevantWallets} wallets to ${outFile}`);
285
-
286
- return done();
287
- } catch (err) {
288
- return done(err);
289
- }
290
- });
@@ -1,11 +0,0 @@
1
- import type { INotificationRecipient } from './notifications';
2
-
3
- export interface IRecipient extends INotificationRecipient {
4
- emailAddress: string;
5
- }
6
-
7
- export interface IEmailNotificationType {
8
- filename: string;
9
- notifyDoer: boolean;
10
- notifyOthers: boolean;
11
- }
@@ -1,8 +0,0 @@
1
- export interface INotificationRecipient {
2
- copayerId: string;
3
- language: string;
4
- unit: string;
5
- }
6
-
7
- export type FormatType = 'html' | 'plain';
8
- export type Extension = '.html' | '.plain';
@@ -1,51 +0,0 @@
1
- import type { FormatType, INotificationRecipient } from './notifications';
2
- // import type { INotificationData } from 'src/lib/model/notification';
3
- type INotificationData = any;
4
- export interface IPushNotificationType {
5
- filename?: string | string[];
6
- dataOnly?: boolean;
7
- broadcastToActiveUsers?: boolean;
8
- }
9
-
10
- export interface IPushNotificationService {
11
- templatePath: string;
12
- defaultLanguage: string;
13
- defaultUnit: string;
14
- subjectPrefix: string;
15
- pushServerUrl: string;
16
- pushServerUrlBraze: string;
17
- availableLanguages: string[];
18
- authorizationKey: string;
19
- authorizationKeyBraze: string;
20
- messageBroker: any;
21
- }
22
-
23
- export interface IRecipient extends INotificationRecipient {
24
- walletId: string;
25
- }
26
-
27
- export interface ITemplate {
28
- subject: string;
29
- body: string;
30
- }
31
-
32
- export interface IContents {
33
- [language: string]: {
34
- [key in FormatType]?: ITemplate;
35
- };
36
- }
37
-
38
- export interface INotifTemplateData extends INotificationData {
39
- subjectPrefix?: string;
40
- networkStr?: string;
41
- rejectorsNames?: string;
42
- walletId?: string;
43
- walletName?: string;
44
- walletM?: number;
45
- walletN?: number;
46
- copayerId?: string;
47
- copayerName?: string;
48
- rejectedBy?: string[];
49
- rejectorNames?: string;
50
- address?: string | { coin: string };
51
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=delme.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"delme.d.ts","sourceRoot":"","sources":["../../scripts/delme.ts"],"names":[],"mappings":""}