Skip to content

Commit d7ec98b

Browse files
authored
Enhance checkAndUpdateSingleCollectibleOwnershipStatus to use use passed accountParams for selectedAddress and chainId (#672)
* Enhance checkAndUpdateSingleCollectibleOwnershipStatus to use use passed accountParams for selectedAddress and chainId
1 parent b048670 commit d7ec98b

File tree

2 files changed

+93
-27
lines changed

2 files changed

+93
-27
lines changed

src/assets/CollectiblesController.test.ts

+65
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const MAINNET_PROVIDER = new HttpProvider(
2525
'https://mainnet.infura.io/v3/ad3a368836ff4596becc3be8e2f137ac',
2626
);
2727
const OWNER_ADDRESS = '0x5a3CA5cD63807Ce5e4d7841AB32Ce6B6d9BbBa2D';
28+
const SECOND_OWNER_ADDRESS = '0x500017171kasdfbou081';
2829

2930
const OPEN_SEA_HOST = 'https://api.opensea.io';
3031
const OPEN_SEA_PATH = '/api/v1';
@@ -1301,6 +1302,70 @@ describe('CollectiblesController', () => {
13011302

13021303
expect(updatedCollectible.isCurrentlyOwned).toBe(false);
13031304
});
1305+
1306+
it('should check whether the passed collectible is still owned by the the selectedAddress/chainId combination passed in the accountParams argument and update its isCurrentlyOwned property in state, when the currently configured selectedAddress/chainId are different from those passed', async () => {
1307+
const firstNetworkType = 'rinkeby';
1308+
const secondNetworkType = 'ropsten';
1309+
1310+
preferences.update({ selectedAddress: OWNER_ADDRESS });
1311+
network.update({
1312+
provider: {
1313+
type: firstNetworkType,
1314+
chainId: NetworksChainId[firstNetworkType],
1315+
},
1316+
});
1317+
1318+
const { selectedAddress, chainId } = collectiblesController.config;
1319+
const collectible = {
1320+
address: '0x02',
1321+
tokenId: '1',
1322+
name: 'name',
1323+
image: 'image',
1324+
description: 'description',
1325+
standard: 'standard',
1326+
favorite: false,
1327+
};
1328+
1329+
await collectiblesController.addCollectible(
1330+
collectible.address,
1331+
collectible.tokenId,
1332+
collectible,
1333+
);
1334+
1335+
expect(
1336+
collectiblesController.state.allCollectibles[selectedAddress][
1337+
chainId
1338+
][0].isCurrentlyOwned,
1339+
).toBe(true);
1340+
1341+
sandbox.restore();
1342+
sandbox
1343+
.stub(collectiblesController, 'isCollectibleOwner' as any)
1344+
.returns(false);
1345+
1346+
preferences.update({ selectedAddress: SECOND_OWNER_ADDRESS });
1347+
network.update({
1348+
provider: {
1349+
type: secondNetworkType,
1350+
chainId: NetworksChainId[secondNetworkType],
1351+
},
1352+
});
1353+
1354+
await collectiblesController.checkAndUpdateSingleCollectibleOwnershipStatus(
1355+
collectible,
1356+
false,
1357+
{
1358+
userAddress: OWNER_ADDRESS,
1359+
chainId: NetworksChainId[firstNetworkType],
1360+
},
1361+
);
1362+
1363+
expect(
1364+
collectiblesController.state.allCollectibles[OWNER_ADDRESS][
1365+
NetworksChainId[firstNetworkType]
1366+
][0].isCurrentlyOwned,
1367+
).toBe(false);
1368+
});
13041369
});
13051370
});
13061371
});

src/assets/CollectiblesController.ts

+28-27
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ export interface CollectibleMetadata {
118118
lastSale?: ApiCollectibleLastSale;
119119
}
120120

