Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The invalid type Record<never, never> removed from return type #4609

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,82 @@ describe('SafeEventEmitterProvider', () => {
expect(result).toBe(42);
});

it('handles a successful EIP-1193 object request without params', async () => {
const engine = new JsonRpcEngine();
let req: JsonRpcRequest | undefined;
engine.push((_req, res, _next, end) => {
req = _req;
res.result = 42;
end();
});
const provider = new SafeEventEmitterProvider({ engine });
const exampleRequest = {
method: 'test',
};
jest.spyOn(uuid, 'v4').mockReturnValueOnce('mock-id');

const result = await provider.request(exampleRequest);

expect(req).toStrictEqual({
id: 'mock-id',
jsonrpc: '2.0' as const,
method: 'test',
});
expect(result).toBe(42);
});

it('handles a successful EIP-1193 object request with params empty object', async () => {
const engine = new JsonRpcEngine();
let req: JsonRpcRequest | undefined;
engine.push((_req, res, _next, end) => {
req = _req;
res.result = 42;
end();
});
const provider = new SafeEventEmitterProvider({ engine });
const exampleRequest = {
method: 'test',
params: {},
};
jest.spyOn(uuid, 'v4').mockReturnValueOnce('mock-id');

const result = await provider.request(exampleRequest);

expect(req).toStrictEqual({
id: 'mock-id',
jsonrpc: '2.0' as const,
method: 'test',
params: {},
});
expect(result).toBe(42);
});

it('handles a successful EIP-1193 object request with params empty array', async () => {
const engine = new JsonRpcEngine();
let req: JsonRpcRequest | undefined;
engine.push((_req, res, _next, end) => {
req = _req;
res.result = 42;
end();
});
const provider = new SafeEventEmitterProvider({ engine });
const exampleRequest = {
method: 'test',
params: [],
};
jest.spyOn(uuid, 'v4').mockReturnValueOnce('mock-id');

const result = await provider.request(exampleRequest);

expect(req).toStrictEqual({
id: 'mock-id',
jsonrpc: '2.0' as const,
method: 'test',
params: [],
});
expect(result).toBe(42);
});

it('handles a failure with a non-JSON-RPC error', async () => {
const engine = new JsonRpcEngine();
engine.push((_req, _res, _next, end) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { v4 as uuidV4 } from 'uuid';
/**
* A JSON-RPC request conforming to the EIP-1193 specification.
*/
type Eip1193Request<Params extends JsonRpcParams> = {
type Eip1193Request<Params extends JsonRpcParams = JsonRpcParams> = {
id?: JsonRpcId;
jsonrpc?: JsonRpcVersion2;
method: string;
Expand All @@ -26,11 +26,9 @@ type Eip1193Request<Params extends JsonRpcParams> = {
* @param eip1193Request - The EIP-1193 request to convert.
* @returns The corresponding JSON-RPC request.
*/
export function convertEip1193RequestToJsonRpcRequest<
Params extends JsonRpcParams,
>(
eip1193Request: Eip1193Request<Params>,
): JsonRpcRequest<Params | Record<never, never>> {
export function convertEip1193RequestToJsonRpcRequest(
eip1193Request: Eip1193Request,
): JsonRpcRequest {
Comment on lines +29 to +31
Copy link
Contributor

@MajorLift MajorLift Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, I think this function needs to be generic over Params. It would potentially be unusable downstream without an exposed way to narrow the params property of the return object.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In EIP 1193 optional params is unknown[] | object. And here we have assigned the same using JsonRpcParams (it's a default type for params). So it has to be of this type. Just thinking, in which case we need this to be beyond this type?

const { id = uuidV4(), jsonrpc = '2.0', method, params } = eip1193Request;
return params
? {
Expand Down Expand Up @@ -78,15 +76,10 @@ export class SafeEventEmitterProvider extends SafeEventEmitter {
* @param eip1193Request - The request to send.
* @returns The JSON-RPC response.
*/
async request<Params extends JsonRpcParams, Result extends Json>(
eip1193Request: Eip1193Request<Params>,
): Promise<Result> {
async request(eip1193Request: Eip1193Request): Promise<Json> {
Copy link
Contributor

@MajorLift MajorLift Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't request still be generic over Params and Result? This seems like a fundamental alteration of the EIP-1193 provider API that would make it unusable in many downstream call sites.

We should check whether this change breaks downstream packages using a preview build of this branch.

const jsonRpcRequest =
convertEip1193RequestToJsonRpcRequest(eip1193Request);
const response = await this.#engine.handle<
Params | Record<never, never>,
Result
>(jsonRpcRequest);
const response = await this.#engine.handle(jsonRpcRequest);

if ('result' in response) {
return response.result;
Expand Down
Loading