diff --git a/src/config.ts b/src/config.ts index 62aa085..e6adbc9 100644 --- a/src/config.ts +++ b/src/config.ts @@ -61,6 +61,12 @@ export function buildConfig(config: Record) { config.USE_MERCURY === "true" || process.env.USE_MERCURY === "true", useSorobanPublic: true, sentryKey: config.SENTRY_KEY || process.env.SENTRY_KEY, + + blockaidConfig: { + useBlockaidDappScanning: true, + useBlockaidTxScanning: true, + useBlockaidAssetScanning: true, + }, }; } diff --git a/src/helper/error.ts b/src/helper/error.ts index 49cadc8..6d1af9e 100644 --- a/src/helper/error.ts +++ b/src/helper/error.ts @@ -22,4 +22,7 @@ export const ERROR = { UNABLE_TO_SCAN_SITE: "unable to scan site using blockaid", UNABLE_TO_SCAN_TX: "unable to scan tx using blockaid", UNABLE_TO_SCAN_ASSET: "unable to scan asset using blockaid", + SCAN_SITE_DISABLED: "scanning site using blockaid is disabled", + SCAN_TX_DISABLED: "scanning tx using blockaid is disabled", + SCAN_ASSET_DISABLED: "scanning asset using blockaid is disabled", }; diff --git a/src/index.ts b/src/index.ts index f6901a0..6b95b65 100644 --- a/src/index.ts +++ b/src/index.ts @@ -82,7 +82,7 @@ async function main() { renewClientMaker: buildRenewClientMaker(graphQlEndpoints), backendClientMaker: buildBackendClientMaker(graphQlEndpoints), currentDataClientMaker: buildCurrentDataClientMaker( - graphQlCurrentDataEndpoints + graphQlCurrentDataEndpoints, ), backends, credentials: { @@ -130,7 +130,7 @@ async function main() { rpcErrorCounter, criticalError, }, - redis + redis, ); const server = await initApiServer( mercuryClient, @@ -140,7 +140,8 @@ async function main() { conf.useSorobanPublic, register, env as mode, - redis + conf.blockaidConfig, + redis, ); const metricsServer = await initMetricsServer(register, redis); diff --git a/src/route/index.ts b/src/route/index.ts index 9d46088..5bbe230 100644 --- a/src/route/index.ts +++ b/src/route/index.ts @@ -10,8 +10,14 @@ import { Networks } from "stellar-sdk-next"; import * as StellarSdk from "stellar-sdk"; import { MercuryClient } from "../service/mercury"; -import { BlockAidService } from "../service/blockaid"; -import { addScannedStatus } from "../service/blockaid/helpers/addScanResults"; +import { + BlockAidService, + BlockaidAssetScanResponse, +} from "../service/blockaid"; +import { + addScannedStatus, + defaultBenignResponse, +} from "../service/blockaid/helpers/addScanResults"; import { ajv } from "./validators"; import { isContractId, @@ -44,6 +50,11 @@ export async function initApiServer( useSorobanPublic: boolean, register: Prometheus.Registry, mode: mode, + blockaidConfig: { + useBlockaidDappScanning: boolean; + useBlockaidTxScanning: boolean; + useBlockaidAssetScanning: boolean; + }, redis?: Redis, ) { const routeMetricsStore = new WeakMap< @@ -323,6 +334,7 @@ export async function initApiServer( blockAidService, network, logger, + blockaidConfig.useBlockaidAssetScanning, ); } catch (e) { data.balances = data.balances.map((bal: {}) => ({ @@ -577,12 +589,17 @@ export async function initApiServer( reply, ) => { const { url } = request.query; - try { - const { data, error } = await blockAidService.scanDapp(url); - return reply.code(error ? 400 : 200).send({ data, error }); - } catch (error) { - return reply.code(500).send(ERROR.SERVER_ERROR); + if (blockaidConfig.useBlockaidDappScanning) { + try { + const { data, error } = await blockAidService.scanDapp(url); + return reply.code(error ? 400 : 200).send({ data, error }); + } catch (error) { + return reply.code(500).send(ERROR.SERVER_ERROR); + } } + return reply + .code(200) + .send({ data: null, error: ERROR.SCAN_SITE_DISABLED }); }, }); @@ -618,16 +635,21 @@ export async function initApiServer( reply, ) => { const { tx_xdr, url, network } = request.query; - try { - const { data, error } = await blockAidService.scanTx( - tx_xdr, - url, - network, - ); - return reply.code(error ? 400 : 200).send({ data, error }); - } catch (error) { - return reply.code(500).send(ERROR.SERVER_ERROR); + if (blockaidConfig.useBlockaidTxScanning) { + try { + const { data, error } = await blockAidService.scanTx( + tx_xdr, + url, + network, + ); + return reply.code(error ? 400 : 200).send({ data, error }); + } catch (error) { + return reply.code(500).send(ERROR.SERVER_ERROR); + } } + return reply + .code(200) + .send({ data: null, error: ERROR.SCAN_TX_DISABLED }); }, }); @@ -654,12 +676,18 @@ export async function initApiServer( reply, ) => { const { address } = request.query; - try { - const { data, error } = await blockAidService.scanAsset(address); - return reply.code(error ? 400 : 200).send({ data, error }); - } catch (error) { - return reply.code(500).send(ERROR.SERVER_ERROR); + + if (blockaidConfig.useBlockaidAssetScanning) { + try { + const { data, error } = await blockAidService.scanAsset(address); + return reply.code(error ? 400 : 200).send({ data, error }); + } catch (error) { + return reply.code(500).send(ERROR.SERVER_ERROR); + } } + return reply + .code(200) + .send({ data: null, error: ERROR.SCAN_ASSET_DISABLED }); }, }); @@ -690,13 +718,29 @@ export async function initApiServer( reply, ) => { const { asset_ids } = request.query; - try { - const { data, error } = - await blockAidService.scanAssetBulk(asset_ids); - return reply.code(error ? 400 : 200).send({ data, error }); - } catch (error) { - return reply.code(500).send(ERROR.SERVER_ERROR); + if (blockaidConfig.useBlockaidAssetScanning) { + try { + const { data, error } = + await blockAidService.scanAssetBulk(asset_ids); + return reply.code(error ? 400 : 200).send({ data, error }); + } catch (error) { + return reply.code(500).send(ERROR.SERVER_ERROR); + } } + const defaultResponse: { + [addres: string]: BlockaidAssetScanResponse; + } = {}; + asset_ids.forEach((address) => { + defaultResponse[address] = { + ...defaultBenignResponse, + }; + }); + return reply + .code(200) + .send({ + data: { results: defaultResponse }, + error: ERROR.SCAN_ASSET_DISABLED, + }); }, }); diff --git a/src/service/blockaid/helpers/addScanResults.ts b/src/service/blockaid/helpers/addScanResults.ts index 28d6429..3861928 100644 --- a/src/service/blockaid/helpers/addScanResults.ts +++ b/src/service/blockaid/helpers/addScanResults.ts @@ -3,11 +3,27 @@ import { Logger } from "pino"; import { BlockAidService } from ".."; import { NetworkNames } from "../../../helper/validate"; +export const defaultBenignResponse: Blockaid.Token.TokenScanResponse = { + result_type: "Benign", + malicious_score: "0.0", + attack_types: {}, + chain: "stellar", + address: "", + metadata: { + type: "", + }, + fees: {}, + features: [], + trading_limits: {}, + financial_stats: {}, +}; + export const addScannedStatus = async ( balances: { [key: string]: {} }, blockaidService: BlockAidService, network: NetworkNames, logger: Logger, + useBlockaidAssetScanning: boolean, ) => { const scannedBalances = {} as { [key: string]: { blockaidData: Blockaid.Token.TokenScanResponse }; @@ -33,23 +49,12 @@ export const addScannedStatus = async ( scannedBalances[key] = { ...balanceInfo, blockaidData: { - result_type: "Benign", - malicious_score: "0.0", - attack_types: {}, - chain: "stellar", - address: "", - metadata: { - type: "", - }, - fees: {}, - features: [], - trading_limits: {}, - financial_stats: {}, + ...defaultBenignResponse, }, }; } - if (network === "PUBLIC") { + if (network === "PUBLIC" && useBlockaidAssetScanning) { // we only scan non-native assets on the public network try { const bulkRes = await blockaidService.scanAssetBulk(keyList); diff --git a/src/service/blockaid/index.ts b/src/service/blockaid/index.ts index a2bd26c..333570f 100644 --- a/src/service/blockaid/index.ts +++ b/src/service/blockaid/index.ts @@ -3,6 +3,7 @@ import Prometheus from "prom-client"; import { Logger } from "pino"; import { Networks, TransactionBuilder } from "stellar-sdk"; +import { defaultBenignResponse } from "./helpers/addScanResults"; import { ERROR } from "../../helper/error"; import { NetworkNames } from "../../helper/validate"; @@ -14,6 +15,8 @@ const NetworkNameBlockaid: { TESTNET: "testnet", }; +export type BlockaidAssetScanResponse = Blockaid.Token.TokenScanResponse; + export class BlockAidService { blockAidClient: Blockaid; logger: Logger; @@ -113,7 +116,19 @@ export class BlockAidService { } catch (error) { this.logger.error(error); this.scanMissCounter.inc(); - return { data: null, error: ERROR.UNABLE_TO_SCAN_ASSET }; + const defaultResponse: { + [addres: string]: Blockaid.Token.TokenScanResponse; + } = {}; + addressList.forEach((address) => { + defaultResponse[address] = { + ...defaultBenignResponse, + }; + }); + + return { + data: { results: defaultResponse }, + error: ERROR.UNABLE_TO_SCAN_ASSET, + }; } }; }