@lunch-money/ethereum-to-lunch-money 1.4.0 → 2.0.1

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.
@@ -0,0 +1,340 @@
1
+ import { ethers } from 'ethers';
2
+ import { createEthereumWalletClient } from './client';
3
+ import fetch from 'node-fetch';
4
+ // Helper function to wrap promises around provider tests
5
+ const wrapPromise = (promise) => promise.then((result) => result, (error) => error);
6
+ class EthereumInitializationService {
7
+ integrations;
8
+ logDebug;
9
+ initialized = false;
10
+ ethereumIntegration;
11
+ constructor(integrations, logDebug) {
12
+ this.integrations = integrations;
13
+ this.logDebug = logDebug;
14
+ this.logDebug = logDebug.bind(this);
15
+ this.handleError = this.handleError.bind(this);
16
+ // TODO: this could us a little more error handling
17
+ integrations.ethereum.initialized = false;
18
+ this.ethereumIntegration = integrations.ethereum;
19
+ }
20
+ async initialize() {
21
+ if (this.initialized) {
22
+ return this.ethereumIntegration;
23
+ }
24
+ try {
25
+ await this.validateAPIKeys();
26
+ if (this.ethereumIntegration.serviceProviderInfo.length > 0) {
27
+ // Yay, we got a valid Service Provider Key!
28
+ this.ethereumIntegration.walletClient = createEthereumWalletClient(this.ethereumIntegration.serviceProviderInfo, this.ethereumIntegration.walletProviderInfo);
29
+ this.logDebug('Ethereum initialized with supplied provider(s)');
30
+ }
31
+ else {
32
+ this.ethereumIntegration.walletClient = createEthereumWalletClient();
33
+ this.logDebug('Ethereum initialized with public provider(s)');
34
+ }
35
+ this.initialized = true;
36
+ this.ethereumIntegration.initialized = true;
37
+ }
38
+ catch (error) {
39
+ const errorMessage = this.getErrorMessage(error);
40
+ console.error(`Unexpected error in Ethereum initialization: ${errorMessage}`);
41
+ throw new Error(errorMessage);
42
+ }
43
+ return this.ethereumIntegration;
44
+ }
45
+ async validateAPIKeys() {
46
+ try {
47
+ this.warnAboutLegacyKeys();
48
+ this.logDebug('Starting background testing of private providers and API keys');
49
+ // This is a well known test Ethereum wallet address
50
+ const testAddress = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2';
51
+ const missingKeyResults = [];
52
+ let wrappedProviderPromises = [];
53
+ // Prepare private provider tests
54
+ const privateProviders = this.getPrivateProviders();
55
+ if (privateProviders.length === 0) {
56
+ this.logDebug('No Ethereum service provider keys (ALCHEMY_API_KEY or INFURA_API_KEY) are set.');
57
+ missingKeyResults.push({
58
+ type: 'Service Provider',
59
+ name: 'Ethereum Service Providers',
60
+ status: 'FAILED',
61
+ error: 'Missing required Ethereum service provider keys (ALCHEMY_API_KEY or INFURA_API_KEY)',
62
+ });
63
+ }
64
+ else {
65
+ wrappedProviderPromises = privateProviders.map((provider) => wrapPromise(this.testProvider(provider, testAddress)));
66
+ }
67
+ //Prepare API Key Tests
68
+ let wrappedApiKeyPromises = [];
69
+ const apiKeys = this.getWalletTokenApiKeyTestInfo(testAddress);
70
+ if (apiKeys.length === 0) {
71
+ missingKeyResults.push({
72
+ type: 'API Provider',
73
+ name: 'API Keys',
74
+ status: 'FAILED',
75
+ error: 'Missing required wallet token API keys (ETHERSCAN_API_KEY or MORALIS_API_KEY)',
76
+ });
77
+ }
78
+ else {
79
+ wrappedApiKeyPromises = apiKeys.map((apiKeyTestInfo) => wrapPromise(this.testApiKey(apiKeyTestInfo)));
80
+ }
81
+ // Wrap any existing results in a promise
82
+ const missingKeyResultsPromise = Promise.resolve(missingKeyResults);
83
+ // Run all tests in parallel, including the results
84
+ const allResults = await Promise.all([
85
+ ...(await missingKeyResultsPromise),
86
+ ...wrappedProviderPromises,
87
+ ...wrappedApiKeyPromises,
88
+ ]);
89
+ this.processResults(allResults);
90
+ }
91
+ catch (error) {
92
+ const errorMessage = this.getErrorMessage(error);
93
+ console.error(`Unexpected error in Ethereum initialization: ${errorMessage}`);
94
+ throw new Error(errorMessage);
95
+ }
96
+ }
97
+ processResults(allResults) {
98
+ // Process Provider results
99
+ const successfulProviders = allResults.filter((result) => result.status === 'SUCCESS' && result.type === 'Service Provider');
100
+ const failedProviders = allResults.filter((result) => result.status === 'FAILED');
101
+ if (successfulProviders.length > 0) {
102
+ this.ethereumIntegration.serviceProviderInfo = successfulProviders;
103
+ if (failedProviders.length > 0) {
104
+ this.logDebug(`Secondary provider validation failed: ${failedProviders.map((p) => `${p.name}: ${p.error}`).join(', ')}`);
105
+ if (process.env.DEBUG_ETHEREUM_FAIL_ON_ERROR === 'true') {
106
+ this.logDebug('DEBUG_ETHEREUM_FAIL_ON_ERROR is set to true. Exiting...');
107
+ process.exit(1);
108
+ }
109
+ else {
110
+ const primaryProvider = this.integrations.ethereum.serviceProviderInfo[0];
111
+ this.logDebug(`Continuing with ${primaryProvider.name} as primary provider and no secondary provider.`);
112
+ }
113
+ }
114
+ // }
115
+ }
116
+ else {
117
+ if (failedProviders.length > 0) {
118
+ this.logDebug(`Provider validation failed: ${failedProviders.map((p) => `${p.name}: ${p.error}`).join(', ')}`);
119
+ if (process.env.DEBUG_ETHEREUM_FAIL_ON_ERROR === 'true') {
120
+ this.logDebug('DEBUG_ETHEREUM_FAIL_ON_ERROR is set to true. Exiting...');
121
+ process.exit(1);
122
+ }
123
+ else {
124
+ console.log('[DEBUG_ETHEREUM] Will continue with the public provider. THIS IS NOT RECOMMENDED!');
125
+ }
126
+ }
127
+ // Return here since we won't bother with API key tests if the provider tests failed
128
+ return;
129
+ }
130
+ // Process API Key test results
131
+ const successfulApiKeys = allResults.filter((result) => result.status === 'SUCCESS' && result.type === 'API Provider');
132
+ const failedApiKeys = allResults.filter((result) => result.status === 'FAILED' && result.type === 'API Provider');
133
+ if (successfulApiKeys.length === 0) {
134
+ if (failedApiKeys.length === 0) {
135
+ this.logDebug('No ETHERSCAN or MORALIS wallet API keys were provided, or all API keys failed.');
136
+ }
137
+ else {
138
+ this.logDebug(`API key validation failed: ${failedApiKeys.map((p) => `${p.name}: ${p.error}`).join(', ')}`);
139
+ }
140
+ if (process.env.DEBUG_ETHEREUM_FAIL_ON_ERROR === 'true') {
141
+ this.logDebug('DEBUG_ETHEREUM_FAIL_ON_ERROR is set to true. Exiting...');
142
+ process.exit(1);
143
+ }
144
+ else {
145
+ this.logDebug('[DEBUG_ETHEREUM] Will continue without wallet API keys. THIS MAY LEAD TO ETHEREUM SERVICE PROVIDER RATE LIMITING!');
146
+ }
147
+ }
148
+ else {
149
+ this.ethereumIntegration.walletProviderInfo = successfulApiKeys;
150
+ if (failedApiKeys.length > 0) {
151
+ this.logDebug(`API key validation failed: ${failedApiKeys.map((p) => `${p.name}: ${p.error}`).join(', ')}`);
152
+ if (process.env.DEBUG_ETHEREUM_FAIL_ON_ERROR === 'true') {
153
+ console.error('DEBUG_ETHEREUM_FAIL_ON_ERROR is set to true. Exiting...');
154
+ process.exit(1);
155
+ }
156
+ else {
157
+ this.logDebug(`Will continue using the single ${successfulApiKeys[0].name} API key with no secondary API key.`);
158
+ }
159
+ }
160
+ }
161
+ }
162
+ // Add a utility function for error handling
163
+ handleError(providerName, error, type) {
164
+ const errorMessage = this.getCleanErrorMessage(error);
165
+ this.logDebug(`${providerName} test: FAILED - ${errorMessage}`);
166
+ return {
167
+ type,
168
+ name: providerName,
169
+ status: 'FAILED',
170
+ error: errorMessage,
171
+ };
172
+ }
173
+ // Check if the provider is valid and create a wallet client if it is
174
+ async testProvider(providerInfo, testAddress) {
175
+ try {
176
+ const balance = await providerInfo.provider.getBalance(testAddress);
177
+ const network = await providerInfo.provider.getNetwork();
178
+ this.logDebug(`${providerInfo.name} API key test: SUCCESS - Network: ${network.name}, Test Balance returned.`);
179
+ return {
180
+ type: 'Service Provider',
181
+ provider: providerInfo.provider,
182
+ name: providerInfo.name,
183
+ status: 'SUCCESS',
184
+ network: network.name,
185
+ balance: balance.toString(),
186
+ apiKey: providerInfo.apiKey,
187
+ };
188
+ }
189
+ catch (error) {
190
+ return this.handleError(providerInfo.name, error, 'Service Provider');
191
+ }
192
+ }
193
+ // Check if a wallet token API key is valid
194
+ async testApiKey(apiKeyTestInfo) {
195
+ try {
196
+ let response;
197
+ if (apiKeyTestInfo.headers) {
198
+ response = await fetch(apiKeyTestInfo.url, {
199
+ headers: apiKeyTestInfo.headers,
200
+ });
201
+ }
202
+ else {
203
+ response = await fetch(apiKeyTestInfo.url);
204
+ }
205
+ return await apiKeyTestInfo.responseHandler(response);
206
+ }
207
+ catch (error) {
208
+ return this.handleError(apiKeyTestInfo.provider, error, 'API Provider');
209
+ }
210
+ }
211
+ // Helper function to extract clean error messages from API key tests
212
+ getCleanErrorMessage = (error) => {
213
+ const errorMessage = error instanceof Error ? error.message : String(error);
214
+ // Extract just the essential error information
215
+ if (errorMessage.includes('401')) {
216
+ return 'Authentication failed - invalid API key';
217
+ }
218
+ else if (errorMessage.includes('403')) {
219
+ return 'Access forbidden - check API key permissions';
220
+ }
221
+ else if (errorMessage.includes('429') || errorMessage.includes('rate limit')) {
222
+ return 'Rate limit exceeded - try again later';
223
+ }
224
+ else if (errorMessage.includes('network') || errorMessage.includes('connection')) {
225
+ return 'Network connection error';
226
+ }
227
+ else if (errorMessage.includes('timeout')) {
228
+ return 'Request timed out';
229
+ }
230
+ else {
231
+ // For other errors, take just the first meaningful part
232
+ const firstLine = errorMessage.split('\n')[0];
233
+ // Remove verbose details and keep just the core message
234
+ if (firstLine.includes('server response')) {
235
+ const match = firstLine.match(/server response (\d+)/);
236
+ if (match) {
237
+ return `Server error ${match[1]}`;
238
+ }
239
+ }
240
+ return firstLine;
241
+ }
242
+ };
243
+ // Helper to display masked API Keys in debug messages
244
+ maskKey(key) {
245
+ if (!key)
246
+ return 'undefined';
247
+ if (key.length <= 8)
248
+ return '*'.repeat(key.length);
249
+ return key.substring(0, 4) + '*'.repeat(key.length - 8) + key.substring(key.length - 4);
250
+ }
251
+ warnAboutLegacyKeys() {
252
+ if (process.env.DEBUG_ETHEREUM) {
253
+ if (process.env.INFURA_PROJECT_ID || process.env.INFURA_PROJECT_SECRET) {
254
+ this.logDebug('[DEBUG_ETHEREUM] Found an Infura API Project ID and/or Secret. Replace this with INFURA_API_KEY.');
255
+ if (process.env.DEBUG_ETHEREUM_FAIL_ON_ERROR === 'true') {
256
+ this.logDebug('Remove unused INFURA_PROJECT_ID and INFURA_PROJECT_SECRET from your environment variables.');
257
+ this.logDebug('DEBUG_ETHEREUM_FAIL_ON_ERROR is set to true. Exiting...');
258
+ process.exit(1);
259
+ }
260
+ }
261
+ if (process.env.POCKET_API_KEY) {
262
+ this.logDebug('[DEBUG_ETHEREUM] Found a Pocket API key. Pocket is no longer recommended as a service node.');
263
+ if (process.env.DEBUG_ETHEREUM_FAIL_ON_ERROR === 'true') {
264
+ this.logDebug('Remove unused POCKET_API_KEY from your environment variables.');
265
+ this.logDebug('DEBUG_ETHEREUM_FAIL_ON_ERROR is set to true. Exiting...');
266
+ process.exit(1);
267
+ }
268
+ }
269
+ }
270
+ }
271
+ // Helper to get the private providers from the environment variables
272
+ getPrivateProviders() {
273
+ const providers = [];
274
+ if (process.env.ALCHEMY_API_KEY) {
275
+ const alchemyProvider = new ethers.AlchemyProvider('mainnet', process.env.ALCHEMY_API_KEY);
276
+ providers.push({ name: 'Alchemy', provider: alchemyProvider, apiKey: process.env.ALCHEMY_API_KEY });
277
+ this.logDebug(`Found an Alchemy key (masked): ${this.maskKey(process.env.ALCHEMY_API_KEY)}`);
278
+ }
279
+ if (process.env.INFURA_API_KEY) {
280
+ const infuraProvider = new ethers.InfuraProvider('mainnet', process.env.INFURA_API_KEY);
281
+ providers.push({ name: 'Infura', provider: infuraProvider, apiKey: process.env.INFURA_API_KEY });
282
+ this.logDebug(`Found an Infura key (masked): ${this.maskKey(process.env.INFURA_API_KEY)}`);
283
+ }
284
+ return providers;
285
+ }
286
+ // Helper to get the array of wallet token API key tests
287
+ getWalletTokenApiKeyTestInfo(testAddress) {
288
+ const apiKeyTestInfo = [];
289
+ if (process.env.ETHERSCAN_API_KEY || process.env.MORALIS_API_KEY) {
290
+ if (process.env.MORALIS_API_KEY && process.env.DEBUG_ETHEREUM) {
291
+ this.logDebug(`Found a Moralis key (masked): ${this.maskKey(process.env.MORALIS_API_KEY)}`);
292
+ apiKeyTestInfo.push({
293
+ provider: 'Moralis',
294
+ url: `https://deep-index.moralis.io/api/v2/${testAddress}/balance`,
295
+ headers: { 'X-API-Key': process.env.MORALIS_API_KEY },
296
+ responseHandler: this.handleMoralisResponse,
297
+ });
298
+ }
299
+ if (process.env.ETHERSCAN_API_KEY && process.env.DEBUG_ETHEREUM) {
300
+ this.logDebug(`Found an Etherscan key (masked): ${this.maskKey(process.env.ETHERSCAN_API_KEY)}`);
301
+ apiKeyTestInfo.push({
302
+ provider: 'Etherscan',
303
+ url: `https://api.etherscan.io/api?module=account&action=balance&address=${testAddress}&tag=latest&apikey=${process.env.ETHERSCAN_API_KEY}`,
304
+ responseHandler: this.handleEtherscanResponse,
305
+ });
306
+ }
307
+ }
308
+ return apiKeyTestInfo;
309
+ }
310
+ // Define handlers to validate response from Wallet API requests
311
+ // Use arrow functions to bind 'this' to the class instance
312
+ handleMoralisResponse = async (response) => {
313
+ if (!response.ok) {
314
+ throw new Error(`Moralis API error: ${response.status} ${response.statusText}`);
315
+ }
316
+ this.logDebug('Moralis API key test: SUCCESS');
317
+ return { type: 'API Provider', name: 'Moralis', status: 'SUCCESS', apiKey: process.env.MORALIS_API_KEY };
318
+ };
319
+ handleEtherscanResponse = async (response) => {
320
+ const data = await response.json();
321
+ if (data.status === '0' && data.message === 'NOTOK') {
322
+ throw new Error(`Etherscan API error: ${data.result}`);
323
+ }
324
+ console.log('[DEBUG_ETHEREUM] Etherscan API key test: SUCCESS');
325
+ return {
326
+ type: 'API Provider',
327
+ name: 'Etherscan',
328
+ status: 'SUCCESS',
329
+ apiKey: process.env.ETHERSCAN_API_KEY,
330
+ };
331
+ };
332
+ getErrorMessage(error) {
333
+ if (error instanceof Error) {
334
+ return error.message;
335
+ }
336
+ return String(error);
337
+ }
338
+ }
339
+ export default EthereumInitializationService;
340
+ //# sourceMappingURL=ethereum_init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ethereum_init.js","sourceRoot":"","sources":["../../../src/ethereum_init.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  import type { LunchMoneyCryptoConnection, LunchMoneyCryptoConnectionContext, LunchMoneyCryptoConnectionConfig } from './types.js';
2
2
  import { EthereumWalletClient } from './client.js';
