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

types: export EIP1193Provider and LegacyEthereumProvider interfaces #140

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

legobeat
Copy link
Contributor

@legobeat legobeat commented Sep 13, 2023

Description

This exports two new TypeScript declarations:

Motivation

As far as I know, there is no common explicit interface for the de-facto interface implemented by various Ethereum Json RPC providers. Across the MetaMask npm packages, there are currently use of differing implementations with mostly overlapping interfaces.

This PR introduces a common interface that can be applied regardless of implementations and used in MetaMask packages.

Example of situation where this will be useful

@legobeat legobeat added the question Further information is requested label Sep 13, 2023
@socket-security
Copy link

socket-security bot commented Sep 13, 2023

No top level dependency changes detected. Learn more about Socket for GitHub ↗︎

@socket-security
Copy link

socket-security bot commented Sep 13, 2023

👍 Dependency issues cleared. Learn more about Socket for GitHub ↗︎

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

@legobeat legobeat marked this pull request as ready for review September 13, 2023 06:19
@legobeat legobeat requested a review from a team as a code owner September 13, 2023 06:19
@legobeat
Copy link
Contributor Author

@SocketSecurity ignore @metamask/[email protected]

Copy link
Member

@Mrtenz Mrtenz left a comment

Choose a reason for hiding this comment

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

In Snaps we typically just import MetaMaskInpageProvider from @metamask/providers to get types for this. Do you think it's useful to export this from @metamask/utils?

src/index.ts Outdated Show resolved Hide resolved
src/eth-provider-types.ts Outdated Show resolved Hide resolved
@legobeat
Copy link
Contributor Author

legobeat commented Sep 13, 2023

In Snaps we typically just import MetaMaskInpageProvider from @metamask/providers to get types for this. Do you think it's useful to export this from @metamask/utils?

MetaMaskInpageprovider is a class which would satisfy the interface here. The intention here is to supply that common interface that can be used regardless of implementation when interfacing with internal providers like EthQuery et al.

@legobeat
Copy link
Contributor Author

Related: MetaMask/eth-json-rpc-provider#14

@jiexi
Copy link
Contributor

jiexi commented Oct 3, 2023

looks good. I think we can do without EthJsonRpcProvider as I don't see when we would use the extra properties being defined

@legobeat legobeat force-pushed the types-provider branch 2 times, most recently from 0a8d867 to b759b1a Compare October 4, 2023 04:34
@legobeat
Copy link
Contributor Author

legobeat commented Oct 4, 2023

@legobeat legobeat requested review from a team, Mrtenz and jiexi October 4, 2023 04:36
@legobeat legobeat removed the question Further information is requested label Oct 4, 2023
@legobeat
Copy link
Contributor Author

legobeat commented Oct 4, 2023

@SocketSecurity ignore [email protected]
@SocketSecurity ignore @ethersproject/[email protected]
@SocketSecurity ignore [email protected]

@legobeat legobeat marked this pull request as ready for review October 4, 2023 06:35
Comment on lines +50 to +55
/*
send<Result extends Json = Json>(
method: string,
params: any[],
): Promise<Result>;
*/
Copy link
Contributor

@MajorLift MajorLift Oct 4, 2023

Choose a reason for hiding this comment

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

Does defining send as a generic cause issues? I think this comment should be removed either way.

Copy link
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

In general I'm good with defining a unified legacy type like this as I think it brings our knowledge of these concepts into one place, but considering the abstract nature of the utils package, we should make sure that this type is grounded, i.e., we've tested this type with the libraries we want to support before we merge this to ensure that no type errors occur.


type LegacyEthersProvider = {
/**
* Send a provider request asynchronously. (ethers v5 Web3Provider)
Copy link
Contributor

Choose a reason for hiding this comment

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

To make this a little cleaner, what do you think about adding a comment above LegacyEthersProvider which explains what it represents? My understanding is that this interface represents the portion of Ethers v5's ExternalProvider interface which intersects with our legacy provider — is that correct?

* @param params - Array with method parameters.
* @returns A promise resolving with the result of the RPC call, or rejecting on failure.
*/
send(method: string, params: any[]): Promise<Json>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we trying to align with Ethers v5 here? If so, its signature for send is here: https://github.com/ethers-io/ethers.js/blob/v5.7.2/packages/providers/src.ts/web3-provider.ts#L19

src/json-rpc-provider-types.ts Outdated Show resolved Hide resolved
src/json-rpc-provider-types.ts Show resolved Hide resolved
* @returns A Promise that resolves with the result of the RPC method,
* or rejects if an error is encountered.
*/
request<Params extends JsonRpcParams, Result extends Json>(
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this method signature always compatible with the one in BaseProvider? If not, do we plan on changing BaseProvider to match this?

params: any[],
): Promise<Result>;
*/
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we also need to include sendAsync in this type? Or do we need to define two types for Ethers v5, one that contains send, another that contains sendAsync?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ethers itself (which this is intended to represent) only has send, not sendAsync: https://docs.ethers.org/v5/api/providers/jsonrpc-provider/#JsonRpcProvider-send

src/json-rpc-provider-types.ts Outdated Show resolved Hide resolved
): void;
};

