From 463fd632936f3723ffa6f07799babde2c9605779 Mon Sep 17 00:00:00 2001 From: Kornii Date: Tue, 10 Sep 2024 13:19:27 +0100 Subject: [PATCH 1/3] TW-1537 Add TKEY stats endpoint (#173) * TW-1537 Add TKEY stats endpoint * TW-1537 Fix linter errors * TW-1537 Fetch incentives, developer rewards and investment fund dynamically --- src/index.ts | 5 +++++ src/tkey-stats.ts | 52 +++++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 2 +- 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/tkey-stats.ts diff --git a/src/index.ts b/src/index.ts index 66a1771..35f8f26 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,6 +22,7 @@ import { getPlatforms } from './notifications/utils/get-platforms.util'; import { redisClient } from './redis'; import { evmRouter } from './routers/evm'; import { adRulesRouter } from './routers/slise-ad-rules'; +import { getTkeyStats } from './tkey-stats'; import { getABData } from './utils/ab-test'; import { cancelAliceBobOrder } from './utils/alice-bob/cancel-alice-bob-order'; import { createAliceBobOrder } from './utils/alice-bob/create-alice-bob-order'; @@ -105,6 +106,10 @@ app.get('/api/top-coins', (_req, res) => { res.status(200).send(coinGeckoTokens); }); +app.get('/api/tkey', async (_req, res) => { + res.send(await getTkeyStats()); +}); + app.get('/api/notifications', async (_req, res) => { try { const { platform, startFromTime } = _req.query; diff --git a/src/tkey-stats.ts b/src/tkey-stats.ts new file mode 100644 index 0000000..bbcc38c --- /dev/null +++ b/src/tkey-stats.ts @@ -0,0 +1,52 @@ +import axios from 'axios'; +import memoizee from 'memoizee'; + +const BURN_ADDRESS = 'tz1burnburnburnburnburnburnburjAYjjX'; +const INCENTIVES_ADDRESS = 'tz1Ntpk55Q6AVJHVrCs1uN4HyTTxBbVMFZcb'; +const INVESTMENT_ADDRESS = 'tz1imUX3aTc4HX6KygaQUe8e1sQqYvGs6eCF'; +const DEVELOPER_REWARDS_ADDRESS = 'tz1bxHEHAtKubVy44vBDFVEZ1iqYPYdJVS9U'; +const CONTRACT = 'KT1VaEsVNiBoA56eToEK6n6BcPgh1tdx9eXi'; +const DECIMALS = 18n; +const TOTAL_SUPPLY = 14_000_000_000_000_000_000_000_000n; +const TOTAL_SUPPLY_WITH_DECIMALS = TOTAL_SUPPLY / 10n ** DECIMALS; + +const getTkeyBalance = memoizee( + async (holder: string) => { + const response = await axios.get( + `https://api.tzkt.io/v1/tokens/balances?account=${holder}&token.contract=${CONTRACT}` + ); + + return BigInt(response.data[0].balance) / 10n ** DECIMALS; + }, + { + maxAge: 1000 * 60 * 60 // 1 hour + } +); + +const getBurnedTokens = () => getTkeyBalance(BURN_ADDRESS); +const getInvestmentFund = () => getTkeyBalance(INVESTMENT_ADDRESS); +const getIncentivesFund = () => getTkeyBalance(INCENTIVES_ADDRESS); +const getDeveloperRewardsFund = () => getTkeyBalance(DEVELOPER_REWARDS_ADDRESS); + +export const getTkeyStats = memoizee( + async () => { + const burned = await getBurnedTokens(); + const incentives = await getIncentivesFund(); + const investment = await getInvestmentFund(); + const developerRewards = await getDeveloperRewardsFund(); + + const circulating = TOTAL_SUPPLY_WITH_DECIMALS - incentives - developerRewards - investment - burned; + + return { + incentivesFund: incentives.toString(), + investmentFund: investment.toString(), + developerRewardsFund: developerRewards.toString(), + totalSupply: TOTAL_SUPPLY_WITH_DECIMALS.toString(), + circulating: circulating.toString(), + burned: burned.toString() + }; + }, + { + maxAge: 1000 * 60 * 60 // 1 hour + } +); diff --git a/tsconfig.json b/tsconfig.json index 87d512f..aa0ae21 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { /* Basic Options */ - "target": "ES2019", + "target": "ES2020", "module": "commonjs", "lib": ["esnext"], "allowJs": true, From fc0d15048a5451690cfe7114811295fbfe0aa002 Mon Sep 17 00:00:00 2001 From: Inokentii Mazhara Date: Wed, 25 Sep 2024 14:59:02 +0300 Subject: [PATCH 2/3] TW-1518: Add an entrypoint for blacklisted Hypelab campaigns (#174) --- src/advertising/external-ads.ts | 12 ++-- src/index.ts | 3 + src/redis.ts | 6 ++ src/routers/slise-ad-rules/providers.ts | 47 ++++--------- src/routers/temple-wallet-ads.ts | 88 +++++++++++++++++++++++++ src/utils/express-helpers.ts | 45 +++++++++++++ 6 files changed, 159 insertions(+), 42 deletions(-) create mode 100644 src/routers/temple-wallet-ads.ts diff --git a/src/advertising/external-ads.ts b/src/advertising/external-ads.ts index f59a5cf..75373d8 100644 --- a/src/advertising/external-ads.ts +++ b/src/advertising/external-ads.ts @@ -1,6 +1,6 @@ import { satisfies as versionSatisfiesRange } from 'semver'; -import { objectStorageMethodsFactory, redisClient } from '../redis'; +import { objectStorageMethodsFactory, setStorageMethodsFactory } from '../redis'; /** Style properties names that are likely to be unnecessary for banners are skipped */ export const stylePropsNames = [ @@ -176,6 +176,7 @@ const PERMANENT_NATIVE_AD_PLACES_RULES_KEY = 'permanent_native_ad_places_rules'; const REPLACE_ADS_URLS_BLACKLIST_KEY = 'replace_ads_urls_blacklist'; const ELEMENTS_TO_HIDE_OR_REMOVE_KEY = 'elements_to_hide_or_remove'; const AD_PROVIDERS_CATEGORIES_KEY = 'ad_providers_categories'; +const HYPELAB_CAMPAIGNS_BLACKLIST_KEY = 'hypelab_campaigns_blacklist'; export const adPlacesRulesMethods = objectStorageMethodsFactory(AD_PLACES_RULES_KEY, []); @@ -210,13 +211,8 @@ export const adProvidersCategoriesMethods = objectStorageMethodsFactory redisClient.smembers(AD_PROVIDERS_ALL_SITES_KEY); - -export const addAdProvidersForAllSites = async (providers: string[]) => - redisClient.sadd(AD_PROVIDERS_ALL_SITES_KEY, ...providers); - -export const removeAdProvidersForAllSites = async (providers: string[]) => - redisClient.srem(AD_PROVIDERS_ALL_SITES_KEY, ...providers); +export const adProvidersForAllSitesMethods = setStorageMethodsFactory(AD_PROVIDERS_ALL_SITES_KEY); +export const hypelabCampaignsBlacklistMethods = setStorageMethodsFactory(HYPELAB_CAMPAIGNS_BLACKLIST_KEY); const FALLBACK_VERSION = '0.0.0'; diff --git a/src/index.ts b/src/index.ts index 35f8f26..fa0c07e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,6 +22,7 @@ import { getPlatforms } from './notifications/utils/get-platforms.util'; import { redisClient } from './redis'; import { evmRouter } from './routers/evm'; import { adRulesRouter } from './routers/slise-ad-rules'; +import { templeWalletAdsRouter } from './routers/temple-wallet-ads'; import { getTkeyStats } from './tkey-stats'; import { getABData } from './utils/ab-test'; import { cancelAliceBobOrder } from './utils/alice-bob/cancel-alice-bob-order'; @@ -343,6 +344,8 @@ app.use('/api/slise-ad-rules', adRulesRouter); app.use('/api/evm', evmRouter); +app.use('/api/temple-wallet-ads', templeWalletAdsRouter); + app.post('/api/magic-square-quest/start', async (req, res) => { try { await startMagicSquareQuest(req.body); diff --git a/src/redis.ts b/src/redis.ts index 0451742..b178b03 100644 --- a/src/redis.ts +++ b/src/redis.ts @@ -30,3 +30,9 @@ export const objectStorageMethodsFactory = (storageKey: string, fallba ), removeValues: (keys: string[]) => redisClient.hdel(storageKey, ...keys) }); + +export const setStorageMethodsFactory = (storageKey: string) => ({ + addValues: (values: string[]) => redisClient.sadd(storageKey, ...values), + removeValues: (values: string[]) => redisClient.srem(storageKey, ...values), + getAllValues: () => redisClient.smembers(storageKey) +}); diff --git a/src/routers/slise-ad-rules/providers.ts b/src/routers/slise-ad-rules/providers.ts index 5567565..cbbe99b 100644 --- a/src/routers/slise-ad-rules/providers.ts +++ b/src/routers/slise-ad-rules/providers.ts @@ -2,9 +2,7 @@ import { Request, Router } from 'express'; import { identity } from 'lodash'; import { - addAdProvidersForAllSites, - getAdProvidersForAllSites, - removeAdProvidersForAllSites, + adProvidersForAllSitesMethods, adProvidersMethods, adProvidersByDomainRulesMethods, AdProviderSelectorsRule, @@ -12,8 +10,11 @@ import { AdProvidersByDomainRule, adProvidersCategoriesMethods } from '../../advertising/external-ads'; -import { basicAuth } from '../../middlewares/basic-auth.middleware'; -import { addObjectStorageMethodsToRouter, withBodyValidation, withExceptionHandler } from '../../utils/express-helpers'; +import { + addObjectStorageMethodsToRouter, + addSetStorageMethodsToRouter, + withExceptionHandler +} from '../../utils/express-helpers'; import { isDefined, transformValues } from '../../utils/helpers'; import { nonEmptyStringsListSchema, @@ -204,35 +205,13 @@ export const adProvidersRouter = Router(); * '500': * $ref: '#/components/responses/ErrorResponse' */ -adProvidersRouter - .route('/all-sites') - .get( - withExceptionHandler(async (_req, res) => { - const providers = await getAdProvidersForAllSites(); - - res.status(200).header('Cache-Control', 'public, max-age=300').send(providers); - }) - ) - .post( - basicAuth, - withExceptionHandler( - withBodyValidation(nonEmptyStringsListSchema, async (req, res) => { - const providersAddedCount = await addAdProvidersForAllSites(req.body); - - res.status(200).send({ message: `${providersAddedCount} providers have been added` }); - }) - ) - ) - .delete( - basicAuth, - withExceptionHandler( - withBodyValidation(nonEmptyStringsListSchema, async (req, res) => { - const providersRemovedCount = await removeAdProvidersForAllSites(req.body); - - res.status(200).send({ message: `${providersRemovedCount} providers have been removed` }); - }) - ) - ); +addSetStorageMethodsToRouter(adProvidersRouter, { + path: '/all-sites', + methods: adProvidersForAllSitesMethods, + arrayValidationSchema: nonEmptyStringsListSchema, + successfulAdditionMessage: addedEntriesCount => `${addedEntriesCount} providers have been added`, + successfulRemovalMessage: removedEntriesCount => `${removedEntriesCount} providers have been removed` +}); /** * @swagger diff --git a/src/routers/temple-wallet-ads.ts b/src/routers/temple-wallet-ads.ts new file mode 100644 index 0000000..7aa54b2 --- /dev/null +++ b/src/routers/temple-wallet-ads.ts @@ -0,0 +1,88 @@ +import { Router } from 'express'; + +import { hypelabCampaignsBlacklistMethods } from '../advertising/external-ads'; +import { addSetStorageMethodsToRouter } from '../utils/express-helpers'; +import { nonEmptyStringsListSchema } from '../utils/schemas'; + +export const templeWalletAdsRouter = Router(); + +/** + * @swagger + * tags: + * name: Temple Wallet Ads + * /api/temple-wallet-ads/hypelab-campaigns-blacklist: + * get: + * summary: Get the list of blacklisted Hypelab campaigns slugs + * tags: + * - Temple Wallet Ads + * responses: + * '200': + * description: List of blacklisted Hypelab campaigns slugs + * content: + * application/json: + * schema: + * type: array + * items: + * type: string + * example: + * - '3896abb03b' + * '500': + * $ref: '#/components/responses/ErrorResponse' + * post: + * summary: Add Hypelab campaigns slugs to the blacklist + * tags: + * - Temple Wallet Ads + * security: + * - basicAuth: [] + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: array + * items: + * type: string + * example: + * - '3896abb03b' + * responses: + * '200': + * $ref: '#/components/responses/SuccessResponse' + * '400': + * $ref: '#/components/responses/ErrorResponse' + * '401': + * $ref: '#/components/responses/UnauthorizedError' + * '500': + * $ref: '#/components/responses/ErrorResponse' + * delete: + * summary: Remove Hypelab campaigns slugs from the blacklist + * tags: + * - Temple Wallet Ads + * security: + * - basicAuth: [] + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: array + * items: + * type: string + * example: + * - '3896abb03b' + * responses: + * '200': + * $ref: '#/components/responses/SuccessResponse' + * '400': + * $ref: '#/components/responses/ErrorResponse' + * '401': + * $ref: '#/components/responses/UnauthorizedError' + * '500': + * $ref: '#/components/responses/ErrorResponse' + */ +addSetStorageMethodsToRouter(templeWalletAdsRouter, { + path: '/hypelab-campaigns-blacklist', + methods: hypelabCampaignsBlacklistMethods, + arrayValidationSchema: nonEmptyStringsListSchema, + successfulAdditionMessage: slugs => `Added ${slugs} slugs to the blacklist`, + successfulRemovalMessage: slugs => `Removed ${slugs} slugs from the blacklist` +}); diff --git a/src/utils/express-helpers.ts b/src/utils/express-helpers.ts index 9ad300f..ae8ff1e 100644 --- a/src/utils/express-helpers.ts +++ b/src/utils/express-helpers.ts @@ -13,6 +13,12 @@ interface ObjectStorageMethods { removeValues: (keys: string[]) => Promise; } +interface SetStorageMethods { + addValues: (values: string[]) => Promise; + removeValues: (values: string[]) => Promise; + getAllValues: () => Promise; +} + type TypedBodyRequestHandler = ( req: Request, unknown, T>, res: Response, @@ -103,6 +109,45 @@ interface ObjectStorageMethodsEntrypointsConfig ValueResponse; } +interface SetStorageMethodsEntrypointsConfig { + path: string; + methods: SetStorageMethods; + arrayValidationSchema: IArraySchema; + successfulAdditionMessage: (addedEntriesCount: number) => string; + successfulRemovalMessage: (removedEntriesCount: number) => string; +} + +export const addSetStorageMethodsToRouter = (router: Router, config: SetStorageMethodsEntrypointsConfig) => { + const { path, methods, arrayValidationSchema, successfulAdditionMessage, successfulRemovalMessage } = config; + + router + .route(path) + .get( + withExceptionHandler(async (_req, res) => { + res + .status(200) + .header('Cache-Control', 'public, max-age=300') + .send(await methods.getAllValues()); + }) + ) + .post( + basicAuth, + withExceptionHandler( + withBodyValidation(arrayValidationSchema, async (req, res) => { + res.status(200).send({ message: successfulAdditionMessage(await methods.addValues(req.body)) }); + }) + ) + ) + .delete( + basicAuth, + withExceptionHandler( + withBodyValidation(arrayValidationSchema, async (req, res) => { + res.status(200).send({ message: successfulRemovalMessage(await methods.removeValues(req.body)) }); + }) + ) + ); +}; + export const addObjectStorageMethodsToRouter = < StoredValue, ObjectResponse = Record, From 3a479f6e10bcc13621f7007bfae277b74f82820e Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 18 Oct 2024 01:58:30 +0300 Subject: [PATCH 3/3] TW-1479: [EVM] Transactions history (#176) * TW-1479: [EVM] Transactions history * TW-1479: [EVM] Transactions history. ++ Covalent SDK --- .gitignore | 2 + package.json | 2 +- src/routers/evm/covalent.ts | 104 ++++++++---- src/routers/evm/index.ts | 71 +++++--- src/utils/express-helpers.ts | 33 +--- src/utils/schemas.ts | 11 ++ yarn.lock | 308 +---------------------------------- 7 files changed, 141 insertions(+), 390 deletions(-) diff --git a/.gitignore b/.gitignore index 8e39db5..a785147 100644 --- a/.gitignore +++ b/.gitignore @@ -108,3 +108,5 @@ dist # IDE .idea + +.DS_Store diff --git a/package.json b/package.json index e7a064d..694feb0 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "author": "Inokentii Mazhara ", "license": "MIT", "dependencies": { - "@covalenthq/client-sdk": "^1.0.2", + "@covalenthq/client-sdk": "^2", "@ethersproject/address": "^5.7.0", "@ethersproject/hash": "^5.7.0", "@ethersproject/strings": "^5.7.0", diff --git a/src/routers/evm/covalent.ts b/src/routers/evm/covalent.ts index e71fc3b..2f40415 100644 --- a/src/routers/evm/covalent.ts +++ b/src/routers/evm/covalent.ts @@ -1,45 +1,41 @@ -import { ChainID, CovalentClient } from '@covalenthq/client-sdk'; +import { + GoldRushClient, + ChainID, + GoldRushResponse, + GetTransactionsForAddressV3QueryParamOpts +} from '@covalenthq/client-sdk'; import retry from 'async-retry'; import { EnvVars } from '../../config'; import { CodedError } from '../../utils/errors'; -const client = new CovalentClient(EnvVars.COVALENT_API_KEY, { enableRetry: false, threadCount: 10 }); +const client = new GoldRushClient(EnvVars.COVALENT_API_KEY, { enableRetry: false, threadCount: 10 }); -const RETRY_OPTIONS = { maxRetryTime: 30_000 }; +const RETRY_OPTIONS: retry.Options = { maxRetryTime: 30_000 }; -export const getEvmBalances = async (walletAddress: string, chainId: string) => - await retry( - async () => +/** For v2 only for now. No support in v3. */ +const ACTIVITIES_PER_PAGE = 30; + +export const getEvmBalances = (walletAddress: string, chainId: string) => + retry( + () => client.BalanceService.getTokenBalancesForWalletAddress(Number(chainId) as ChainID, walletAddress, { nft: true, noNftAssetMetadata: true, quoteCurrency: 'USD', noSpam: false - }).then(({ data, error, error_message, error_code }) => { - if (error) { - throw new CodedError(Number(error_code) || 500, error_message); - } - - return data; - }), + }).then(processGoldRushResponse), RETRY_OPTIONS ); -export const getEvmTokensMetadata = async (walletAddress: string, chainId: string) => - await retry( - async () => +export const getEvmTokensMetadata = (walletAddress: string, chainId: string) => + retry( + () => client.BalanceService.getTokenBalancesForWalletAddress(Number(chainId) as ChainID, walletAddress, { nft: false, quoteCurrency: 'USD', noSpam: false - }).then(({ data, error, error_message, error_code }) => { - if (error) { - throw new CodedError(Number(error_code) || 500, error_message); - } - - return data; - }), + }).then(processGoldRushResponse), RETRY_OPTIONS ); @@ -49,20 +45,62 @@ export const getEvmCollectiblesMetadata = async (walletAddress: string, chainId: const withUncached = CHAIN_IDS_WITHOUT_CACHE_SUPPORT.includes(Number(chainId)); return await retry( - async () => + () => client.NftService.getNftsForAddress(Number(chainId) as ChainID, walletAddress, { withUncached, noSpam: false - }).then(({ data, error, error_message, error_code }) => { - if (error) { - throw new CodedError(Number(error_code) || 500, error_message); - } - - return data; - }), + }).then(processGoldRushResponse), RETRY_OPTIONS ); }; -export const getStringifiedResponse = (response: any) => - JSON.stringify(response, (_, value) => (typeof value === 'bigint' ? value.toString() : value)); +export const getEvmAccountTransactions = (walletAddress: string, chainId: string, page?: number) => + retry(async () => { + const options: GetTransactionsForAddressV3QueryParamOpts = { + // blockSignedAtAsc: true, + noLogs: false, + quoteCurrency: 'USD', + withSafe: false + }; + + const res = await (typeof page === 'number' + ? client.TransactionService.getTransactionsForAddressV3(Number(chainId) as ChainID, walletAddress, page, options) + : client.TransactionService.getAllTransactionsForAddressByPage( + Number(chainId) as ChainID, + walletAddress, + options + )); + + return processGoldRushResponse(res); + }, RETRY_OPTIONS); + +export const getEvmAccountERC20Transfers = ( + walletAddress: string, + chainId: string, + contractAddress: string, + page?: number +) => + retry(async () => { + const res = await client.BalanceService.getErc20TransfersForWalletAddressByPage( + Number(chainId) as ChainID, + walletAddress, + { + contractAddress, + quoteCurrency: 'USD', + pageNumber: page, + pageSize: ACTIVITIES_PER_PAGE + } + ); + + return processGoldRushResponse(res); + }, RETRY_OPTIONS); + +function processGoldRushResponse({ data, error, error_message, error_code }: GoldRushResponse) { + if (error) { + const code = error_code && Number.isSafeInteger(Number(error_code)) ? Number(error_code) : 500; + + throw new CodedError(code, error_message ?? 'Unknown error'); + } + + return JSON.stringify(data, (_, value) => (typeof value === 'bigint' ? value.toString() : value)); +} diff --git a/src/routers/evm/index.ts b/src/routers/evm/index.ts index 5eb4ac5..84165eb 100644 --- a/src/routers/evm/index.ts +++ b/src/routers/evm/index.ts @@ -1,44 +1,69 @@ import { Router } from 'express'; -import { withCodedExceptionHandler, withEvmQueryValidation } from '../../utils/express-helpers'; -import { getEvmBalances, getEvmCollectiblesMetadata, getEvmTokensMetadata, getStringifiedResponse } from './covalent'; +import { withCodedExceptionHandler } from '../../utils/express-helpers'; +import { + evmQueryParamsSchema, + evmQueryParamsPaginatedSchema, + evmQueryParamsTransfersSchema +} from '../../utils/schemas'; +import { + getEvmBalances, + getEvmCollectiblesMetadata, + getEvmTokensMetadata, + getEvmAccountTransactions, + getEvmAccountERC20Transfers +} from './covalent'; export const evmRouter = Router(); evmRouter .get( '/balances', - withCodedExceptionHandler( - withEvmQueryValidation(async (_1, res, _2, evmQueryParams) => { - const { walletAddress, chainId } = evmQueryParams; + withCodedExceptionHandler(async (req, res) => { + const { walletAddress, chainId } = await evmQueryParamsSchema.validate(req.query); - const data = await getEvmBalances(walletAddress, chainId); + const data = await getEvmBalances(walletAddress, chainId); - res.status(200).send(getStringifiedResponse(data)); - }) - ) + res.status(200).send(data); + }) ) .get( '/tokens-metadata', - withCodedExceptionHandler( - withEvmQueryValidation(async (_1, res, _2, evmQueryParams) => { - const { walletAddress, chainId } = evmQueryParams; + withCodedExceptionHandler(async (req, res) => { + const { walletAddress, chainId } = await evmQueryParamsSchema.validate(req.query); - const data = await getEvmTokensMetadata(walletAddress, chainId); + const data = await getEvmTokensMetadata(walletAddress, chainId); - res.status(200).send(getStringifiedResponse(data)); - }) - ) + res.status(200).send(data); + }) ) .get( '/collectibles-metadata', - withCodedExceptionHandler( - withEvmQueryValidation(async (_1, res, _2, evmQueryParams) => { - const { walletAddress, chainId } = evmQueryParams; + withCodedExceptionHandler(async (req, res) => { + const { walletAddress, chainId } = await evmQueryParamsSchema.validate(req.query); - const data = await getEvmCollectiblesMetadata(walletAddress, chainId); + const data = await getEvmCollectiblesMetadata(walletAddress, chainId); - res.status(200).send(getStringifiedResponse(data)); - }) - ) + res.status(200).send(data); + }) + ) + .get( + '/transactions', + withCodedExceptionHandler(async (req, res) => { + const { walletAddress, chainId, page } = await evmQueryParamsPaginatedSchema.validate(req.query); + + const data = await getEvmAccountTransactions(walletAddress, chainId, page); + + res.status(200).send(data); + }) + ) + .get( + '/erc20-transfers', + withCodedExceptionHandler(async (req, res) => { + const { walletAddress, chainId, contractAddress, page } = await evmQueryParamsTransfersSchema.validate(req.query); + + const data = await getEvmAccountERC20Transfers(walletAddress, chainId, contractAddress, page); + + res.status(200).send(data); + }) ); diff --git a/src/utils/express-helpers.ts b/src/utils/express-helpers.ts index ae8ff1e..c8dfac3 100644 --- a/src/utils/express-helpers.ts +++ b/src/utils/express-helpers.ts @@ -4,7 +4,6 @@ import { ArraySchema as IArraySchema, ObjectSchema as IObjectSchema, Schema, Val import { basicAuth } from '../middlewares/basic-auth.middleware'; import { CodedError } from './errors'; import logger from './logger'; -import { evmQueryParamsSchema } from './schemas'; interface ObjectStorageMethods { getByKey: (key: string) => Promise; @@ -41,36 +40,6 @@ export const withBodyValidation = return handler(req, res, next); }; -interface EvmQueryParams { - walletAddress: string; - chainId: string; -} - -type TypedEvmQueryRequestHandler = ( - req: Request, - res: Response, - next: NextFunction, - evmQueryParams: EvmQueryParams -) => void; - -export const withEvmQueryValidation = - (handler: TypedEvmQueryRequestHandler): RequestHandler => - async (req, res, next) => { - let evmQueryParams: EvmQueryParams; - - try { - evmQueryParams = await evmQueryParamsSchema.validate(req.query); - } catch (error) { - if (error instanceof ValidationError) { - return res.status(400).send({ error: error.message }); - } - - throw error; - } - - return handler(req, res, next, evmQueryParams); - }; - export const withExceptionHandler = (handler: RequestHandler): RequestHandler => async (req, res, next) => { @@ -92,6 +61,8 @@ export const withCodedExceptionHandler = if (error instanceof CodedError) { res.status(error.code).send(error.buildResponse()); + } else if (error instanceof ValidationError) { + res.status(400).send({ error: error.message }); } else { res.status(500).send({ message: error?.message }); } diff --git a/src/utils/schemas.ts b/src/utils/schemas.ts index a5a1241..49f3e93 100644 --- a/src/utils/schemas.ts +++ b/src/utils/schemas.ts @@ -1,3 +1,4 @@ +import { getAddress } from '@ethersproject/address'; import { validRange as getValidatedRange } from 'semver'; import { array as arraySchema, @@ -114,6 +115,16 @@ export const evmQueryParamsSchema = objectSchema().shape({ chainId: nonEmptyStringSchema.clone().required('chainId is undefined') }); +export const evmQueryParamsPaginatedSchema = evmQueryParamsSchema.clone().shape({ + page: numberSchema().integer().min(1) +}); + +export const evmQueryParamsTransfersSchema = evmQueryParamsPaginatedSchema.clone().shape({ + contractAddress: stringSchema() + .required() + .test(val => getAddress(val) === val) +}); + const adPlacesRulesSchema = arraySchema() .of( objectSchema() diff --git a/yarn.lock b/yarn.lock index ac2c2e5..a26ea40 100644 --- a/yarn.lock +++ b/yarn.lock @@ -55,25 +55,12 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/runtime@^7.21.0": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.1.tgz#431f9a794d173b53720e69a6464abc6f0e2a5c57" - integrity sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ== - dependencies: - regenerator-runtime "^0.14.0" - -"@covalenthq/client-sdk@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@covalenthq/client-sdk/-/client-sdk-1.0.2.tgz#58937f405f65e0e5eb1c7a6264da0da9b3371aac" - integrity sha512-jOFUW83qiONMm3jDeEEtQotJXPkQ9qJW9VRqxpLPifi+Nm6HPFKdRWwSRrpE5SZMDpZuK9VZQFk3t5tiJzys7w== +"@covalenthq/client-sdk@^2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@covalenthq/client-sdk/-/client-sdk-2.1.1.tgz#d49a70f67f9f03747acbe28455240ee38b9ecc90" + integrity sha512-wrtb6sn5cUOTOTD+GbE1Xi92b2Q2Wd76roK2wwUMdbOQ591ucahgSPfaJEgZY29nocLc3wDV2vhR11fNX8nZxA== dependencies: - "@rollup/plugin-commonjs" "^25.0.4" - "@rollup/plugin-node-resolve" "^15.2.1" big.js "^6.2.1" - date-fns "^2.30.0" - rollup "^3.29.1" - rollup-plugin-typescript2 "^0.35.0" - typescript "^5.1.6" "@cspotcode/source-map-support@^0.8.0": version "0.8.1" @@ -447,11 +434,6 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/sourcemap-codec@^1.4.15": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - "@jridgewell/trace-mapping@0.3.9": version "0.3.9" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" @@ -544,47 +526,6 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= -"@rollup/plugin-commonjs@^25.0.4": - version "25.0.7" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz#145cec7589ad952171aeb6a585bbeabd0fd3b4cf" - integrity sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ== - dependencies: - "@rollup/pluginutils" "^5.0.1" - commondir "^1.0.1" - estree-walker "^2.0.2" - glob "^8.0.3" - is-reference "1.2.1" - magic-string "^0.30.3" - -"@rollup/plugin-node-resolve@^15.2.1": - version "15.2.3" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz#e5e0b059bd85ca57489492f295ce88c2d4b0daf9" - integrity sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ== - dependencies: - "@rollup/pluginutils" "^5.0.1" - "@types/resolve" "1.20.2" - deepmerge "^4.2.2" - is-builtin-module "^3.2.1" - is-module "^1.0.0" - resolve "^1.22.1" - -"@rollup/pluginutils@^4.1.2": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" - integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== - dependencies: - estree-walker "^2.0.1" - picomatch "^2.2.2" - -"@rollup/pluginutils@^5.0.1": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" - integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== - dependencies: - "@types/estree" "^1.0.0" - estree-walker "^2.0.2" - picomatch "^2.3.1" - "@stablelib/binary@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@stablelib/binary/-/binary-1.0.1.tgz#c5900b94368baf00f811da5bdb1610963dfddf7f" @@ -794,11 +735,6 @@ dependencies: "@types/node" "*" -"@types/estree@*", "@types/estree@^1.0.0": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" - integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== - "@types/express-jwt@0.0.42": version "0.0.42" resolved "https://registry.yarnpkg.com/@types/express-jwt/-/express-jwt-0.0.42.tgz#4f04e1fadf9d18725950dc041808a4a4adf7f5ae" @@ -964,11 +900,6 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== -"@types/resolve@1.20.2": - version "1.20.2" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" - integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== - "@types/retry@*": version "0.12.5" resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.5.tgz#f090ff4bd8d2e5b940ff270ab39fd5ca1834a07e" @@ -1387,13 +1318,6 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -1440,11 +1364,6 @@ buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" -builtin-modules@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" - integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== - bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -1568,11 +1487,6 @@ commander@^10.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - compressible@^2.0.12: version "2.0.18" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" @@ -1698,13 +1612,6 @@ date-and-time@^2.0.0: resolved "https://registry.yarnpkg.com/date-and-time/-/date-and-time-2.3.0.tgz#1b509be4c938dbbf5fc9c14d66e1daf9fe3cef13" integrity sha512-DY53oj742mykXjZzDxT7NxH5cxwBRb7FsVG5+8pcV96qU9JQd0UhA21pQB18fwwsXOXeSM0RJV4OzgVxu8eatg== -date-fns@^2.30.0: - version "2.30.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" - integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== - dependencies: - "@babel/runtime" "^7.21.0" - dateformat@^4.5.1: version "4.5.1" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.5.1.tgz#c20e7a9ca77d147906b6dc2261a8be0a5bd2173c" @@ -1736,11 +1643,6 @@ deep-is@^0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -deepmerge@^4.2.2: - version "4.3.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" - integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== - define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -2218,11 +2120,6 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== -estree-walker@^2.0.1, estree-walker@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" - integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== - esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -2403,23 +2300,6 @@ finalhandler@1.2.0: statuses "2.0.1" unpipe "~1.0.0" -find-cache-dir@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - -find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - firebase-admin@^10.0.2: version "10.0.2" resolved "https://registry.yarnpkg.com/firebase-admin/-/firebase-admin-10.0.2.tgz#d1142fb40738fa9b62f6625c4e3fc8cbc0ba61c6" @@ -2485,15 +2365,6 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= -fs-extra@^10.0.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" - integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -2504,21 +2375,11 @@ fsevents@~2.3.1: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== -fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - function.prototype.name@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" @@ -2637,17 +2498,6 @@ glob@^7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^8.0.3: - version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" - integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - globals@^13.6.0, globals@^13.9.0: version "13.19.0" resolved "https://registry.yarnpkg.com/globals/-/globals-13.19.0.tgz#7a42de8e6ad4f7242fbcca27ea5b23aca367b5c8" @@ -2727,11 +2577,6 @@ graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== -graceful-fs@^4.1.6, graceful-fs@^4.2.0: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - gtoken@^5.0.4: version "5.3.2" resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-5.3.2.tgz#deb7dc876abe002178e0515e383382ea9446d58f" @@ -2819,13 +2664,6 @@ hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hasown@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" - integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== - dependencies: - function-bind "^1.1.2" - hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -2988,13 +2826,6 @@ is-boolean-object@^1.1.0: dependencies: call-bind "^1.0.2" -is-builtin-module@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" - integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== - dependencies: - builtin-modules "^3.3.0" - is-callable@^1.1.3, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" @@ -3005,13 +2836,6 @@ is-callable@^1.1.4, is-callable@^1.2.3: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== -is-core-module@^2.13.0: - version "2.13.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" - integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== - dependencies: - hasown "^2.0.0" - is-core-module@^2.2.0: version "2.4.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" @@ -3055,11 +2879,6 @@ is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" - integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== - is-negative-zero@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" @@ -3090,13 +2909,6 @@ is-promise@^2.2.2: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== -is-reference@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" - integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== - dependencies: - "@types/estree" "*" - is-regex@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" @@ -3253,15 +3065,6 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - jsonwebtoken@^8.5.1: version "8.5.1" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" @@ -3361,13 +3164,6 @@ load-json-file@^4.0.0: pify "^3.0.0" strip-bom "^3.0.0" -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" @@ -3488,14 +3284,7 @@ lru-queue@^0.1.0: dependencies: es5-ext "~0.10.2" -magic-string@^0.30.3: - version "0.30.8" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.8.tgz#14e8624246d2bedba70d5462aa99ac9681844613" - integrity sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ== - dependencies: - "@jridgewell/sourcemap-codec" "^1.4.15" - -make-dir@^3.0.0, make-dir@^3.0.2: +make-dir@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== @@ -3614,13 +3403,6 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - minimist@^1.2.0, minimist@^1.2.6: version "1.2.7" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" @@ -3803,13 +3585,6 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - p-limit@^3.0.1: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" @@ -3817,18 +3592,6 @@ p-limit@^3.0.1: dependencies: yocto-queue "^0.1.0" -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -3849,11 +3612,6 @@ parseurl@~1.3.3: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -3896,7 +3654,7 @@ picomatch@^2.0.4, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== -picomatch@^2.2.2, picomatch@^2.3.1: +picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -3960,13 +3718,6 @@ pino@^6.0.0, pino@^6.11.2: quick-format-unescaped "^4.0.3" sonic-boom "^1.0.2" -pkg-dir@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -4146,11 +3897,6 @@ redis-parser@^3.0.0: dependencies: redis-errors "^1.0.0" -regenerator-runtime@^0.14.0: - version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" - integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== - regexp.prototype.flags@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" @@ -4197,15 +3943,6 @@ resolve@^1.20.0, resolve@^1.22.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^1.22.1: - version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - retry-request@^4.0.0, retry-request@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-4.2.2.tgz#b7d82210b6d2651ed249ba3497f07ea602f1a903" @@ -4251,24 +3988,6 @@ ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -rollup-plugin-typescript2@^0.35.0: - version "0.35.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.35.0.tgz#a84fb4e802b919613f31552c69c3415101b547c1" - integrity sha512-szcIO9hPUx3PhQl91u4pfNAH2EKbtrXaES+m163xQVE5O1CC0ea6YZV/5woiDDW3CR9jF2CszPrKN+AFiND0bg== - dependencies: - "@rollup/pluginutils" "^4.1.2" - find-cache-dir "^3.3.2" - fs-extra "^10.0.0" - semver "^7.3.7" - tslib "^2.4.0" - -rollup@^3.29.1: - version "3.29.4" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981" - integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== - optionalDependencies: - fsevents "~2.3.2" - run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -4789,11 +4508,6 @@ tslib@^2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== -tslib@^2.4.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== - tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -4862,11 +4576,6 @@ typescript@^4.9.5: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== -typescript@^5.1.6: - version "5.4.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.3.tgz#5c6fedd4c87bee01cd7a528a30145521f8e0feff" - integrity sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg== - unbox-primitive@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" @@ -4894,11 +4603,6 @@ unique-string@^2.0.0: dependencies: crypto-random-string "^2.0.0" -universalify@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" - integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== - unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"