Skip to content

Commit

Permalink
Add method to check and update collectible ownership state (#664)
Browse files Browse the repository at this point in the history
* Add method to check and update collectible ownership state
  • Loading branch information
adonesky1 committed Dec 17, 2021
1 parent be94b9b commit 5aaf511
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/assets/CollectibleDetectionController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ describe('CollectibleDetectionController', () => {
tokenId: '2574',
standard: 'ERC721',
favorite: false,
isCurrentlyOwned: true,
},
]);
});
Expand Down Expand Up @@ -343,6 +344,7 @@ describe('CollectibleDetectionController', () => {
standard: 'ERC721',
tokenId: '2573',
favorite: false,
isCurrentlyOwned: true,
},
{
address: '0xebE4e5E773AFD2bAc25De0cFafa084CFb3cBf1eD',
Expand All @@ -352,6 +354,7 @@ describe('CollectibleDetectionController', () => {
tokenId: '2574',
standard: 'ERC721',
favorite: false,
isCurrentlyOwned: true,
},
]);
});
Expand Down Expand Up @@ -453,6 +456,7 @@ describe('CollectibleDetectionController', () => {
tokenId: '2574',
standard: 'ERC721',
favorite: false,
isCurrentlyOwned: true,
};
const collectibleGG2574 = {
address: '0xCE7ec4B2DfB30eB6c0BB5656D33aAd6BFb4001Fc',
Expand All @@ -462,6 +466,7 @@ describe('CollectibleDetectionController', () => {
tokenId: '2574',
standard: 'ERC721',
favorite: false,
isCurrentlyOwned: true,
};
const collectibleII2577 = {
address: '0x0B0fa4fF58D28A88d63235bd0756EDca69e49e6d',
Expand All @@ -471,6 +476,7 @@ describe('CollectibleDetectionController', () => {
tokenId: '2577',
standard: 'ERC721',
favorite: false,
isCurrentlyOwned: true,
};
const collectibleContractHH = {
address: '0xebE4e5E773AFD2bAc25De0cFafa084CFb3cBf1eD',
Expand Down
100 changes: 100 additions & 0 deletions src/assets/CollectiblesController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ describe('CollectiblesController', () => {
tokenId: '1',
standard: 'standard',
favorite: false,
isCurrentlyOwned: true,
});

expect(
Expand Down Expand Up @@ -256,6 +257,7 @@ describe('CollectiblesController', () => {
name: 'name',
tokenId: '1234',
favorite: false,
isCurrentlyOwned: true,
});
});

Expand All @@ -282,6 +284,7 @@ describe('CollectiblesController', () => {
standard: 'standard',
tokenId: '1',
favorite: false,
isCurrentlyOwned: true,
});

await collectiblesController.addCollectible('0x01', '1', {
Expand All @@ -304,6 +307,7 @@ describe('CollectiblesController', () => {
tokenId: '1',
standard: 'standard',
favorite: false,
isCurrentlyOwned: true,
});
});

Expand Down Expand Up @@ -352,6 +356,7 @@ describe('CollectiblesController', () => {
standard: 'ERC1155',
tokenId: '1',
favorite: false,
isCurrentlyOwned: true,
});
});

Expand Down Expand Up @@ -379,6 +384,7 @@ describe('CollectiblesController', () => {
numberOfSales: 1,
standard: 'ERC1155',
favorite: false,
isCurrentlyOwned: true,
});
});

Expand Down Expand Up @@ -406,6 +412,7 @@ describe('CollectiblesController', () => {
imageOriginal: 'Kudos url',
standard: 'ERC721',
favorite: false,
isCurrentlyOwned: true,
});

expect(
Expand Down Expand Up @@ -445,6 +452,7 @@ describe('CollectiblesController', () => {
tokenId: '1203',
standard: 'ERC721',
favorite: false,
isCurrentlyOwned: true,
});

expect(
Expand Down Expand Up @@ -504,6 +512,7 @@ describe('CollectiblesController', () => {
name: 'name',
tokenId: '1234',
favorite: false,
isCurrentlyOwned: true,
});
});

Expand Down Expand Up @@ -553,6 +562,7 @@ describe('CollectiblesController', () => {
standard: 'ERC721',
tokenId: '1203',
favorite: false,
isCurrentlyOwned: true,
},
]);

Expand Down Expand Up @@ -650,6 +660,7 @@ describe('CollectiblesController', () => {
description: 'description',
standard: 'ERC721',
favorite: false,
isCurrentlyOwned: true,
});
});
});
Expand Down Expand Up @@ -683,6 +694,7 @@ describe('CollectiblesController', () => {
name: 'name',
tokenId: '1234',
favorite: false,
isCurrentlyOwned: true,
});
});

Expand Down Expand Up @@ -778,6 +790,7 @@ describe('CollectiblesController', () => {
name: 'name',
tokenId: '4321',
favorite: false,
isCurrentlyOwned: true,
});
});

Expand Down Expand Up @@ -829,6 +842,7 @@ describe('CollectiblesController', () => {
name: 'name',
tokenId: '4321',
favorite: false,
isCurrentlyOwned: true,
});
});
});
Expand Down Expand Up @@ -1056,6 +1070,7 @@ describe('CollectiblesController', () => {
address: ERC721_DEPRESSIONIST_ADDRESS,
tokenId: ERC721_DEPRESSIONIST_ID,
favorite: true,
isCurrentlyOwned: true,
}),
);

