Skip to content

Commit 2532b02

Browse files
authored
Add initial bridge implementation (#1767)
1 parent cea6a43 commit 2532b02

23 files changed

+1779
-1001
lines changed

.env.template

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
API_URL=http://localhost:8003
22
BLOCK_EXPLORER_URL=http://localhost:3000
33
BLOCK_LOADER_TRANSACTION_TIMEOUT=5000
4+
CHAINPORT_API_URL=https://preprod-api.chainport.io/
5+
CHAINPORT_API_VERSION=2
6+
CHAINPORT_NETWORK_ID=22
47
CORS_ENABLED=true
58
DATABASE_CONNECTION_POOL_URL=postgres://postgres:password@localhost:5432/ironfish_api_development
69
DATABASE_URL=postgres://postgres:password@localhost:5432/ironfish_api_development

.env.test

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
API_URL=http://localhost:8003
22
BLOCK_EXPLORER_URL=test
33
BLOCK_LOADER_TRANSACTION_TIMEOUT=5000
4+
CHAINPORT_API_URL=https://preprod-api.chainport.io/
5+
CHAINPORT_API_VERSION=2
6+
CHAINPORT_NETWORK_ID=22
47
CORS_ENABLED=true
58
DATABASE_CONNECTION_POOL_URL=postgres://postgres:password@localhost:5432/ironfish_api_test
69
DATABASE_URL=postgres://postgres:password@localhost:5432/ironfish_api_test

package.json

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"@types/compression": "1.7.5",
4040
"@types/express": "4.17.20",
4141
"@types/faker": "5.5.9",
42-
"@types/jest": "27.5.0",
42+
"@types/jest": "29.5.13",
4343
"@types/passport": "1.0.14",
4444
"@types/semver": "7.5.3",
4545
"@types/supertest": "2.0.15",
@@ -55,9 +55,9 @@
5555
"eslint-plugin-prettier": "4.2.1",
5656
"eslint-plugin-simple-import-sort": "10.0.0",
5757
"faker": "5.5.3",
58-
"jest": "27.5.1",
58+
"jest": "29.7.0",
5959
"prettier": "2.8.8",
60-
"prisma": "5.13.0",
60+
"prisma": "5.20.0",
6161
"run-script-webpack-plugin": "0.2.0",
6262
"supertest": "6.3.3",
6363
"ts-jest": "29.1.1",
@@ -70,18 +70,20 @@
7070
},
7171
"dependencies": {
7272
"@influxdata/influxdb-client": "1.33.2",
73+
"@nestjs/axios": "3.0.3",
7374
"@nestjs/common": "8.4.7",
7475
"@nestjs/config": "3.1.1",
7576
"@nestjs/core": "8.4.7",
7677
"@nestjs/microservices": "8.4.7",
7778
"@nestjs/passport": "10.0.2",
7879
"@nestjs/platform-express": "8.4.7",
7980
"@nestjs/swagger": "5.2.1",
80-
"@prisma/client": "5.13.0",
81+
"@prisma/client": "5.20.0",
8182
"@sindresorhus/is": "4.6.0",
8283
"assert": "2.0.0",
84+
"axios": "1.7.7",
8385
"class-transformer": "0.5.1",
84-
"class-validator": "0.13.2",
86+
"class-validator": "0.14.1",
8587
"cluster": "0.7.7",
8688
"compression": "1.7.4",
8789
"dd-trace": "4.16.0",

src/app.module.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { AuthModule } from './auth/auth.module';
1717
import { BlocksRestModule } from './blocks/blocks.rest.module';
1818
import { BlocksDailyJobsModule } from './blocks-daily/blocks-daily.jobs.module';
1919
import { BlocksDailyRestModule } from './blocks-daily/blocks-daily.rest.module';
20+
import { BridgesRestModule } from './bridges/bridges.rest.module';
2021
import { RequireSslMiddleware } from './common/middlewares/require-ssl.middleware';
2122
import { DatadogModule } from './datadog/datadog.module';
2223
import { FaucetTransactionsRestModule } from './faucet-transactions/faucet-transactions.rest.module';
@@ -34,6 +35,7 @@ export const REST_MODULES = [
3435
AssetsRestModule,
3536
BlocksDailyRestModule,
3637
BlocksRestModule,
38+
BridgesRestModule,
3739
FaucetTransactionsRestModule,
3840
HealthRestModule,
3941
SupplyRestModule,
@@ -52,6 +54,9 @@ export const REST_MODULES = [
5254
API_URL: joi.string().required(),
5355
BLOCK_EXPLORER_URL: joi.string().required(),
5456
BLOCK_LOADER_TRANSACTION_TIMEOUT: joi.number().optional(),
57+
CHAINPORT_API_URL: joi.string().required(),
58+
CHAINPORT_API_VERSION: joi.number().required(),
59+
CHAINPORT_NETWORK_ID: joi.string().required(),
5560
CORS_ENABLED: joi.boolean().default(true),
5661
DATABASE_CONNECTION_POOL_URL: joi.string().required(),
5762
DATABASE_URL: joi.string().required(),

src/asset-descriptions/__snapshots__/asset-descriptions.controller.spec.ts.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

33
exports[`AssetDescriptionsController GET /asset_descriptions with an invalid query returns a 422 1`] = `
4-
Object {
4+
{
55
"error": "Unprocessable Entity",
6-
"message": Array [
7-
"\\"asset\\" required to query for asset descriptions",
6+
"message": [
7+
""asset" required to query for asset descriptions",
88
"asset must be a string",
99
],
1010
"statusCode": 422,

src/assets/__snapshots__/assets.controller.spec.ts.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

33
exports[`AssetsController GET /assets/find with an invalid query returns a 422 1`] = `
4-
Object {
4+
{
55
"error": "Unprocessable Entity",
6-
"message": Array [
7-
"\\"id\\" required to query for asset",
6+
"message": [
7+
""id" required to query for asset",
88
"id must be a string",
99
],
1010
"statusCode": 422,

src/blocks/__snapshots__/blocks.controller.spec.ts.snap

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

33
exports[`BlocksController GET /blocks with invalid sequence_gte and sequence_lt parameters when sequence_gte > sequence_lt returns a 422 1`] = `
4-
Object {
4+
{
55
"error": "Unprocessable Entity",
66
"message": "'sequence_gte' must be strictly less than 'sequence_lt'.",
77
"statusCode": 422,
88
}
99
`;
1010

1111
exports[`BlocksController GET /blocks with invalid sequence_gte and sequence_lt parameters when sequence_gte and sequence_lt are not at least 1 returns a 422 1`] = `
12-
Object {
12+
{
1313
"error": "Unprocessable Entity",
14-
"message": Array [
14+
"message": [
1515
"sequence_gte must not be less than 1",
1616
"sequence_lt must not be less than 1",
1717
],
@@ -20,27 +20,27 @@ Object {
2020
`;
2121

2222
exports[`BlocksController GET /blocks with invalid sequence_gte and sequence_lt parameters when the range is too long returns a 422 1`] = `
23-
Object {
23+
{
2424
"error": "Unprocessable Entity",
2525
"message": "Range is too long. Max sequence difference is 1000.",
2626
"statusCode": 422,
2727
}
2828
`;
2929

3030
exports[`BlocksController GET /blocks/find with neither a matching hash nor sequence returns a 404 1`] = `
31-
Object {
31+
{
3232
"message": "Not Found",
3333
"statusCode": 404,
3434
}
3535
`;
3636

3737
exports[`BlocksController GET /blocks/find with neither a valid hash nor sequence returns a 422 1`] = `
38-
Object {
38+
{
3939
"error": "Unprocessable Entity",
40-
"message": Array [
41-
"\\"hash\\" or \\"sequence\\" required to query for single block",
40+
"message": [
41+
""hash" or "sequence" required to query for single block",
4242
"hash must be a string",
43-
"\\"hash\\" or \\"sequence\\" required to query for single block",
43+
""hash" or "sequence" required to query for single block",
4444
"sequence must be an integer number",
4545
"sequence must not be less than 1",
4646
"sequence must not be greater than 9007199254740991",
@@ -50,57 +50,57 @@ Object {
5050
`;
5151

5252
exports[`BlocksController GET /blocks/metrics with a time range longer than the supported range returns a 422 1`] = `
53-
Object {
53+
{
5454
"error": "Unprocessable Entity",
5555
"message": "Time range too long",
5656
"statusCode": 422,
5757
}
5858
`;
5959

6060
exports[`BlocksController GET /blocks/metrics with invalid granularity returns a 422 1`] = `
61-
Object {
61+
{
6262
"error": "Unprocessable Entity",
63-
"message": "\\"granularity\\" must be \\"day\\"",
63+
"message": ""granularity" must be "day"",
6464
"statusCode": 422,
6565
}
6666
`;
6767

6868
exports[`BlocksController GET /blocks/metrics with missing arguments returns a 422 1`] = `
69-
Object {
69+
{
7070
"error": "Unprocessable Entity",
71-
"message": Array [
71+
"message": [
7272
"start must be a Date instance",
7373
"end must be a Date instance",
74-
"granularity must be a valid enum value",
74+
"granularity must be one of the following values: day, lifetime, total",
7575
],
7676
"statusCode": 422,
7777
}
7878
`;
7979

8080
exports[`BlocksController GET /blocks/metrics with start after end returns a 422 1`] = `
81-
Object {
81+
{
8282
"error": "Unprocessable Entity",
83-
"message": "\\"start\\" must be stricly less than \\"end\\"",
83+
"message": ""start" must be strictly less than "end"",
8484
"statusCode": 422,
8585
}
8686
`;
8787

8888
exports[`BlocksController POST /blocks with a missing api key returns a 401 1`] = `
89-
Object {
89+
{
9090
"message": "Unauthorized",
9191
"statusCode": 401,
9292
}
9393
`;
9494

9595
exports[`BlocksController POST /blocks with missing arguments returns a 422 1`] = `
96-
Object {
96+
{
9797
"error": "Unprocessable Entity",
98-
"message": Array [
98+
"message": [
9999
"blocks.0.hash must be a string",
100100
"blocks.0.sequence must be an integer number",
101101
"blocks.0.sequence must not be greater than 9007199254740991",
102102
"blocks.0.difficulty must be an integer number",
103-
"blocks.0.type must be a valid enum value",
103+
"blocks.0.type must be one of the following values: connected, disconnected, fork",
104104
"blocks.0.timestamp must be a Date instance",
105105
"blocks.0.graffiti must be a string",
106106
"blocks.0.size must be a positive number",
@@ -114,26 +114,26 @@ Object {
114114
`;
115115

116116
exports[`BlocksController POST /blocks with too many blocks returns a 422 1`] = `
117-
Object {
117+
{
118118
"error": "Unprocessable Entity",
119-
"message": Array [
120-
"blocks must contain not more than 3000 elements",
119+
"message": [
120+
"blocks must contain no more than 3000 elements",
121121
],
122122
"statusCode": 422,
123123
}
124124
`;
125125

126126
exports[`BlocksController POST /blocks/disconnect with a missing api key returns a 401 1`] = `
127-
Object {
127+
{
128128
"message": "Unauthorized",
129129
"statusCode": 401,
130130
}
131131
`;
132132

133133
exports[`BlocksController POST /blocks/disconnect with missing arguments returns a 422 1`] = `
134-
Object {
134+
{
135135
"error": "Unprocessable Entity",
136-
"message": Array [
136+
"message": [
137137
"sequence_gt must be an integer number",
138138
"sequence_gt must not be less than 1",
139139
"sequence_gt must not be greater than 9007199254740991",

src/blocks/blocks.controller.spec.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { GraphileWorkerService } from '../graphile-worker/graphile-worker.servic
1212
import { PrismaService } from '../prisma/prisma.service';
1313
import { bootstrapTestApp } from '../test/test-app';
1414
import { BlocksService } from './blocks.service';
15-
import { UpsertBlocksDto } from './dto/upsert-blocks.dto';
15+
import { BlockDto, UpsertBlocksDto } from './dto/upsert-blocks.dto';
1616
import { BlockOperation } from './enums/block-operation';
1717
import { SerializedBlockWithTransactions } from './interfaces/serialized-block-with-transactions';
1818

@@ -85,7 +85,7 @@ describe('BlocksController', () => {
8585

8686
describe('with too many blocks', () => {
8787
it('returns a 422', async () => {
88-
const blocks = [];
88+
const blocks: BlockDto[] = [];
8989
for (let i = 0; i < 3001; i++) {
9090
blocks.push({
9191
hash: uuid(),
@@ -94,7 +94,6 @@ describe('BlocksController', () => {
9494
type: BlockOperation.CONNECTED,
9595
sequence: faker.datatype.number(),
9696
timestamp: new Date(),
97-
transactions_count: 0,
9897
graffiti: uuid(),
9998
previous_block_hash: uuid(),
10099
size: faker.datatype.number({ min: 1 }),

src/blocks/blocks.controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ export class BlocksController {
319319
if (start >= end) {
320320
return {
321321
isValid: false,
322-
error: '"start" must be stricly less than "end"',
322+
error: '"start" must be strictly less than "end"',
323323
};
324324
}
325325

0 commit comments

Comments
 (0)