Skip to content

Commit

Permalink
Release/1.4.8 (#152)
Browse files Browse the repository at this point in the history
* adds a mercury integration guide

* adds transformer section

* adds link to Mercury docs

* Bump find-my-way from 8.2.0 to 8.2.2 in the npm_and_yarn group

Bumps the npm_and_yarn group with 1 update: [find-my-way](https://github.com/delvedor/find-my-way).


Updates `find-my-way` from 8.2.0 to 8.2.2
- [Release notes](https://github.com/delvedor/find-my-way/releases)
- [Commits](delvedor/find-my-way@v8.2.0...v8.2.2)

---
updated-dependencies:
- dependency-name: find-my-way
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

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

* Feature/blockaid flags (#161)

* add individual flags for blockaid scanning

* fix tests

* add tests

* better default setting for dapp scanning

* better catch default for scan-site

---------

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Piyal Basu <[email protected]>
  • Loading branch information
3 people authored Oct 14, 2024
1 parent c6542c0 commit 1d6f952
Show file tree
Hide file tree
Showing 11 changed files with 316 additions and 57 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ For full runbook details, please reference [the runbook.](./docs/runbook.md)
## Mercury Details

This project integrates with Mercury, an indexer for Stellar/Soroban. You can find general developer documentation (in their repo docs)[https://github.com/xycloo/merury-developers-documentation/blob/main/src/SUMMARY.md].

For full integration details, see [the Mercury docs](./docs/mercury.md).
64 changes: 64 additions & 0 deletions docs/mercury.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Mercury Integration Guide

Freighter's backend relies on data that is ingested and indexed by Mercury in order to serve different wallet views.

Mercury is an indexer and API built on Stellar, [see docs for more info.](https://www.mercurydata.app/)
It allows users to subscribe to data on the network and query indexed data using a GraphQL API.

## Playground

To learn more about the available queries or to construct queries, you can use [the playground.](https://api.mercurydata.app:2083/graphiql)

Playground steps -

1. Aquire an access token by signing up for an account on the dashboard.

Testnet - https://test.mercurydata.app/
Pubnet - https://main.mercurydata.app/

Select "Get Access token" under Active Subscriptions and grab your token.

2. Add your access token to the playground.

You can add your token to be used in the requests the playground makes.
Click on the headers tab on the left pane at the bottom and add it in the following format -

```
{
Authorization: "Bearer <TOKEN>"
}
```

3. Query for data in subscriptions
At this point you can query for any data that you have a subscription on, for example to get `changeTrust` operations for an account you could run this query -

```
query Test {
changeTrustByPublicKey(publicKeyText:"<PUBLIC_KEY>") {
edges {
node {
opId
...
}
}
}
}
```

## Subscriptions

In order to query data, you must subscribe to it first. Mercury supports subscription APIs for contract events, ledger entries, ledger entry expirations, and accounts.

See [full docs](https://docs.mercurydata.app/mercury-classic/subscriptions/api-definition) for more info.

## Adding a new query

Mercury queries can be added by adding a new key to the `query` map in the [queries file](../src/service/mercury/queries.ts).
Queries are stored as template strings that represent the GraphQL query. Arguments can be passed by writing the query as a function and interpolating the arguments into the template string.

Queries can be imported into anything that accepts GraphQL documents.

## Usage in public facing routes

The account history and account balance queries are used to serve public facing routes, we use [transformers](../src/service/mercury/helpers/transformers.ts) to process this data from Mercury in order to maintain schema compatibility with Horizon/RPC responses.
Any changes to these queries should be accompanied by an update to the corresponding transformer in order align with Horizon schemas used in the transformer.
6 changes: 6 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ export function buildConfig(config: Record<string, string | undefined>) {
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,
},
};
}

Expand Down
3 changes: 3 additions & 0 deletions src/helper/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
};
25 changes: 16 additions & 9 deletions src/helper/test-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ function backendClientMaker(network: NetworkNames) {
}
case query.getTokenBalanceSub(
"CBGTG7XFRY3L6OKAUTR6KGDKUXUQBX3YDJ3QFDYTGVMOM7VV4O7NCODG",
tokenBalanceLedgerKey
tokenBalanceLedgerKey,
): {
return Promise.resolve({
data: {
Expand All @@ -123,7 +123,7 @@ function backendClientMaker(network: NetworkNames) {
}
case query.getTokenBalanceSub(
"CCWAMYJME4H5CKG7OLXGC2T4M6FL52XCZ3OQOAV6LL3GLA4RO4WH3ASP",
tokenBalanceLedgerKey
tokenBalanceLedgerKey,
): {
return Promise.resolve({
data: {
Expand All @@ -141,7 +141,7 @@ function backendClientMaker(network: NetworkNames) {
}
case query.getTokenBalanceSub(
"CDP3XWJ4ZN222LKYBMWIY3GYXZYX3KA6WVNDS6V7WKXSYWLAEMYW7DTZ",
tokenBalanceLedgerKey
tokenBalanceLedgerKey,
): {
return Promise.resolve({
data: {
Expand All @@ -160,7 +160,7 @@ function backendClientMaker(network: NetworkNames) {
case query.getCurrentDataAccountBalances(
pubKey,
tokenBalanceLedgerKey,
[]
[],
): {
return Promise.resolve({
data: queryMockResponse["query.getAccountBalancesCurrentData"],
Expand Down Expand Up @@ -592,7 +592,7 @@ const mockMercuryClient = new MercuryClient(
mercuryErrorCounter,
rpcErrorCounter,
criticalError,
}
},
);
jest.mock("@blockaid/client", () => {
return class Blockaid {};
Expand All @@ -601,7 +601,7 @@ const blockAidClient = new Blockaid();
const blockAidService = new BlockAidService(
blockAidClient,
testLogger,
register
register,
);

jest
Expand All @@ -613,17 +613,24 @@ jest
decimals: 7,
symbol: "TST",
};
}
},
);
async function getDevServer() {
async function getDevServer(
blockaidConfig = {
useBlockaidAssetScanning: true,
useBlockaidDappScanning: true,
useBlockaidTxScanning: true,
},
) {
const server = await initApiServer(
mockMercuryClient,
blockAidService,
testLogger,
true,
true,
register,
"development"
"development",
blockaidConfig,
);

await server.listen();
Expand Down
7 changes: 4 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ async function main() {
renewClientMaker: buildRenewClientMaker(graphQlEndpoints),
backendClientMaker: buildBackendClientMaker(graphQlEndpoints),
currentDataClientMaker: buildCurrentDataClientMaker(
graphQlCurrentDataEndpoints
graphQlCurrentDataEndpoints,
),
backends,
credentials: {
Expand Down Expand Up @@ -130,7 +130,7 @@ async function main() {
rpcErrorCounter,
criticalError,
},
redis
redis,
);
const server = await initApiServer(
mercuryClient,
Expand All @@ -140,7 +140,8 @@ async function main() {
conf.useSorobanPublic,
register,
env as mode,
redis
conf.blockaidConfig,
redis,
);
const metricsServer = await initMetricsServer(register, redis);

Expand Down
110 changes: 110 additions & 0 deletions src/route/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from "../helper/test-helper";
import { transformAccountHistory } from "../service/mercury/helpers/transformers";
import { query } from "../service/mercury/queries";
import { defaultBenignResponse } from "../service/blockaid/helpers/addScanResults";

jest.mock("@blockaid/client", () => {
return class Blockaid {
Expand Down Expand Up @@ -41,6 +42,24 @@ jest.mock("@blockaid/client", () => {
return Promise.resolve({ results: res });
},
};
token = {
scan: ({ address }: { address: string }) => {
if (
address ===
"BLND-GATALTGTWIOT6BUDBCZM3Q4OQ4BO2COLOAZ7IYSKPLC2PMSOPPGF5V56"
) {
return Promise.resolve({
result_type: "Malicious",
malicious_score: 1,
});
}

return Promise.resolve({
result_type: "Benign",
malicious_score: 0,
});
},
};
};
});

Expand Down Expand Up @@ -288,5 +307,96 @@ describe("API routes", () => {
register.clear();
await server.close();
});
it("does not scan assets when config is disabled", async () => {
const asset_ids = [
"BLND-GATALTGTWIOT6BUDBCZM3Q4OQ4BO2COLOAZ7IYSKPLC2PMSOPPGF5V56",
"FOO-CDP3XWJ4ZN222LKYBMWIY3GYXZYX3KA6WVNDS6V7WKXSYWLAEMYW7DTZ",
];
const server = await getDevServer({
useBlockaidAssetScanning: false,
useBlockaidDappScanning: false,
useBlockaidTxScanning: false,
});
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({
...defaultBenignResponse,
});
expect(
data.data.results[
"FOO-CDP3XWJ4ZN222LKYBMWIY3GYXZYX3KA6WVNDS6V7WKXSYWLAEMYW7DTZ"
],
).toEqual({
...defaultBenignResponse,
});
register.clear();
await server.close();
});
});
describe("/scan-asset", () => {
it("can scan an asset", async () => {
const server = await getDevServer();
const url = new URL(
`http://localhost:${
(server?.server?.address() as any).port
}/api/v1/scan-asset`,
);
url.searchParams.append(
"address",
"BLND-GATALTGTWIOT6BUDBCZM3Q4OQ4BO2COLOAZ7IYSKPLC2PMSOPPGF5V56",
);
const response = await fetch(url.href);
const data = await response.json();

expect(response.status).toEqual(200);
expect(data.data).toEqual({
result_type: "Malicious",
malicious_score: 1,
});
register.clear();
await server.close();
});
it("does not scan an asset when config is disabled", async () => {
const server = await getDevServer({
useBlockaidAssetScanning: false,
useBlockaidDappScanning: false,
useBlockaidTxScanning: false,
});
const url = new URL(
`http://localhost:${
(server?.server?.address() as any).port
}/api/v1/scan-asset`,
);
url.searchParams.append(
"address",
"BLND-GATALTGTWIOT6BUDBCZM3Q4OQ4BO2COLOAZ7IYSKPLC2PMSOPPGF5V56",
);
const response = await fetch(url.href);
const data = await response.json();

expect(response.status).toEqual(200);
expect(data.data).toEqual({
...defaultBenignResponse,
address:
"BLND-GATALTGTWIOT6BUDBCZM3Q4OQ4BO2COLOAZ7IYSKPLC2PMSOPPGF5V56",
});
register.clear();
await server.close();
});
});
});
Loading

0 comments on commit 1d6f952

Please sign in to comment.