Expand Down Expand Up @@ -1107,12 +1122,97 @@ describe('CollectiblesController', () => {
address: ERC721_DEPRESSIONIST_ADDRESS,
tokenId: ERC721_DEPRESSIONIST_ID,
favorite: false,
isCurrentlyOwned: true,
}),
);

expect(
collectiblesController.state.allCollectibles[selectedAddress][chainId],
).toHaveLength(1);
});

describe('checkAndUpdateCollectiblesOwnershipStatus', () => {
it('should check whether collectibles for the current selectedAddress/chainId combination are still owned by the selectedAddress and update the isCurrentlyOwned value to false when collectible is not still owned', async () => {
sandbox.restore();
sandbox
.stub(collectiblesController, 'isCollectibleOwner' as any)
.returns(false);

const { selectedAddress, chainId } = collectiblesController.config;
await collectiblesController.addCollectible('0x02', '1', {
name: 'name',
image: 'image',
description: 'description',
standard: 'standard',
favorite: false,
});

expect(
collectiblesController.state.allCollectibles[selectedAddress][
chainId
][0].isCurrentlyOwned,
).toBe(true);

await collectiblesController.checkAndUpdateCollectiblesOwnershipStatus();
expect(
collectiblesController.state.allCollectibles[selectedAddress][
chainId
][0].isCurrentlyOwned,
).toBe(false);
});
});

it('should check whether collectibles for the current selectedAddress/chainId combination are still owned by the selectedAddress and leave/set the isCurrentlyOwned value to true when collectible is still owned', async () => {
const { selectedAddress, chainId } = collectiblesController.config;
await collectiblesController.addCollectible('0x02', '1', {
name: 'name',
image: 'image',
description: 'description',
standard: 'standard',
favorite: false,
});

expect(
collectiblesController.state.allCollectibles[selectedAddress][
chainId
][0].isCurrentlyOwned,
).toBe(true);

await collectiblesController.checkAndUpdateCollectiblesOwnershipStatus();
expect(
collectiblesController.state.allCollectibles[selectedAddress][
chainId
][0].isCurrentlyOwned,
).toBe(true);
});

it('should check whether collectibles for the current selectedAddress/chainId combination are still owned by the selectedAddress and leave the isCurrentlyOwned value as is when collectible ownership check fails', async () => {
sandbox.restore();
sandbox
.stub(collectiblesController, 'isCollectibleOwner' as any)
.throws(new Error('Unable to verify ownership'));

const { selectedAddress, chainId } = collectiblesController.config;
await collectiblesController.addCollectible('0x02', '1', {
name: 'name',
image: 'image',
description: 'description',
standard: 'standard',
favorite: false,
});

expect(
collectiblesController.state.allCollectibles[selectedAddress][
chainId
][0].isCurrentlyOwned,
).toBe(true);

await collectiblesController.checkAndUpdateCollectiblesOwnershipStatus();
expect(
collectiblesController.state.allCollectibles[selectedAddress][
chainId
][0].isCurrentlyOwned,
).toBe(true);
});
});
});
40 changes: 39 additions & 1 deletion src/assets/CollectiblesController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ import { compareCollectiblesMetadata } from './assetsUtil';
* @property animationOriginal - URI of the original animation associated with this collectible
* @property externalLink - External link containing additional information
* @property creator - The collectible owner information object
* @property isCurrentlyOwned - Boolean indicating whether the address/chainId combination where it's currently stored currently owns this collectible
*/
export interface Collectible extends CollectibleMetadata {
tokenId: string;
address: string;
isCurrentlyOwned?: boolean;
}

/**
Expand Down Expand Up @@ -587,8 +589,9 @@ export class CollectiblesController extends BaseController<
const newEntry: Collectible = {
address,
tokenId,
...collectibleMetadata,
favorite: existingEntry?.favorite || false,
isCurrentlyOwned: true,
...collectibleMetadata,
};

const newCollectibles = [...collectibles, newEntry];
Expand Down Expand Up @@ -1036,6 +1039,41 @@ export class CollectiblesController extends BaseController<
this.update({ ignoredCollectibles: [] });
}

/**
* Checks whether Collectibles associated with current selectedAddress/chainId combination are still owned by the user
* And updates the isCurrentlyOwned value on each accordingly.
*/
async checkAndUpdateCollectiblesOwnershipStatus() {
const { allCollectibles } = this.state;
const { chainId, selectedAddress } = this.config;
const collectibles = allCollectibles[selectedAddress]?.[chainId] || [];
const updatedCollectibles = await Promise.all(
collectibles.map(async (collectible) => {
const { address, tokenId } = collectible;
let isOwned = collectible.isCurrentlyOwned;
try {
isOwned = await this.isCollectibleOwner(
selectedAddress,
address,
tokenId,
);
} catch (error) {
if (!error.message.includes('Unable to verify ownership')) {
throw error;
}
}
collectible.isCurrentlyOwned = isOwned;

return collectible;
}),
);

this.updateNestedCollectibleState(
updatedCollectibles,
ALL_COLLECTIBLES_STATE_KEY,
);
}

/**
* Update collectible favorite status.
*
Expand Down

0 comments on commit 5aaf511

Please sign in to comment.