Skip to content

Commit

Permalink
Release/1.4.7 (#148)
Browse files Browse the repository at this point in the history
* upgrade blockaid/client and return full blockaid results (#145)

* upgrade blockaid/client and return full blockaid results

* fix tests

* add route to bulk scan assets (#146)

* adds runbook and updates readme

* Bump the minor-and-patch group across 1 directory with 11 updates

Bumps the minor-and-patch group with 11 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@blockaid/client](https://github.com/blockaid-official/blockaid-client-node) | `0.21.0` | `0.25.0` |
| [@sentry/node](https://github.com/getsentry/sentry-javascript) | `8.23.0` | `8.28.0` |
| [@urql/core](https://github.com/urql-graphql/urql/tree/HEAD/packages/core) | `5.0.5` | `5.0.6` |
| [axios](https://github.com/axios/axios) | `1.7.3` | `1.7.7` |
| [pino](https://github.com/pinojs/pino) | `9.3.2` | `9.4.0` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.1.0` | `22.5.4` |
| [@types/yargs](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/yargs) | `17.0.32` | `17.0.33` |
| [husky](https://github.com/typicode/husky) | `9.1.4` | `9.1.5` |
| [lint-staged](https://github.com/lint-staged/lint-staged) | `15.2.8` | `15.2.10` |
| [ts-jest](https://github.com/kulshekhar/ts-jest) | `29.2.4` | `29.2.5` |
| [webpack](https://github.com/webpack/webpack) | `5.93.0` | `5.94.0` |



Updates `@blockaid/client` from 0.21.0 to 0.25.0
- [Release notes](https://github.com/blockaid-official/blockaid-client-node/releases)
- [Changelog](https://github.com/blockaid-official/blockaid-client-node/blob/main/CHANGELOG.md)
- [Commits](blockaid-official/blockaid-client-node@v0.21.0...v0.25.0)

Updates `@sentry/node` from 8.23.0 to 8.28.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](getsentry/sentry-javascript@8.23.0...8.28.0)

Updates `@urql/core` from 5.0.5 to 5.0.6
- [Release notes](https://github.com/urql-graphql/urql/releases)
- [Changelog](https://github.com/urql-graphql/urql/blob/main/packages/core/CHANGELOG.md)
- [Commits](https://github.com/urql-graphql/urql/commits/@urql/[email protected]/packages/core)

Updates `axios` from 1.7.3 to 1.7.7
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](axios/axios@v1.7.3...v1.7.7)

Updates `pino` from 9.3.2 to 9.4.0
- [Release notes](https://github.com/pinojs/pino/releases)
- [Commits](pinojs/pino@v9.3.2...v9.4.0)

Updates `@types/node` from 22.1.0 to 22.5.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@types/yargs` from 17.0.32 to 17.0.33
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/yargs)

Updates `husky` from 9.1.4 to 9.1.5
- [Release notes](https://github.com/typicode/husky/releases)
- [Commits](typicode/husky@v9.1.4...v9.1.5)

Updates `lint-staged` from 15.2.8 to 15.2.10
- [Release notes](https://github.com/lint-staged/lint-staged/releases)
- [Changelog](https://github.com/lint-staged/lint-staged/blob/master/CHANGELOG.md)
- [Commits](lint-staged/lint-staged@v15.2.8...v15.2.10)

Updates `ts-jest` from 29.2.4 to 29.2.5
- [Release notes](https://github.com/kulshekhar/ts-jest/releases)
- [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md)
- [Commits](kulshekhar/ts-jest@v29.2.4...v29.2.5)

Updates `webpack` from 5.93.0 to 5.94.0
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](webpack/webpack@v5.93.0...v5.94.0)

---
updated-dependencies:
- dependency-name: "@blockaid/client"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: "@sentry/node"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: "@urql/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: axios
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: pino
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: "@types/yargs"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: husky
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: lint-staged
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: ts-jest
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: webpack
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <[email protected]>

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: Piyal Basu <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 11, 2024
1 parent 61f3d98 commit be441f7
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 142 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Freighter's indexer integration layer and general backend

You will need

- Node (>=18.0): https://nodejs.org/en/download/
- Node (>=20.0): https://nodejs.org/en/download/
- Yarn (>=v1.22.5): https://classic.yarnpkg.com/en/docs/install

## Development
Expand All @@ -16,6 +16,8 @@ This application relies on a Redis instance when `MODE=production`, you can eith
To start the server in development mode, run:
`yarn i && yarn start`

For full runbook details, please reference [the runbook.](./docs/runbook.md)

## Production build

`yarn build:prod`
Expand Down
57 changes: 57 additions & 0 deletions docs/runbook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
## Prerequisites

- Node (>=20.0): https://nodejs.org/en/download/
- Yarn (>=v1.22.5): https://classic.yarnpkg.com/en/docs/install
- Docker: (optional) https://docs.docker.com/engine/install/

## Environment

| Variable Name | Description |
| ------------------------------------- | -------------------------------------------------------- | ----------- |
| AUTH_EMAIL | Email address used to log in to Mercury(pubnet) |
| AUTH_PASS | Password used to log in to Mercury(pubnet) |
| AUTH_EMAIL_TESTNET | Email address used to log in to Mercury(testnet) |
| AUTH_PASS_TESTNET | Password used to log in to Mercury(testnet) |
| MERCURY_INTEGRITY_CHECK_ACCOUNT_EMAIL | Email address used to log in to Mercury(integrity check) |
| MERCURY_INTEGRITY_CHECK_ACCOUNT_PASS | Password used to log in to Mercury(integrity check) |
| REDIS_CONNECTION_NAME | Redis connection name |
| REDIS_PORT | port for Redis |
| HOSTNAME | hostname Redis is running at |
| MODE | app run move(development | production) |
| USE_MERCURY | flag to toggle use of Mercury |
| SENTRY_KEY | key to configure Sentry instance |
| BLOCKAID_KEY | key to configure Blockaid instance |

Relies on a Redis instance when `MODE=production`, you can either run `docker compose up` to use docker to stand up a Redis or you can start one on the configured port manually. If you're running in development mode, it uses a memory store instead.

## Setup

To install dependencies, run `yarn i`

## Development

Start development server -
`yarn start`

CLI arguments
-e | --env: (optional) Overrides the environment variable set for `MODE`, should be set to `development|production`
-p | --port: (optional) Sets the application port adn defaults to `3002`

## Production Build

`yarn build:prod`

## Testing

Run unit tests with `yarn test`.

## Mercury Integrity Test

In order to test Mercury for data integrity against Horizon, you can configure your env to `USE_MERCURY=true && MODE=production`.
This will result in a worker that continously processes new blocks, queries both Mercury and Horizon for the same transaction, transforms both responses into a common schema, and finally checks for correctness of the results.

In case of an integrity failure, the `USE_MERCURY` redis flag will be flipped to false and the application will fallback to serving requests from Horizon/Rpc.

## Metrics

Metrics are gathered using [Prometheus](https://prometheus.io/docs/introduction/overview/), and a standalone metrics server runs on the standard Prometheus port and exposes a `/metrics` route for collection.
22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@
"node": ">=18.12.0"
},
"dependencies": {
"@blockaid/client": "^0.21.0",
"@blockaid/client": "^0.25.0",
"@fastify/cors": "^9.0.1",
"@fastify/helmet": "^11.1.1",
"@fastify/rate-limit": "^9.1.0",
"@sentry/node": "^8.22.0",
"@sentry/node": "^8.28.0",
"@stellar/js-xdr": "^3.1.2",
"@urql/core": "^5.0.5",
"@urql/core": "^5.0.6",
"ajv": "^8.17.0",
"axios": "^1.7.4",
"axios": "^1.7.7",
"dotenv-expand": "^11.0.6",
"fastify": "^4.28.1",
"ioredis": "^5.4.1",
"pino": "^9.3.2",
"pino": "^9.4.0",
"pino-pretty": "^11.2.2",
"prom-client": "^15.1.3",
"stellar-sdk": "yarn:stellar-sdk@^12.1.0",
Expand All @@ -52,19 +52,19 @@
"@babel/preset-typescript": "^7.24.7",
"@stellar/tsconfig": "^1.0.2",
"@types/jest": "^29.5.12",
"@types/node": "^22.1.0",
"@types/yargs": "^17.0.32",
"@types/node": "^22.5.4",
"@types/yargs": "^17.0.33",
"babel-jest": "^29.7.0",
"dotenv": "^16.4.5",
"husky": "^9.1.4",
"husky": "^9.1.5",
"jest": "^29.7.0",
"lint-staged": "^15.2.8",
"lint-staged": "^15.2.10",
"prettier": "^3.3.3",
"pretty-quick": "^4.0.0",
"ts-jest": "^29.2.4",
"ts-jest": "^29.2.5",
"ts-loader": "^9.5.1",
"typescript": "^5.5.4",
"webpack": "^5.93.0",
"webpack": "^5.94.0",
"webpack-cli": "^5.1.4",
"webpack-node-externals": "^3.0.0"
}
Expand Down
58 changes: 50 additions & 8 deletions src/route/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ jest.mock("@blockaid/client", () => {
"BLND-GATALTGTWIOT6BUDBCZM3Q4OQ4BO2COLOAZ7IYSKPLC2PMSOPPGF5V56"
) {
res[address] = {
result_type: "Malicious",
malicious_score: 1,
};
return;
}

res[address] = {
result_type: "Benign",
malicious_score: 0,
};
});
Expand Down Expand Up @@ -181,13 +183,13 @@ describe("API routes", () => {
expect(
data.balances[
"BLND:GATALTGTWIOT6BUDBCZM3Q4OQ4BO2COLOAZ7IYSKPLC2PMSOPPGF5V56"
].isMalicious,
).toEqual(true);
].blockaidData.result_type,
).toEqual("Malicious");
expect(
data.balances[
"TST:CCWAMYJME4H5CKG7OLXGC2T4M6FL52XCZ3OQOAV6LL3GLA4RO4WH3ASP"
].isMalicious,
).toEqual(false);
].blockaidData.result_type,
).toEqual("Benign");
register.clear();
await server.close();
});
Expand All @@ -213,8 +215,8 @@ describe("API routes", () => {
expect(
data.balances[
"BLND:GATALTGTWIOT6BUDBCZM3Q4OQ4BO2COLOAZ7IYSKPLC2PMSOPPGF5V56"
].isMalicious,
).toEqual(false);
].blockaidData.result_type,
).toEqual("Benign");
register.clear();
await server.close();
});
Expand All @@ -241,8 +243,48 @@ describe("API routes", () => {
expect(
data.balances[
"TST:CDP3XWJ4ZN222LKYBMWIY3GYXZYX3KA6WVNDS6V7WKXSYWLAEMYW7DTZ"
].isMalicious,
).toEqual(false);
].blockaidData.result_type,
).toEqual("Benign");
register.clear();
await server.close();
});
});
describe("/scan-asset-bulk", () => {
it("can scan assets in bulk", async () => {
const asset_ids = [
"BLND-GATALTGTWIOT6BUDBCZM3Q4OQ4BO2COLOAZ7IYSKPLC2PMSOPPGF5V56",
"FOO-CDP3XWJ4ZN222LKYBMWIY3GYXZYX3KA6WVNDS6V7WKXSYWLAEMYW7DTZ",
];
const server = await getDevServer();
const url = new URL(
`http://localhost:${
(server?.server?.address() as any).port
}/api/v1/scan-asset-bulk`,
);
url.searchParams.append("network", "PUBLIC");
for (const id of asset_ids) {
url.searchParams.append("asset_ids", id);
}
const response = await fetch(url.href);
const data = await response.json();

expect(response.status).toEqual(200);
expect(
data.data.results[
"BLND-GATALTGTWIOT6BUDBCZM3Q4OQ4BO2COLOAZ7IYSKPLC2PMSOPPGF5V56"
],
).toEqual({
result_type: "Malicious",
malicious_score: 1,
});
expect(
data.data.results[
"FOO-CDP3XWJ4ZN222LKYBMWIY3GYXZYX3KA6WVNDS6V7WKXSYWLAEMYW7DTZ"
],
).toEqual({
result_type: "Benign",
malicious_score: 0,
});
register.clear();
await server.close();
});
Expand Down
37 changes: 37 additions & 0 deletions src/route/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,43 @@ export async function initApiServer(
},
});

instance.route({
method: "GET",
url: "/scan-asset-bulk",
schema: {
querystring: {
type: "object",
required: ["asset_ids"],
properties: {
["asset_ids"]: {
type: "array",
validator: (qStr: Array<unknown>) =>
qStr
.map((q) => String(q).split("-")[1])
.every((k) => isContractId(k) || isPubKey(k)),
},
},
},
},
handler: async (
request: FastifyRequest<{
Querystring: {
["asset_ids"]: string[];
};
}>,
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);
}
},
});

instance.route({
method: "POST",
url: "/subscription/token",
Expand Down
25 changes: 20 additions & 5 deletions src/service/blockaid/helpers/addScanResults.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Blockaid from "@blockaid/client";
import { Logger } from "pino";
import { BlockAidService } from "..";
import { NetworkNames } from "../../../helper/validate";
Expand All @@ -8,7 +9,9 @@ export const addScannedStatus = async (
network: NetworkNames,
logger: Logger,
) => {
const scannedBalances = {} as { [key: string]: { isMalicious: boolean } };
const scannedBalances = {} as {
[key: string]: { blockaidData: Blockaid.Token.TokenScanResponse };
};
const entries = Object.entries(balances);
const keyList: string[] = [];

Expand All @@ -26,10 +29,23 @@ export const addScannedStatus = async (
}
}

// we set a default for isMalicious that, if we do scan with Blockaid, we will overwrite. Otherwise, we're done
// set a default as Benign. If we do scan with Blockaid, we will overwrite. Otherwise, we're done
scannedBalances[key] = {
...balanceInfo,
isMalicious: false,
blockaidData: {
result_type: "Benign",
malicious_score: "0.0",
attack_types: {},
chain: "stellar",
address: "",
metadata: {
type: "",
},
fees: {},
features: [],
trading_limits: {},
financial_stats: {},
},
};
}

Expand All @@ -44,8 +60,7 @@ export const addScannedStatus = async (
const balKey = `${splitKey[0]}:${splitKey[1]}`;

// overwrite the isMalicious default with the Blockaid scan result
scannedBalances[balKey].isMalicious =
Boolean(Number(val?.malicious_score)) || false;
scannedBalances[balKey].blockaidData = val;
} catch (e) {
logger.error(e);
logger.error(`Failed to process Blockaid scan result: ${key}:${val}`);
Expand Down
Loading

0 comments on commit be441f7

Please sign in to comment.