Skip to content

Commit d841e26

Browse files
Add EVM-compatible JSON RPC wrapper to Paima (#407)
* Introduct JSON-RPC wrapper * remove unused packages * Implement cache * Add more endpoints * work towards block/tx endpoints * Finish remaining TODOs * Fix weird eslint bug * more eslint fixes * PR feedback
1 parent efab497 commit d841e26

35 files changed

+3631
-382
lines changed

package-lock.json

Lines changed: 369 additions & 218 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/batcher/runtime/src/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,11 @@ async function main(): Promise<void> {
170170
}
171171

172172
const pool = initializePool();
173+
const backendVersion = await getRemoteBackendVersion();
174+
if (backendVersion.success == false) throw new Error(backendVersion.errorMessage);
173175
await initMiddlewareCore(
174176
'Game Batcher', // TODO: it doesn't matter now, but there is no way for the batcher to get the name of the game
175-
await getRemoteBackendVersion()
177+
backendVersion.result
176178
);
177179
let provider: EthersEvmProvider | AvailJsProvider;
178180
let batchedTransactionPoster;

packages/engine/paima-rest/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
"author": "Paima Studios",
1515
"dependencies": {
1616
"express": "^4.18.1",
17-
"yaml": "^2.3.1",
18-
"tsoa": "^6.0.0"
17+
"http-status-codes": "^2.3.0",
18+
"tsoa": "^6.0.0",
19+
"yaml": "^2.3.1"
1920
},
2021
"devDependencies": {
2122
"@types/cors": "^2.8.12",

packages/engine/paima-rest/src/controllers/AchievementsController.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ import {
99
type PlayerAchievements,
1010
type Validity,
1111
} from '@paima/utils-backend';
12-
import { Controller, Get, Header, Path, Query, Route } from 'tsoa';
12+
import { Controller, Get, Header, Path, Query, Response, Route } from 'tsoa';
1313
import { EngineService } from '../EngineService.js';
14+
import { StatusCodes } from 'http-status-codes';
15+
import type {
16+
FailedResult,
17+
InternalServerErrorResult,
18+
ValidateErrorResult,
19+
} from './BasicControllers.js';
1420

1521
// ----------------------------------------------------------------------------
1622
// Controller and routes per PRC-1
@@ -38,21 +44,24 @@ export class AchievementsController extends Controller {
3844
private async meta(): Promise<AchievementMetadata> {
3945
const meta = EngineService.INSTANCE.achievements;
4046
if (!meta) {
41-
this.setStatus(501);
47+
this.setStatus(StatusCodes.NOT_IMPLEMENTED);
4248
throw new Error('Achievements are not supported by this game');
4349
}
4450
return await meta;
4551
}
4652

4753
private async validity(): Promise<Validity> {
4854
return {
49-
// Note: will need updating when we support non-EVM data availability layers.
55+
// TODO: will need updating when we support non-EVM data availability layers.
5056
caip2: `eip155:${ENV.CHAIN_ID}`,
5157
block: await EngineService.INSTANCE.getSM().latestProcessedBlockHeight(),
5258
time: new Date().toISOString(),
5359
};
5460
}
5561

62+
@Response<FailedResult>(StatusCodes.NOT_IMPLEMENTED)
63+
@Response<InternalServerErrorResult>(StatusCodes.INTERNAL_SERVER_ERROR)
64+
@Response<ValidateErrorResult>(StatusCodes.UNPROCESSABLE_ENTITY)
5665
@Get('public/list')
5766
public async public_list(
5867
@Query() category?: string,
@@ -78,6 +87,8 @@ export class AchievementsController extends Controller {
7887
};
7988
}
8089

90+
@Response<InternalServerErrorResult>(StatusCodes.INTERNAL_SERVER_ERROR)
91+
@Response<ValidateErrorResult>(StatusCodes.UNPROCESSABLE_ENTITY)
8192
@Get('wallet/{wallet}')
8293
public async wallet(
8394
@Path() wallet: string,
@@ -115,6 +126,10 @@ export class AchievementsController extends Controller {
115126
};
116127
}
117128

129+
@Response<FailedResult>(StatusCodes.NOT_FOUND)
130+
@Response<FailedResult>(StatusCodes.NOT_IMPLEMENTED)
131+
@Response<InternalServerErrorResult>(StatusCodes.INTERNAL_SERVER_ERROR)
132+
@Response<ValidateErrorResult>(StatusCodes.UNPROCESSABLE_ENTITY)
118133
@Get('erc/{erc}/{cde}/{token_id}')
119134
public async nft(
120135
@Path() erc: string,
@@ -131,12 +146,12 @@ export class AchievementsController extends Controller {
131146
return await this.wallet(wallet, name);
132147
} else {
133148
// Future improvement: throw a different error if no CDE with that name exists
134-
this.setStatus(404);
149+
this.setStatus(StatusCodes.NOT_FOUND);
135150
throw new Error('No owner for that NFT');
136151
}
137152
// Future improvement: erc6551
138153
default:
139-
this.setStatus(404);
154+
this.setStatus(StatusCodes.NOT_IMPLEMENTED);
140155
throw new Error(`No support for /erc/${erc}`);
141156
}
142157
}

0 commit comments

Comments
 (0)