type LegacyWeb3Provider = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need this type? Our provider technically supports send, but it's even more deprecated than sendAsync is. I can't recall a time where we've used it internally.

* @param callback - A function that is called upon the success or failure of the request.
*/
sendAsync<Result extends Json = Json>(
req: Partial<JsonRpcRequest>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, this seems overly strict. The params here can be anything — eth-query / ethjs-query doesn't put a restriction on what they can be.

Where did you derive this type from?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

From here: https://github.com/MetaMask/eth-query/blob/main/index.d.ts

First, we can see here that the missing parts are auto-filled in ethjs-rpc (actual provider for eth-query) so we can at least see that the same interface is implicit.

As for extraneous parameters: On one hand, the more backwards-compatible approach would be something like Json, EverythingButNull or even unknown. But at the same time I'm thinking that users of this type could benefit from spotting unintentionally unsupported API-usage (as any non-standard fields would have to be recognized by the actual provider).

Are we aware of any places where that could already be a thing?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm... I'm wary of doing this, but I don't know why yet. I'll have to think about this.

@legobeat legobeat marked this pull request as draft October 5, 2023 01:39
@legobeat legobeat changed the title types: export EIP1993Provider and LegacyEthereumProvider interfaces types: export EIP1193Provider and LegacyEthereumProvider interfaces Oct 5, 2023
Co-authored-by: Jongsun Suh <[email protected]>
legobeat and others added 2 commits October 10, 2023 23:34
- For proof of correctness see https://tsplay.dev/mpQX7W.
- TODO: move `EverythingButNull` into `misc.ts` and export.
MajorLift added a commit to MetaMask/core that referenced this pull request Oct 13, 2023
## Explanation

This PR implements the following incremental steps in the process for
migrating `eth-json-rpc-provider` into the core monorepo:

***

### Phase B: Staging from `merged-packages/`

#### 5. Port tags 
  - See: #1800
  
<details>  
  <summary>Push ported tags to core repo</summary>
  
- [x]
https://github.com/MetaMask/core/releases/tag/@metamask/[email protected]
- [x]
https://github.com/MetaMask/core/releases/tag/@metamask/[email protected]
- [x]
https://github.com/MetaMask/core/releases/tag/@metamask/[email protected]
- [x]
https://github.com/MetaMask/core/releases/tag/@metamask/[email protected]
- [x]
https://github.com/MetaMask/core/releases/tag/@metamask/[email protected]
</details>

<details>
<summary>Verify that the tag diff links in CHANGELOG are
working</summary>
  
- [x] **WONTFIX**:
https://github.com/MetaMask/core/compare/@metamask/[email protected]
- [x]
https://github.com/MetaMask/core/compare/@metamask/[email protected]...@metamask/[email protected]
- [x]
https://github.com/MetaMask/core/compare/@metamask/[email protected]...@metamask/[email protected]
- [x]
https://github.com/MetaMask/core/compare/@metamask/[email protected]...@metamask/[email protected]
- [x]
https://github.com/MetaMask/core/compare/@metamask/[email protected]...@metamask/[email protected]
</details>

### Phase C: Integration into `packages/`

#### 1. The big leap
- [x] **Move migration target from `migrated-packages/` to
`packages/`.**
- [x] Run `yarn install` in the root directory.
- [x] Check that all tests are passing in migration target by running
`yarn workspace @metamask/<package-name> test`.

#### 2. Update downstream repos
- [x] Add tsconfig reference paths for migration target in downstream
packages and root.
- [x] Bump migration target version in downstream packages and root.

#### 3. Linter fixes
- [x] Apply yarn constraints fixes to migration target package.json
file: `yarn constraints --fix` (run twice).
- [x] Identify validator fixes for CHANGELOG using `yarn workspace
@metamask/<package-name> changelog:validate` and apply the diffs.

#### 4. Resolve downstream errors
- [x] #1653
  - If introducing the migration target breaks any downstream repos:
    - [x] Resolve simple errors
- [x] Mark and ignore complex errors using `@ts-expect-error TODO:`
annotations.
- [x] Create a separate issue for resolving the marked errors as soon as
the migration is completed.

#### 5. Finalize merge
- [x] Check that all tests are passing in all subpackages of core and
CI.
- [x] Merge `packages/<package-name>` directory into core main branch.

***

See #1551 (comment)
for an outline of the entire process.

## Next Steps

- The next PR(s) will implement the final steps of the migration process
(D-1 in the migration checklist).

## Blocked by
- Dependencies:
  - [x] typescript bump: #1718
- [x] `@metamask/utils` bump: #1639
- Downstream type errors:
  - [x] #1653
- [ ] MetaMask/eth-json-rpc-provider#14
(ignored)
  - [ ] MetaMask/utils#140 (ignored)
- Tag porting:
  - [x] #1802
- [x] "Unreleased" tag diff link shows entire history of core:
https://github.com/MetaMask/core/compare/@metamask/[email protected]

## References

- Contributes to #1685
- Contributes to #1551

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/eth-json-rpc-provider`

- **ADDED**: Migrated into the core monorepo.

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
@rekmarks rekmarks removed their request for review February 9, 2024 22:02
@Mrtenz Mrtenz removed their request for review March 1, 2024 09:01
@FrederikBolding FrederikBolding removed their request for review April 19, 2024 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants