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

any type in asset-controller classes have been fixed with a proper types #3818

Merged
merged 16 commits into from
Feb 9, 2024

Conversation

kanthesha
Copy link
Contributor

@kanthesha kanthesha commented Jan 23, 2024

Explanation

Replace use of any with proper types (non-test files only) in asset-controller.

Changelog

@metamask/assets-controllers

  • BREAKING: Change type of provider property in AssetsContractController from any to Provider from @metamask/network-controller.
  • BREAKING: Change type of provider property in TokensController from any to Provider from @metamask/network-controller.

References

@@ -177,7 +175,9 @@ export class AssetsContractController extends BaseControllerV1<
*/
getProvider(networkClientId?: NetworkClientId): Web3Provider {
const provider = networkClientId
? this.getNetworkClientById(networkClientId).provider
? (this.getNetworkClientById(networkClientId).provider as unknown as
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's little tricky here! Web3Provider constructor expects ExternalProvider | JsonRpcFetchFunc! but this.getNetworkClientById(networkClientId).provider type is ProxyWithAccessibleTarget<SafeEventEmitterProvider>!! For now, I can only think of this type assertion!!

I'm trying to find if there's a better way!

if (k === 'address') {
return true; // address will always be present
}
// collection will always be an object, we need to check the internal values
if (k === 'collection') {
return v?.name === null && v?.image_url === null;
const obj = v as {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The collection is {name: string; image_url: string} . Link to the declaration.

? this.getNetworkClientById(networkClientId).provider
: this.config?.provider,
);
const provider = networkClientId
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Web3Provider constructor expects ExternalProvider | JsonRpcFetchFunc! but this.getNetworkClientById(networkClientId).provider type is ProxyWithAccessibleTarget<SafeEventEmitterProvider>!! For now, I can only think of this type assertion!!

I'm trying to find if there's a better way!

@MajorLift
Copy link
Contributor

  • Provider type incompatibility in prettified format:
Screenshot 2024-01-24 at 12 44 50 AM Screenshot 2024-01-24 at 12 45 03 AM

Maybe adding id, jsonrpc to the network client provider's sendAsync request type might work?

@kanthesha
Copy link
Contributor Author

@MajorLift
I think, it is other way around! network client provider's sendAsync has a req: JsonRpcRequest, JsonRpcRequest additionally contains id and jsonrpc (link) compared to sendAsync of JsonRpcFetchFunc & ExternalProvider's request: { method: string, params?: Array<any> }.

@MajorLift
Copy link
Contributor

Oh you're right. In that case, I guess we'd want to remove id and jsonrpc from the provider before it's passed into Web3Provider.

@kanthesha
Copy link
Contributor Author

hmm! id and jsonrpc are there in the request parameter of send and sendAync functions of provider object.

@MajorLift

This comment was marked as outdated.

@MajorLift
Copy link
Contributor

MajorLift commented Jan 25, 2024

Here's the updated provider with working methods. Since ExternalProvider and Web3Provider don't use id and jsonrpc, the mock value for id shouldn't be an issue.

    const provider = {
      ...networkClientProvider,
      send: (
        _req: { method: string; params?: Json[] },
        _callback: (error: unknown, response: unknown) => void,
      ) =>
        networkClientProvider.send.bind(provider)(
          { ..._req, id: '', jsonrpc: '2.0' },
          _callback,
        ),
      sendAsync: (
        _req: { method: string; params?: Json[] },
        _callback: (error: unknown, response: unknown) => void,
      ) =>
        networkClientProvider.sendAsync.bind(provider)(
          { ..._req, id: '', jsonrpc: '2.0' },
          _callback,
        ),
    };

@kanthesha kanthesha marked this pull request as ready for review February 6, 2024 12:50
@kanthesha kanthesha requested a review from a team as a code owner February 6, 2024 12:50
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.

Almost there! Just two more things.

);
const provider = networkClientId
? this.getNetworkClientById(networkClientId).provider
: this.config?.provider;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit:
internalConfig is always defined in BaseControllerV1

Suggested change
: this.config?.provider;
: this.config.provider;

@MajorLift
Copy link
Contributor

Looks like the coverage thresholds can be increased.

-      branches: 88.36,
-      functions: 97.08,
-      lines: 97.23,
-      statements: 97.28,
+      branches: 89.35,
+      functions: 97.74,
+      lines: 97.64,
+      statements: 97.68,

@kanthesha
Copy link
Contributor Author

@MajorLift
I see that the branch % is 89.29 in my local. I've updated the jest.config accordingly.

   branches: 89.29,
   functions: 97.74,
   lines: 97.64,
   statements: 97.68,

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.

One final thing :)

mcmire
mcmire previously approved these changes Feb 8, 2024
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.

Left a non-blocking comment. Looks good.

@@ -109,6 +110,8 @@ describe('TokensController', () => {
tokenListStateChangeListener = listener;
});

const fakeProvider = new FakeProvider();
Copy link
Contributor

Choose a reason for hiding this comment

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

Heads up — it's best to avoid setting variables outside of beforeEach/afterEach/it, because it means that changes to an object could persist across multiple tests, which could lead to tests that intermittently fail or that are difficult to debug. In this case it's okay since the fake provider isn't actually used for anything, it's just here to satisfy a type, but something to keep in mind for future tests. This is something we go into more detail about in the contributor docs, but we could certainly make this more clear if it's not clear enough.

Copy link
Contributor Author

@kanthesha kanthesha Feb 9, 2024

Choose a reason for hiding this comment

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

Yeah, here it is intentional. The objects and variables which will be modified in the tests and needs reset after each test has to be included in beforeEach/afterEach/it. For example, if we want to write a test case where mainnet provider is expected and in an another test case, we are expecting testnet. But in this case we are not modifying the provider. This kind of initialisation can optionally moved to beforeAll. Adding unnecessary setup work into beforeEach or afterEach may slowdown the tests.

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.

Looks good!

There's one thing remaining in this PR: updating the Changelog section in the PR description. We use this section to populate CHANGELOG.md when we create release PRs. You can see an example of that in this PR: #3749. In this case I believe that some of the changes to AssetsContractController and TokensController are breaking.

@kanthesha kanthesha merged commit 8282d9c into main Feb 9, 2024
136 checks passed
@kanthesha kanthesha deleted the asset-controller-fix-any-type branch February 9, 2024 18:18
@kanthesha
Copy link
Contributor Author

The changelog section has been added.

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.

assets-controllers: Replace use of any with proper types (non-test files only)
3 participants