3
+ import EthereumInitializationService, { EthereumIntegrationType } from './ethereum_init.js';
3
4
  export { createEthereumWalletClient } from './client.js';
5
+ export { EthereumInitializationService, EthereumIntegrationType };
4
6
  interface LunchMoneyEthereumWalletConnectionConfig extends LunchMoneyCryptoConnectionConfig {
5
7
  /** The unique ID of the user's wallet address on the blockchain. */
6
8
  walletAddress: string;
@@ -1,80 +1,15 @@
1
- import { loadTokenList } from './client.js';
2
- import * as ethers from 'ethers';
1
+ import EthereumInitializationService from './ethereum_init.js';
3
2
  export { createEthereumWalletClient } from './client.js';
3
+ export { EthereumInitializationService };
4
4
  /** The minimum balance (in wei) that a token should have in order to be
5
5
  * considered for returning as a balance. */
6
6
  const NEGLIGIBLE_BALANCE_THRESHOLD = 1000;
7
- /**
8
- * Debug function that logs to console.log if DEBUG_ETHEREUM environment variable is set
9
- */
10
- const debug = (...args) => {
11
- if (process.env.DEBUG_ETHEREUM) {
12
- const timestamp = new Date().toISOString();
13
- console.log(`[DEBUG_ETHEREUM] [${timestamp}]`, ...args);
14
- }
15
- };
16
7
  export const LunchMoneyEthereumWalletConnection = {
17
8
  async initiate(config, context) {
18
9
  return this.getBalances(config, context);
19
10
  },
20
11
  async getBalances({ walletAddress, negligibleBalanceThreshold = NEGLIGIBLE_BALANCE_THRESHOLD }, { client }) {
21
- const obscuredWalletAddress = `0x..${walletAddress.slice(-6)}`;
22
- debug('getBalances called for wallet address:', obscuredWalletAddress);
23
- // Create a timeout so we fail instead of generating a CORS errors
24
- let timeoutId;
25
- const timeoutDuration = process.env.ETHEREUM_BALANCE_TIMEOUT_MSECS
26
- ? parseInt(process.env.ETHEREUM_BALANCE_TIMEOUT_MSECS)
27
- : 60000;
28
- const timeout = new Promise((_, reject) => {
29
- timeoutId = setTimeout(() => {
30
- reject(new Error(`Ethereum connector getBalances timed out after ${timeoutDuration} milliseconds.`));
31
- }, timeoutDuration);
32
- });
33
- // Wrap all ethers calls in a single timeout
34
- const result = await Promise.race([
35
- (async () => {
36
- try {
37
- const weiBalance = await client.getWeiBalance(walletAddress);
38
- // Filter out tokens that are not on mainnet
39
- const chainId = await client.getChainId();
40
- const chainFilteredTokensList = (await loadTokenList()).filter((t) => BigInt(t.chainId) === BigInt(chainId));
41
- const map = await client.getTokensBalance(walletAddress, chainFilteredTokensList.map((t) => t.address));
42
- return { weiBalance, chainId, map, chainFilteredTokensList };
43
- }
44
- finally {
45
- // Clear the timeout when the operation completes (success or failure)
46
- if (timeoutId) {
47
- clearTimeout(timeoutId);
48
- }
49
- }
50
- })(),
51
- timeout,
52
- ]);
53
- const { weiBalance, chainId, map, chainFilteredTokensList } = result;
54
- debug('ethers.getTokensBalance returned for wallet address:', obscuredWalletAddress);
55
- const balances = Object.entries(map)
56
- .map(([address, balance]) => {
57
- const token = chainFilteredTokensList.find((t) => t.address === address);
58
- if (!token) {
59
- throw new Error(`Token ${address} not found in filtered token list for chainId ${chainId}`);
60
- }
61
- return {
62
- asset: token.symbol,
63
- undivisedAmount: balance,
64
- decimals: token.decimals,
65
- };
66
- })
67
- .concat({ asset: 'ETH', undivisedAmount: weiBalance, decimals: 18 })
68
- .map(({ asset, undivisedAmount, decimals }) => ({ asset, amount: ethers.formatUnits(undivisedAmount, decimals) }))
69
- // Normalize the amount to 18 decimal places (for the wei per eth standard) for filtering out negligible balances
70
- .filter((b) => ethers.parseUnits(b.amount, 18) > negligibleBalanceThreshold)
71
- .map((b) => ({ asset: b.asset, amount: String(b.amount) }))
72
- .sort((a, b) => a.asset.localeCompare(b.asset));
73
- debug(`Returning from getBalances for ${obscuredWalletAddress}:`, balances);
74
- return {
75
- providerName: 'wallet_ethereum',
76
- balances,
77
- };
12
+ return client.getBalances(walletAddress, negligibleBalanceThreshold);
78
13
  },
79
14
  };
80
15
  //# sourceMappingURL=main.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/main.ts"],"names":[],"mappings":"AAOA,OAAO,6BAA0D,MAAM,oBAAoB,CAAC;AAE5F,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,6BAA6B,EAA2B,CAAC;AAElE;4CAC4C;AAC5C,MAAM,4BAA4B,GAAG,IAAI,CAAC;AAY1C,MAAM,CAAC,MAAM,kCAAkC,GAG3C;IACF,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO;QAC5B,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAE,aAAa,EAAE,0BAA0B,GAAG,4BAA4B,EAAE,EAAE,EAAE,MAAM,EAAE;QACxG,OAAO,MAAM,CAAC,WAAW,CAAC,aAAa,EAAE,0BAA0B,CAAC,CAAC;IACvE,CAAC;CACF,CAAC"}
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "@lunch-money/ethereum-to-lunch-money",
3
3
  "packageManager": "yarn@4.6.0",
4
- "author": "Max Dumas <maltor124@gmail.com>",
4
+ "authors": [
5
+ "Max Dumas <maltor124@gmail.com>",
6
+ "JP Shipherd <jp@lunchmoney.app>"
7
+ ],
5
8
  "bugs": {
6
9
  "url": "https://github.com/lunch-money/ethereum-to-lunch-money/issues"
7
10
  },
8
11
  "homepage": "https://github.com/lunch-money/ethereum-to-lunch-money#README",
9
- "version": "1.4.0",
12
+ "version": "2.0.1",
10
13
  "license": "MIT",
11
14
  "keywords": [
12
15
  "lunch money",
@@ -43,12 +46,14 @@
43
46
  "lint": "eslint '{src,test}/**/*.{js,ts,tsx}' --fix",
44
47
  "test": "tsx node_modules/mocha/lib/cli/cli --recursive --extension ts",
45
48
  "test-live": "npx ts-node --project tsconfig.build-cjs.json bin/get-balances.ts",
46
- "prepare": "husky install"
49
+ "prepare": "husky install",
50
+ "scenarios": "node run-scenarios.mjs"
47
51
  },
48
52
  "devDependencies": {
49
53
  "@types/chai": "^5.0.1",
50
54
  "@types/mocha": "^10.0.10",
51
55
  "@types/node": "^16.18.125",
56
+ "@types/node-fetch": "^2.6.13",
52
57
  "@types/sinon": "^17.0.3",
53
58
  "@typescript-eslint/eslint-plugin": "^8.22.0",
54
59
  "@typescript-eslint/parser": "^8.22.0",