121-
interface DetectionParams {
121+
interface AccountParams {
122122
userAddress: string;
123123
chainId: string;
124124
}
@@ -195,31 +195,27 @@ export class CollectiblesController extends BaseController<
195195
* @param newCollection - the modified piece of state to update in the controller's store
196196
* @param baseStateKey - The root key in the store to update.
197197
* @param passedConfig - An object containing the selectedAddress and chainId that are passed through the auto-detection flow.
198-
* @param passedConfig.selectedAddress - the address passed through the collectible detection flow to ensure detected assets are stored to the correct account
198+
* @param passedConfig.userAddress - the address passed through the collectible detection flow to ensure detected assets are stored to the correct account
199199
* @param passedConfig.chainId - the chainId passed through the collectible detection flow to ensure detected assets are stored to the correct account
200200
*/
201201
private updateNestedCollectibleState(
202202
newCollection: Collectible[] | CollectibleContract[],
203203
baseStateKey: 'allCollectibles' | 'allCollectibleContracts',
204-
passedConfig?: { selectedAddress: string; chainId: string },
204+
{ userAddress, chainId }: AccountParams | undefined = {
205+
userAddress: this.config.selectedAddress,
206+
chainId: this.config.chainId,
207+
},
205208
) {
206-
// We want to use the passedSelectedAddress and passedChainId when defined and not null
207-
// these values are passed through the collectible detection flow, meaning they may not
208-
// match as the currently configured values (which may be stale for this update)
209-
const address =
210-
passedConfig?.selectedAddress ?? this.config.selectedAddress;
211-
const chain = passedConfig?.chainId ?? this.config.chainId;
212-
213209
const { [baseStateKey]: oldState } = this.state;
214210

215-
const addressState = oldState[address];
211+
const addressState = oldState[userAddress];
216212
const newAddressState = {
217213
...addressState,
218-
...{ [chain]: newCollection },
214+
...{ [chainId]: newCollection },
219215
};
220216
const newState = {
221217
...oldState,
222-
...{ [address]: newAddressState },
218+
...{ [userAddress]: newAddressState },
223219
};
224220

225221
this.update({
@@ -540,7 +536,7 @@ export class CollectiblesController extends BaseController<
540536
address: string,
541537
tokenId: string,
542538
collectibleMetadata: CollectibleMetadata,
543-
detection?: DetectionParams,
539+
detection?: AccountParams,
544540
): Promise<Collectible[]> {
545541
// TODO: Remove unused return
546542
const releaseLock = await this.mutex.acquire();
@@ -598,7 +594,7 @@ export class CollectiblesController extends BaseController<
598594
this.updateNestedCollectibleState(
599595
newCollectibles,
600596
ALL_COLLECTIBLES_STATE_KEY,
601-
{ chainId, selectedAddress },
597+
{ chainId, userAddress: selectedAddress },
602598
);
603599

604600
return newCollectibles;
@@ -616,7 +612,7 @@ export class CollectiblesController extends BaseController<
616612
*/
617613
private async addCollectibleContract(
618614
address: string,
619-
detection?: DetectionParams,
615+
detection?: AccountParams,
620616
): Promise<CollectibleContract[]> {
621617
const releaseLock = await this.mutex.acquire();
622618
try {
@@ -686,7 +682,7 @@ export class CollectiblesController extends BaseController<
686682
this.updateNestedCollectibleState(
687683
newCollectibleContracts,
688684
ALL_COLLECTIBLES_CONTRACTS_STATE_KEY,
689-
{ chainId, selectedAddress },
685+
{ chainId, userAddress: selectedAddress },
690686
);
691687

692688
return newCollectibleContracts;
@@ -963,7 +959,7 @@ export class CollectiblesController extends BaseController<
963959
address: string,
964960
tokenId: string,
965961
collectibleMetadata?: CollectibleMetadata,
966-
detection?: DetectionParams,
962+
detection?: AccountParams,
967963
) {
968964
address = toChecksumHexAddress(address);
969965
const newCollectibleContracts = await this.addCollectibleContract(
@@ -1045,22 +1041,23 @@ export class CollectiblesController extends BaseController<
10451041
*
10461042
* @param collectible - The collectible object to check and update.
10471043
* @param batch - A boolean indicating whether this method is being called as part of a batch or single update.
1044+
* @param accountParams - The userAddress and chainId to check ownership against
1045+
* @param accountParams.userAddress - the address passed through the confirmed transaction flow to ensure detected assets are stored to the correct account
1046+
* @param accountParams.chainId - the chainId passed through the confirmed transaction flow to ensure detected assets are stored to the correct account
10481047
* @returns the collectible with the updated isCurrentlyOwned value
10491048
*/
10501049
async checkAndUpdateSingleCollectibleOwnershipStatus(
10511050
collectible: Collectible,
10521051
batch: boolean,
1052+
{ userAddress, chainId }: AccountParams | undefined = {
1053+
userAddress: this.config.selectedAddress,
1054+
chainId: this.config.chainId,
1055+
},
10531056
) {
1054-
const { allCollectibles } = this.state;
1055-
const { selectedAddress, chainId } = this.config;
10561057
const { address, tokenId } = collectible;
10571058
let isOwned = collectible.isCurrentlyOwned;
10581059
try {
1059-
isOwned = await this.isCollectibleOwner(
1060-
selectedAddress,
1061-
address,
1062-
tokenId,
1063-
);
1060+
isOwned = await this.isCollectibleOwner(userAddress, address, tokenId);
10641061
} catch (error) {
10651062
if (!error.message.includes('Unable to verify ownership')) {
10661063
throw error;
@@ -1074,15 +1071,19 @@ export class CollectiblesController extends BaseController<
10741071
}
10751072

10761073
// if this is not part of a batched update we update this one collectible in state
1077-
const collectibles = allCollectibles[selectedAddress]?.[chainId] || [];
1074+
const { allCollectibles } = this.state;
1075+
const collectibles = allCollectibles[userAddress]?.[chainId] || [];
10781076
const collectibleToUpdate = collectibles.find(
1079-
(item) => item.tokenId === tokenId && item.address === address,
1077+
(item) =>
1078+
item.tokenId === tokenId &&
1079+
item.address.toLowerCase() === address.toLowerCase(),
10801080
);
10811081
if (collectibleToUpdate) {
10821082
collectibleToUpdate.isCurrentlyOwned = isOwned;
10831083
this.updateNestedCollectibleState(
10841084
collectibles,
10851085
ALL_COLLECTIBLES_STATE_KEY,
1086+
{ userAddress, chainId },
10861087
);
10871088
}
10881089
return collectible;

0 commit comments

Comments
 (0)