-
-
Notifications
You must be signed in to change notification settings - Fork 261
Add detection params (userAddress, chainId) and remove duplicate source of truth #636
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
Conversation
| /* istanbul ignore else */ | ||
| if ( | ||
| !ignored && | ||
| requestedSelectedAddress === this.config.selectedAddress |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, so this condition was only added on the CollectibleDetectionController and not in the CollectiblesController
gantunesr
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some small comments
| selectedAddress: '0x1', | ||
| selectedAddress, | ||
| }); | ||
| collectiblesController.configure({ selectedAddress }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know these are unit tests so we don't need to test the integration points with other Controllers but I generally like to use the upstream method where the piece of state we're subscribed to actually changes (in this case it would be preferences.setSelectedAddress(selectedAddress)). I think it makes our network of assumptions safer but I'm open to being convinced otherwise! Thoughts @Gudahtt @wachunei @gantunesr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we wanted to test this robustly we'd do both. I'd rather us migrate to using the new base controller than waste our time doing that though, because we don't really want configure to be public API like this.
Following your suggestion would be better at least in that it'd be more compatible with BaseControllerV2 when we do migrate.
| expect(collectiblesController.state.ignoredCollectibles).toHaveLength(0); | ||
| collectiblesController.removeAndIgnoreCollectible( | ||
| '0x1d963688fe2209a98db35c67a041524822cf04ff', | ||
| '0x1d963688FE2209A98dB35C67A041524822Cf04ff', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just curious why was the checksum change here necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really, I did it without noticing 😅
| export interface CollectibleDetectionConfig extends BaseConfig { | ||
| interval: number; | ||
| networkType: NetworkType; | ||
| chainId: `0x${string}` | `${number}` | number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoa! I didn't know you could do string interpolated types! So cool
|
|
||
| await safelyExecute(async () => { | ||
| const apiCollectibles = await this.getOwnerCollectibles(); | ||
| const apiCollectibles = await this.getOwnerCollectibles(selectedAddress); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not understanding what we achieve by getting selectedAddress in detectCollectibles and passing it in to getOwnerCollectibles rather than just pulling selectedAddress off config in getOwnerCollectibles?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We just want to avoid grabbing it in different places to make sure it does not change along the execution of the procedure
adonesky1
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in general I don't like the pattern of replacing undefined with an empty array because it maintains the default value of the collectibles and collectibleContracts subset state values. I think it ends up causing more confusion. Open to be convinced otherwise though!
| collectiblesController.state.allCollectibleContracts[selectedAddress][ | ||
| chainId | ||
| ], | ||
| ).toHaveLength(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we remove the key rather than just remove the item from the array when there are no more left for the address/chainId combo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that this would be nicer, so that the behaviour after adding and removing a collectible matches the initial behaviour. Leaves us with less cases to test, and it's simpler for anyone using this state. I don't want to block on it though.
Co-authored-by: Alex Donesky <[email protected]>
Co-authored-by: Alex Donesky <[email protected]>
Co-authored-by: Alex Donesky <[email protected]>
|
I updated the About this: I think it makes sense to prune empty nodes, is it something we do usually? I'd defer decision to you guys that are more familiar with controllers conventions. |
adonesky1
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
So these "detection params", what purpose do these serve? Is this so that the chainID/address at time of detection is preserved, so that the NFT is assigned correctly if the user switches accounts/networks while the detection was still being processed? I didn't see the problem this was meant to solve explained anywhere. |
|
Yes, exactly that |
| ); | ||
| await this.addCollectible(address, token_id, collectibleMetadata, { | ||
| userAddress: selectedAddress, | ||
| chainId: chainId as string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: We should not need to cast here. If it's possible for this to be something other than a string, we need to deal with that here. If it's not, then the type is wrong and we should fix that instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The chain ID normalization above is responsible for this. It is guaranteed to be a string here but the normalization is done in a way TypeScript's inference is having trouble with. I've just prototyped a solution that I can prepare as a follow up PR later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically it's to move the normalization to a utility function, and adjust the conditions to help TypeScript's inference along a bit better, and add a "throw" case for invalid chain IDs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, this type and normalization is also present in the GasFeeController, so we can use that util there.
| this.configure({ networkType: provider.type }); | ||
| this.configure({ | ||
| networkType: provider.type, | ||
| chainId: provider.chainId as CollectibleDetectionConfig['chainId'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Ideally we'd parse this here to guarantee that the chain ID is the expected type, rather than cast. Or propagate this new chain ID type into the network controller as well. I guess we can do that later.
| this.defaultConfig = { | ||
| interval: DEFAULT_INTERVAL, | ||
| networkType: MAINNET, | ||
| chainId: '1', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I don't object to doing this for now, since the default networkType is MAINNET already, so this is a pre-existing issue. But we shouldn't be setting a default network at all, we can get the true current network from the network controller by passing in a getNetworkState function to the constructor.
This could lead to bugs where something runs initially before the first network state update, and uses the wrong network.
|
Overall looks good! I'm very glad to see that duplicate state removed. It would have been better to do this in two separate PRs, but what's done is done. I can take another look when conflicts are resolved. |
Co-authored-by: Mark Stacey <[email protected]>
|
@Gudahtt Conflicts are resolved 👌 |
Gudahtt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
…ce of truth (#636) Co-authored-by: Alex Donesky <[email protected]> Co-authored-by: Mark Stacey <[email protected]>
…ce of truth (#636) Co-authored-by: Alex Donesky <[email protected]> Co-authored-by: Mark Stacey <[email protected]>
Description
REMOVED
collectiblesandcollectibleContractsare removed fromCollectiblesControllerstate.FIXED:
booleanto an object containingaddressandchainIdthat was used to autodetect.Checklist
Issue
Related MetaMask/metamask-mobile#3335