Skip to content

Commit afb5f3d

Browse files
authored
Release (pre Mises integration) to prod (#169)
Merge pull request #169 from madfish-solutions/development
2 parents e5d44b6 + 3a36381 commit afb5f3d

File tree

15 files changed

+887
-28
lines changed

15 files changed

+887
-28
lines changed

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"author": "Inokentii Mazhara <[email protected]>",
77
"license": "MIT",
88
"dependencies": {
9+
"@covalenthq/client-sdk": "^1.0.2",
910
"@ethersproject/address": "^5.7.0",
1011
"@ethersproject/hash": "^5.7.0",
1112
"@ethersproject/strings": "^5.7.0",
@@ -16,6 +17,7 @@
1617
"@taquito/tzip12": "14.0.0",
1718
"@taquito/tzip16": "14.0.0",
1819
"@taquito/utils": "14.0.0",
20+
"async-retry": "^1.3.3",
1921
"axios": "^0.27.2",
2022
"bignumber.js": "^9.1.0",
2123
"body-parser": "^1.20.2",
@@ -49,6 +51,7 @@
4951
"db-migration": "cd migrations/notifications && npx ts-node index.ts"
5052
},
5153
"devDependencies": {
54+
"@types/async-retry": "^1.4.8",
5255
"@types/body-parser": "^1.19.2",
5356
"@types/express": "^4.17.17",
5457
"@types/express-jwt": "^7.4.2",

src/advertising/external-ads.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export const stylePropsNames = [
1111
'aspect-ratio',
1212
'background',
1313
'border',
14+
'border-top',
15+
'border-bottom',
16+
'border-left',
17+
'border-right',
18+
'border-color',
1419
'border-radius',
1520
'bottom',
1621
'box-shadow',
@@ -49,6 +54,7 @@ export const stylePropsNames = [
4954
'min-inline-size',
5055
'min-width',
5156
'opacity',
57+
'order',
5258
'overflow',
5359
'overflow-anchor',
5460
'overflow-wrap',
@@ -127,8 +133,10 @@ export interface PermanentAdPlacesRule extends ExtVersionConstraints {
127133
divWrapperStyle?: Record<StylePropName, string>;
128134
wrapperStyle?: Record<StylePropName, string>;
129135
elementToMeasureSelector?: string;
136+
elementsToMeasureSelectors?: Record<'width' | 'height', string>;
130137
stylesOverrides?: AdStylesOverrides[];
131138
shouldHideOriginal?: boolean;
139+
displayWidth?: string;
132140
}
133141

134142
export interface AdProvidersByDomainRule extends ExtVersionConstraints {
@@ -138,7 +146,9 @@ export interface AdProvidersByDomainRule extends ExtVersionConstraints {
138146

139147
export interface AdProviderSelectorsRule extends ExtVersionConstraints {
140148
selectors: string[];
149+
negativeSelectors?: string[];
141150
parentDepth?: number;
151+
enableForMises?: boolean;
142152
}
143153

144154
export interface AdProviderForAllSitesRule extends ExtVersionConstraints {
@@ -149,13 +159,22 @@ export interface ReplaceAdsUrlsBlacklistEntry extends ExtVersionConstraints {
149159
regexes: string[];
150160
}
151161

162+
export interface ElementsToHideOrRemoveEntry extends ExtVersionConstraints {
163+
cssString: string;
164+
parentDepth: number;
165+
isMultiple: boolean;
166+
urlRegexes: string[];
167+
shouldHide: boolean;
168+
}
169+
152170
const AD_PLACES_RULES_KEY = 'ad_places_rules';
153171
const AD_PROVIDERS_BY_SITES_KEY = 'ad_providers_by_sites';
154172
const AD_PROVIDERS_ALL_SITES_KEY = 'ad_providers_all_sites';
155173
const AD_PROVIDERS_LIST_KEY = 'ad_providers_list';
156174
const PERMANENT_AD_PLACES_RULES_KEY = 'permanent_ad_places_rules';
157175
const PERMANENT_NATIVE_AD_PLACES_RULES_KEY = 'permanent_native_ad_places_rules';
158176
const REPLACE_ADS_URLS_BLACKLIST_KEY = 'replace_ads_urls_blacklist';
177+
const ELEMENTS_TO_HIDE_OR_REMOVE_KEY = 'elements_to_hide_or_remove';
159178

160179
export const adPlacesRulesMethods = objectStorageMethodsFactory<AdPlacesRule[]>(AD_PLACES_RULES_KEY, []);
161180

@@ -181,6 +200,11 @@ export const replaceAdsUrlsBlacklistMethods = objectStorageMethodsFactory<Replac
181200
[]
182201
);
183202

203+
export const elementsToHideOrRemoveMethods = objectStorageMethodsFactory<ElementsToHideOrRemoveEntry[]>(
204+
ELEMENTS_TO_HIDE_OR_REMOVE_KEY,
205+
[]
206+
);
207+
184208
export const getAdProvidersForAllSites = async () => redisClient.smembers(AD_PROVIDERS_ALL_SITES_KEY);
185209

186210
export const addAdProvidersForAllSites = async (providers: string[]) =>
@@ -191,5 +215,19 @@ export const removeAdProvidersForAllSites = async (providers: string[]) =>
191215

192216
const FALLBACK_VERSION = '0.0.0';
193217

194-
export const filterByVersion = <T extends ExtVersionConstraints>(rules: T[], version?: string) =>
195-
rules.filter(({ extVersion }) => versionSatisfiesRange(version ?? FALLBACK_VERSION, extVersion));
218+
export function filterRules<T extends ExtVersionConstraints>(rules: T[], version: string | undefined): T[];
219+
export function filterRules<T extends ExtVersionConstraints & { enableForMises?: boolean }>(
220+
rules: T[],
221+
version: string | undefined,
222+
isMisesBrowser: boolean
223+
): T[];
224+
export function filterRules<T extends ExtVersionConstraints & { enableForMises?: boolean }>(
225+
rules: T[],
226+
version: string | undefined,
227+
isMisesBrowser = false
228+
) {
229+
return rules.filter(
230+
({ extVersion, enableForMises = true }) =>
231+
versionSatisfiesRange(version ?? FALLBACK_VERSION, extVersion) && (!isMisesBrowser || enableForMises)
232+
);
233+
}

src/config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ export const EnvVars = {
1212
THREE_ROUTE_API_AUTH_TOKEN: getEnv('THREE_ROUTE_API_AUTH_TOKEN'),
1313
REDIS_URL: getEnv('REDIS_URL'),
1414
ADMIN_USERNAME: getEnv('ADMIN_USERNAME'),
15-
ADMIN_PASSWORD: getEnv('ADMIN_PASSWORD')
15+
ADMIN_PASSWORD: getEnv('ADMIN_PASSWORD'),
16+
COVALENT_API_KEY: getEnv('COVALENT_API_KEY')
1617
};
1718

1819
for (const name in EnvVars) {

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { getNotifications } from './notifications/utils/get-notifications.util';
2020
import { getParsedContent } from './notifications/utils/get-parsed-content.util';
2121
import { getPlatforms } from './notifications/utils/get-platforms.util';
2222
import { redisClient } from './redis';
23+
import { evmRouter } from './routers/evm';
2324
import { adRulesRouter } from './routers/slise-ad-rules';
2425
import { getABData } from './utils/ab-test';
2526
import { cancelAliceBobOrder } from './utils/alice-bob/cancel-alice-bob-order';
@@ -334,6 +335,8 @@ app.get('/api/advertising-info', (_req, res) => {
334335

335336
app.use('/api/slise-ad-rules', adRulesRouter);
336337

338+
app.use('/api/evm', evmRouter);
339+
337340
app.post('/api/magic-square-quest/start', async (req, res) => {
338341
try {
339342
await startMagicSquareQuest(req.body);

src/routers/evm/covalent.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { ChainID, CovalentClient } from '@covalenthq/client-sdk';
2+
import retry from 'async-retry';
3+
4+
import { EnvVars } from '../../config';
5+
import { CodedError } from '../../utils/errors';
6+
7+
const client = new CovalentClient(EnvVars.COVALENT_API_KEY, { enableRetry: false, threadCount: 10 });
8+
9+
const RETRY_OPTIONS = { maxRetryTime: 30_000 };
10+
11+
export const getEvmBalances = async (walletAddress: string, chainId: string) =>
12+
await retry(
13+
async () =>
14+
client.BalanceService.getTokenBalancesForWalletAddress(Number(chainId) as ChainID, walletAddress, {
15+
nft: true,
16+
noNftAssetMetadata: true,
17+
quoteCurrency: 'USD',
18+
noSpam: false
19+
}).then(({ data, error, error_message, error_code }) => {
20+
if (error) {
21+
throw new CodedError(Number(error_code) || 500, error_message);
22+
}
23+
24+
return data;
25+
}),
26+
RETRY_OPTIONS
27+
);
28+
29+
export const getEvmTokensMetadata = async (walletAddress: string, chainId: string) =>
30+
await retry(
31+
async () =>
32+
client.BalanceService.getTokenBalancesForWalletAddress(Number(chainId) as ChainID, walletAddress, {
33+
nft: false,
34+
quoteCurrency: 'USD',
35+
noSpam: false
36+
}).then(({ data, error, error_message, error_code }) => {
37+
if (error) {
38+
throw new CodedError(Number(error_code) || 500, error_message);
39+
}
40+
41+
return data;
42+
}),
43+
RETRY_OPTIONS
44+
);
45+
46+
const CHAIN_IDS_WITHOUT_CACHE_SUPPORT = [10, 11155420, 43114, 43113];
47+
48+
export const getEvmCollectiblesMetadata = async (walletAddress: string, chainId: string) => {
49+
const withUncached = CHAIN_IDS_WITHOUT_CACHE_SUPPORT.includes(Number(chainId));
50+
51+
return await retry(
52+
async () =>
53+
client.NftService.getNftsForAddress(Number(chainId) as ChainID, walletAddress, {
54+
withUncached,
55+
noSpam: false
56+
}).then(({ data, error, error_message, error_code }) => {
57+
if (error) {
58+
throw new CodedError(Number(error_code) || 500, error_message);
59+
}
60+
61+
return data;
62+
}),
63+
RETRY_OPTIONS
64+
);
65+
};
66+
67+
export const getStringifiedResponse = (response: any) =>
68+
JSON.stringify(response, (_, value) => (typeof value === 'bigint' ? value.toString() : value));

src/routers/evm/index.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Router } from 'express';
2+
3+
import { withCodedExceptionHandler, withEvmQueryValidation } from '../../utils/express-helpers';
4+
import { getEvmBalances, getEvmCollectiblesMetadata, getEvmTokensMetadata, getStringifiedResponse } from './covalent';
5+
6+
export const evmRouter = Router();
7+
8+
evmRouter
9+
.get(
10+
'/balances',
11+
withCodedExceptionHandler(
12+
withEvmQueryValidation(async (_1, res, _2, evmQueryParams) => {
13+
const { walletAddress, chainId } = evmQueryParams;
14+
15+
const data = await getEvmBalances(walletAddress, chainId);
16+
17+
res.status(200).send(getStringifiedResponse(data));
18+
})
19+
)
20+
)
21+
.get(
22+
'/tokens-metadata',
23+
withCodedExceptionHandler(
24+
withEvmQueryValidation(async (_1, res, _2, evmQueryParams) => {
25+
const { walletAddress, chainId } = evmQueryParams;
26+
27+
const data = await getEvmTokensMetadata(walletAddress, chainId);
28+
29+
res.status(200).send(getStringifiedResponse(data));
30+
})
31+
)
32+
)
33+
.get(
34+
'/collectibles-metadata',
35+
withCodedExceptionHandler(
36+
withEvmQueryValidation(async (_1, res, _2, evmQueryParams) => {
37+
const { walletAddress, chainId } = evmQueryParams;
38+
39+
const data = await getEvmCollectiblesMetadata(walletAddress, chainId);
40+
41+
res.status(200).send(getStringifiedResponse(data));
42+
})
43+
)
44+
);

src/routers/slise-ad-rules/ad-places.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Request, Router } from 'express';
22

33
import {
4-
filterByVersion,
4+
filterRules,
55
permanentNativeAdPlacesMethods,
66
permanentAdPlacesMethods,
77
adPlacesRulesMethods,
@@ -18,7 +18,7 @@ import {
1818
} from '../../utils/schemas';
1919

2020
const transformAdPlaces = <T extends ExtVersionConstraints>(value: T[], req: Request) =>
21-
filterByVersion(value, req.query.extVersion as string | undefined);
21+
filterRules(value, req.query.extVersion as string | undefined);
2222
const transformAdPlacesDictionary = <T extends ExtVersionConstraints>(rules: Record<string, T[]>, req: Request) =>
2323
transformValues(rules, value => transformAdPlaces(value, req));
2424

@@ -280,6 +280,18 @@ const transformAdPlacesDictionary = <T extends ExtVersionConstraints>(rules: Rec
280280
* elementToMeasureSelector:
281281
* type: string
282282
* description: A selector of the element which should be measured to define banner size
283+
* elementsToMeasureSelectors:
284+
* type: object
285+
* required:
286+
* - width
287+
* - height
288+
* properties:
289+
* width:
290+
* type: string
291+
* description: A selector of the element which should be measured to define banner width
292+
* height:
293+
* type: string
294+
* description: A selector of the element which should be measured to define banner height
283295
* stylesOverrides:
284296
* type: array
285297
* items:
@@ -288,6 +300,12 @@ const transformAdPlacesDictionary = <T extends ExtVersionConstraints>(rules: Rec
288300
* type: boolean
289301
* description: Whether original ads banners should be hidden but not removed
290302
* default: false
303+
* displayWidth:
304+
* type: string
305+
* description: >
306+
* A range of display widths in a semver-like format where the rule is applicable. Numbers can be only
307+
* integers. If not specified, the rule is applicable for all display widths.
308+
* example: '>=1024 <1280'
291309
* example:
292310
* urlRegexes:
293311
* - '^https://etherscan\.io/tx/'

0 commit comments

Comments
 (0)