From c554b158dddb99f7b1d33ae7c98256cf65970f0e Mon Sep 17 00:00:00 2001 From: gantunesr Date: Thu, 14 Oct 2021 10:52:05 -0300 Subject: [PATCH 01/43] Add package human-standard-multi-collectible-abi --- package.json | 1 + src/dependencies.d.ts | 2 ++ yarn.lock | 5 +++++ 3 files changed, 8 insertions(+) diff --git a/package.json b/package.json index 282f2d9fa9..4788eb521b 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "ethjs-unit": "^0.1.6", "ethjs-util": "^0.1.6", "human-standard-collectible-abi": "^1.0.2", + "human-standard-multi-collectible-abi": "^1.0.2", "human-standard-token-abi": "^2.0.0", "immer": "^9.0.6", "isomorphic-fetch": "^3.0.0", diff --git a/src/dependencies.d.ts b/src/dependencies.d.ts index f564e5ea41..47880fe1f2 100644 --- a/src/dependencies.d.ts +++ b/src/dependencies.d.ts @@ -22,6 +22,8 @@ declare module 'ethjs-unit'; declare module 'human-standard-collectible-abi'; +declare module 'human-standard-multi-collectible-abi' + declare module 'human-standard-token-abi'; declare module 'isomorphic-fetch'; diff --git a/yarn.lock b/yarn.lock index deea1f6d1f..a1d33f62e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4221,6 +4221,11 @@ human-standard-collectible-abi@^1.0.2: resolved "https://registry.yarnpkg.com/human-standard-collectible-abi/-/human-standard-collectible-abi-1.0.2.tgz#077bae9ed1b0b0b82bc46932104b4b499c941aa0" integrity sha512-nD3ITUuSAIBgkaCm9J2BGwlHL8iEzFjJfTleDAC5Wi8RBJEXXhxV0JeJjd95o+rTwf98uTE5MW+VoBKOIYQh0g== +human-standard-multi-collectible-abi@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/human-standard-multi-collectible-abi/-/human-standard-multi-collectible-abi-1.0.3.tgz#be5896b13f8622289cff70040e478366931bf3d7" + integrity sha512-1VXqats7JQqDZozLKhpmFG0S33hVePrkLNRJNKfJTxewR0heYKjSoz72kqs+6O/Tywi0zW4fWe7dfTaPX4j7gQ== + human-standard-token-abi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/human-standard-token-abi/-/human-standard-token-abi-2.0.0.tgz#e0c2057596d0a1d4a110f91f974a37f4b904f008" From f3a2decec5b7a0f12fbc518074262401800699c5 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Thu, 14 Oct 2021 20:16:36 -0300 Subject: [PATCH 02/43] Get NFT standard from OpenSea --- src/assets/CollectiblesController.test.ts | 12 ++++++++++++ src/assets/CollectiblesController.ts | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/src/assets/CollectiblesController.test.ts b/src/assets/CollectiblesController.test.ts index ce378b7592..4ff4a7c753 100644 --- a/src/assets/CollectiblesController.test.ts +++ b/src/assets/CollectiblesController.test.ts @@ -45,6 +45,9 @@ describe('CollectiblesController', () => { name: 'Name', symbol: 'FOO', total_supply: 0, + asset_contract: { + schema_name: 'ERC1155', + }, }) .get(`${OPEN_SEA_PATH}/asset_contract/0x02`) .reply(200, { @@ -59,6 +62,9 @@ describe('CollectiblesController', () => { description: 'Description', image_original_url: 'url', name: 'Name', + asset_contract: { + schema_name: 'ERC1155', + }, }) .get( `${OPEN_SEA_PATH}/asset/0x2aEa4Add166EBf38b63d09a75dE1a7b94Aa24163/1203`, @@ -67,6 +73,9 @@ describe('CollectiblesController', () => { description: 'Kudos Description', image_original_url: 'Kudos url', name: 'Kudos Name', + asset_contract: { + schema_name: 'ERC721', + }, }) .get( `${OPEN_SEA_PATH}/asset/0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab/798958393`, @@ -204,6 +213,7 @@ describe('CollectiblesController', () => { description: 'Description', imageOriginal: 'url', name: 'Name', + standard: 'ERC1155', tokenId: 1, }); }); @@ -308,12 +318,14 @@ describe('CollectiblesController', () => { true, ); + console.log(collectiblesController.state.collectibles); expect(collectiblesController.state.collectibles).toStrictEqual([ { address: '0x2aEa4Add166EBf38b63d09a75dE1a7b94Aa24163', description: 'Kudos Description', imageOriginal: 'Kudos url', name: 'Kudos Name', + standard: 'ERC721', tokenId: 1203, }, ]); diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index eb9a1e1155..a009964114 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -82,6 +82,7 @@ export interface CollectibleContract { * @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 standard - NFT standard name for the collectible, e.g., ERC-721 or ERC-1155 */ export interface CollectibleMetadata { name?: string; @@ -97,6 +98,7 @@ export interface CollectibleMetadata { externalLink?: string; creator?: ApiCollectibleCreator; lastSale?: ApiCollectibleLastSale; + standard?: string; } /** @@ -184,6 +186,7 @@ export class CollectiblesController extends BaseController< external_link, creator, last_sale, + asset_contract, } = collectibleInformation; /* istanbul ignore next */ @@ -204,6 +207,7 @@ export class CollectiblesController extends BaseController< }, external_link && { externalLink: external_link }, last_sale && { lastSale: last_sale }, + asset_contract.schema_name && { standard: asset_contract.schema_name }, ); return collectibleMetadata; From a240a1e3c65227ef006ac10eb9b2db5f83777664 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Fri, 15 Oct 2021 00:03:34 -0300 Subject: [PATCH 03/43] Add ERC1155 standard class --- .../ERC1155/ERC1155Standard.test.ts | 18 +++ .../ERC1155/ERC1155Standard.ts | 108 ++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts create mode 100644 src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts diff --git a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts new file mode 100644 index 0000000000..f23238f0da --- /dev/null +++ b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts @@ -0,0 +1,18 @@ +import Web3 from 'web3'; +import HttpProvider from 'ethjs-provider-http'; +import abiERC1155 from 'human-standard-multi-collectible-abi'; +import { ERC1155Standard } from './ERC1155Standard'; + +const MAINNET_PROVIDER = new HttpProvider( + 'https://mainnet.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', +); + +describe('ERC721Standard', () => { + let erc721Standard: ERC1155Standard; + let web3: Web3; + + beforeEach(() => { + erc721Standard = new ERC1155Standard(); + web3 = new Web3(MAINNET_PROVIDER); + }); +}); \ No newline at end of file diff --git a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts new file mode 100644 index 0000000000..3cb04c5b5f --- /dev/null +++ b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts @@ -0,0 +1,108 @@ +const ERC1155_METADATA_URI_INTERFACE_ID = '0x0e89341c'; +const ERC1155_TOKEN_RECEIVER_INTERFACE_ID = '0x4e2312e0'; + +export class ERC1155Standard { + /** + * Query if contract implements ERC721Metadata interface. + * + * @param address - ERC721 asset contract address. + * @returns Promise resolving to whether the contract implements ERC721Metadata interface. + */ + contractSupportsURIMetadataInterface = async ( + address: string, + ): Promise => { + return this.contractSupportsInterface( + address, + ERC1155_METADATA_URI_INTERFACE_ID, + ); + }; + + /** + * Query if contract implements ERC721Enumerable interface. + * + * @param address - ERC721 asset contract address. + * @returns Promise resolving to whether the contract implements ERC721Enumerable interface. + */ + contractSupportsTokenReceiverInterface = async ( + address: string, + ): Promise => { + return this.contractSupportsInterface( + address, + ERC1155_TOKEN_RECEIVER_INTERFACE_ID, + ); + }; + + /** + * Query for tokenURI for a given asset. + * + * @param contract - ERC1155 asset contract. + * @param tokenId - ERC1155 asset identifier. + * @returns Promise resolving to the 'tokenURI'. + */ + getCollectibleURI = async ( + contract: any, + tokenId: number, + ): Promise => { + return new Promise((resolve, reject) => { + contract.uri(tokenId, (error: Error, result: string) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result); + }); + }); + }; + + /** + * Query for balance of a given ERC 1155 token. + * + * @param contract - ERC1155 asset contract. + * @param address - Wallet public address. + * @param tokenId - ERC1155 asset identifier. + * @returns Promise resolving to the 'balanceOf'. + */ + getBalanceOf = async ( + contract: any, + address: string, + tokenId: string, + ): Promise => { + return new Promise((resolve, reject) => { + contract.balanceOf(address, tokenId, (error: Error, result: number) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result); + }); + }); + }; + + /** + * Query if a contract implements an interface. + * + * @param contract - ERC1155 asset contract. + * @param interfaceId - Interface identifier. + * @returns Promise resolving to whether the contract implements `interfaceID`. + */ + private contractSupportsInterface = async ( + contract: any, + interfaceId: string, + ): Promise => { + return new Promise((resolve, reject) => { + contract.methods.supportsInterface( + interfaceId, + (error: Error, result: boolean) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result); + }, + ); + }); + }; +} From e63cfc343d8543fc647f5b45d39ce4ca97153268 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Fri, 15 Oct 2021 00:03:45 -0300 Subject: [PATCH 04/43] Add ERC721 standard class --- .../ERC721/ERC721Standard.test.ts | 33 ++++ .../ERC721/ERC721Standard.ts | 178 ++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 src/assets/CollectibleStandards/ERC721/ERC721Standard.test.ts create mode 100644 src/assets/CollectibleStandards/ERC721/ERC721Standard.ts diff --git a/src/assets/CollectibleStandards/ERC721/ERC721Standard.test.ts b/src/assets/CollectibleStandards/ERC721/ERC721Standard.test.ts new file mode 100644 index 0000000000..b2a3158796 --- /dev/null +++ b/src/assets/CollectibleStandards/ERC721/ERC721Standard.test.ts @@ -0,0 +1,33 @@ +import Web3 from 'web3'; +import HttpProvider from 'ethjs-provider-http'; +import abiERC721 from 'human-standard-collectible-abi'; +import { ERC721Standard } from './ERC721Standard'; + +const MAINNET_PROVIDER = new HttpProvider( + 'https://mainnet.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', +); +const GODSADDRESS = '0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab'; +const CKADDRESS = '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d'; + +describe('ERC721Standard', () => { + let erc721Standard: ERC721Standard; + let web3: Web3; + + beforeEach(() => { + erc721Standard = new ERC721Standard(); + web3 = new Web3(MAINNET_PROVIDER); + }); + + it('should determine if contract supports interface correctly', async () => { + const ckContract = web3.eth.contract(abiERC721).at(CKADDRESS); + const CKSupportsEnumerable = await erc721Standard.contractSupportsEnumerableInterface( + ckContract, + ); + const godsContract = web3.eth.contract(abiERC721).at(GODSADDRESS); + const GODSSupportsEnumerable = await erc721Standard.contractSupportsEnumerableInterface( + godsContract, + ); + expect(CKSupportsEnumerable).toBe(false); + expect(GODSSupportsEnumerable).toBe(true); + }); +}); diff --git a/src/assets/CollectibleStandards/ERC721/ERC721Standard.ts b/src/assets/CollectibleStandards/ERC721/ERC721Standard.ts new file mode 100644 index 0000000000..83a6ab945b --- /dev/null +++ b/src/assets/CollectibleStandards/ERC721/ERC721Standard.ts @@ -0,0 +1,178 @@ +import { BN } from 'ethereumjs-util'; + +const ERC721_METADATA_INTERFACE_ID = '0x5b5e139f'; +const ERC721_ENUMERABLE_INTERFACE_ID = '0x780e9d63'; + +export class ERC721Standard { + /** + * Query if contract implements ERC721Metadata interface. + * + * @param contract - ERC721 asset contract. + * @returns Promise resolving to whether the contract implements ERC721Metadata interface. + */ + contractSupportsMetadataInterface = async ( + contract: any, + ): Promise => { + return this.contractSupportsInterface( + contract, + ERC721_METADATA_INTERFACE_ID, + ); + }; + + /** + * Query if contract implements ERC721Enumerable interface. + * + * @param contract - ERC721 asset contract. + * @returns Promise resolving to whether the contract implements ERC721Enumerable interface. + */ + contractSupportsEnumerableInterface = async ( + contract: any, + ): Promise => { + return this.contractSupportsInterface( + contract, + ERC721_ENUMERABLE_INTERFACE_ID, + ); + }; + + /** + * Enumerate assets assigned to an owner. + * + * @param contract - ERC721 asset contract. + * @param selectedAddress - Current account public address. + * @param index - A collectible counter less than `balanceOf(selectedAddress)`. + * @returns Promise resolving to token identifier for the 'index'th asset assigned to 'selectedAddress'. + */ + getCollectibleTokenId = async ( + contract: any, + selectedAddress: string, + index: number, + ): Promise => { + return new Promise((resolve, reject) => { + contract.tokenOfOwnerByIndex( + selectedAddress, + index, + (error: Error, result: BN) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result.toNumber()); + }, + ); + }); + }; + + /** + * Query for tokenURI for a given asset. + * + * @param contract - ERC721 asset contract. + * @param tokenId - ERC721 asset identifier. + * @returns Promise resolving to the 'tokenURI'. + */ + getCollectibleTokenURI = async ( + contract: any, + tokenId: number, + ): Promise => { + const supportsMetadata = await this.contractSupportsMetadataInterface( + contract, + ); + if (!supportsMetadata) { + return ''; + } + return new Promise((resolve, reject) => { + contract.tokenURI(tokenId, (error: Error, result: string) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result); + }); + }); + }; + + /** + * Query for name for a given asset. + * + * @param contract - ERC721 asset contract. + * @returns Promise resolving to the 'name'. + */ + getAssetName = async (contract: any): Promise => { + return new Promise((resolve, reject) => { + contract.name((error: Error, result: string) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result); + }); + }); + }; + + /** + * Query for symbol for a given asset. + * + * @param contract - ERC721 asset contract address. + * @returns Promise resolving to the 'symbol'. + */ + getAssetSymbol = async (contract: any): Promise => { + return new Promise((resolve, reject) => { + contract.symbol((error: Error, result: string) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result); + }); + }); + }; + + /** + * Query for owner for a given ERC721 asset. + * + * @param contract - ERC721 asset contract. + * @param tokenId - ERC721 asset identifier. + * @returns Promise resolving to the owner address. + */ + async getOwnerOf(contract: any, tokenId: number): Promise { + return new Promise((resolve, reject) => { + contract.ownerOf(tokenId, (error: Error, result: string) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result); + }); + }); + } + + /** + * Query if a contract implements an interface. + * + * @param contract - Asset contract. + * @param interfaceId - Interface identifier. + * @returns Promise resolving to whether the contract implements `interfaceID`. + */ + private contractSupportsInterface = async ( + contract: any, + interfaceId: string, + ): Promise => { + return new Promise((resolve, reject) => { + contract.supportsInterface( + interfaceId, + (error: Error, result: boolean) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result); + }, + ); + }); + }; +} From 9b7f0865a1ca44d79ce3f8393c2fcb40b5e4ee42 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Fri, 15 Oct 2021 00:03:57 -0300 Subject: [PATCH 05/43] Update AssetContract controller --- src/assets/AssetsContractController.test.ts | 12 -- src/assets/AssetsContractController.ts | 200 +++++++------------- 2 files changed, 68 insertions(+), 144 deletions(-) diff --git a/src/assets/AssetsContractController.test.ts b/src/assets/AssetsContractController.test.ts index 44d072d320..f7ff66aceb 100644 --- a/src/assets/AssetsContractController.test.ts +++ b/src/assets/AssetsContractController.test.ts @@ -27,18 +27,6 @@ describe('AssetsContractController', () => { ); }); - it('should determine if contract supports interface correctly', async () => { - assetsContract.configure({ provider: MAINNET_PROVIDER }); - const CKSupportsEnumerable = await assetsContract.contractSupportsEnumerableInterface( - CKADDRESS, - ); - const GODSSupportsEnumerable = await assetsContract.contractSupportsEnumerableInterface( - GODSADDRESS, - ); - expect(CKSupportsEnumerable).toBe(false); - expect(GODSSupportsEnumerable).toBe(true); - }); - it('should get balance of contract correctly', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const CKBalance = await assetsContract.getBalanceOf( diff --git a/src/assets/AssetsContractController.ts b/src/assets/AssetsContractController.ts index 1dc8caf564..2a484a32df 100644 --- a/src/assets/AssetsContractController.ts +++ b/src/assets/AssetsContractController.ts @@ -2,11 +2,12 @@ import { BN } from 'ethereumjs-util'; import Web3 from 'web3'; import abiERC20 from 'human-standard-token-abi'; import abiERC721 from 'human-standard-collectible-abi'; +import abiERC1155 from 'human-standard-multi-collectible-abi'; import abiSingleCallBalancesContract from 'single-call-balance-checker-abi'; import { BaseController, BaseConfig, BaseState } from '../BaseController'; +import { ERC721Standard } from './CollectibleStandards/ERC721/ERC721Standard'; +import { ERC1155Standard } from './CollectibleStandards/ERC1155/ERC1155Standard'; -const ERC721METADATA_INTERFACE_ID = '0x5b5e139f'; -const ERC721ENUMERABLE_INTERFACE_ID = '0x780e9d63'; const SINGLE_CALL_BALANCES_ADDRESS = '0xb1f8e55c7f64d203c1400b9d8555d050f94adf39'; @@ -39,32 +40,9 @@ export class AssetsContractController extends BaseController< > { private web3: any; - /** - * Query if a contract implements an interface. - * - * @param address - Asset contract address. - * @param interfaceId - Interface identifier. - * @returns Promise resolving to whether the contract implements `interfaceID`. - */ - private async contractSupportsInterface( - address: string, - interfaceId: string, - ): Promise { - const contract = this.web3.eth.contract(abiERC721).at(address); - return new Promise((resolve, reject) => { - contract.supportsInterface( - interfaceId, - (error: Error, result: boolean) => { - /* istanbul ignore if */ - if (error) { - reject(error); - return; - } - resolve(result); - }, - ); - }); - } + private erc721Standard: ERC721Standard = new ERC721Standard(); + + private erc1155Standard: ERC1155Standard = new ERC1155Standard(); /** * Name of this controller used during composition @@ -103,33 +81,10 @@ export class AssetsContractController extends BaseController< throw new Error('Property only used for setting'); } - /** - * Query if contract implements ERC721Metadata interface. - * - * @param address - ERC721 asset contract address. - * @returns Promise resolving to whether the contract implements ERC721Metadata interface. - */ - async contractSupportsMetadataInterface(address: string): Promise { - return this.contractSupportsInterface(address, ERC721METADATA_INTERFACE_ID); - } - - /** - * Query if contract implements ERC721Enumerable interface. - * - * @param address - ERC721 asset contract address. - * @returns Promise resolving to whether the contract implements ERC721Enumerable interface. - */ - async contractSupportsEnumerableInterface(address: string): Promise { - return this.contractSupportsInterface( - address, - ERC721ENUMERABLE_INTERFACE_ID, - ); - } - /** * Get balance or count for current account on specific asset contract. * - * @param address - Asset contract address. + * @param address - Asset ERC20 contract address. * @param selectedAddress - Current account public address. * @returns Promise resolving to BN object containing balance for current account on specific asset contract. */ @@ -147,6 +102,26 @@ export class AssetsContractController extends BaseController< }); } + /** + * Query for name for a given ERC20 asset. + * + * @param address - ERC20 asset contract address. + * @returns Promise resolving to the 'decimals'. + */ + async getTokenDecimals(address: string): Promise { + const contract = this.web3.eth.contract(abiERC20).at(address); + return new Promise((resolve, reject) => { + contract.decimals((error: Error, result: string) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result); + }); + }); + } + /** * Enumerate assets assigned to an owner. * @@ -161,20 +136,11 @@ export class AssetsContractController extends BaseController< index: number, ): Promise { const contract = this.web3.eth.contract(abiERC721).at(address); - return new Promise((resolve, reject) => { - contract.tokenOfOwnerByIndex( - selectedAddress, - index, - (error: Error, result: BN) => { - /* istanbul ignore if */ - if (error) { - reject(error); - return; - } - resolve(result.toNumber()); - }, - ); - }); + return this.erc721Standard.getCollectibleTokenId( + contract, + selectedAddress, + index, + ); } /** @@ -188,43 +154,8 @@ export class AssetsContractController extends BaseController< address: string, tokenId: number, ): Promise { - const supportsMetadata = await this.contractSupportsMetadataInterface( - address, - ); - if (!supportsMetadata) { - return ''; - } const contract = this.web3.eth.contract(abiERC721).at(address); - return new Promise((resolve, reject) => { - contract.tokenURI(tokenId, (error: Error, result: string) => { - /* istanbul ignore if */ - if (error) { - reject(error); - return; - } - resolve(result); - }); - }); - } - - /** - * Query for name for a given ERC20 asset. - * - * @param address - ERC20 asset contract address. - * @returns Promise resolving to the 'decimals'. - */ - async getTokenDecimals(address: string): Promise { - const contract = this.web3.eth.contract(abiERC20).at(address); - return new Promise((resolve, reject) => { - contract.decimals((error: Error, result: string) => { - /* istanbul ignore if */ - if (error) { - reject(error); - return; - } - resolve(result); - }); - }); + return this.erc721Standard.getCollectibleTokenURI(contract, tokenId); } /** @@ -235,16 +166,7 @@ export class AssetsContractController extends BaseController< */ async getAssetName(address: string): Promise { const contract = this.web3.eth.contract(abiERC721).at(address); - return new Promise((resolve, reject) => { - contract.name((error: Error, result: string) => { - /* istanbul ignore if */ - if (error) { - reject(error); - return; - } - resolve(result); - }); - }); + return this.erc721Standard.getAssetName(contract); } /** @@ -255,16 +177,7 @@ export class AssetsContractController extends BaseController< */ async getAssetSymbol(address: string): Promise { const contract = this.web3.eth.contract(abiERC721).at(address); - return new Promise((resolve, reject) => { - contract.symbol((error: Error, result: string) => { - /* istanbul ignore if */ - if (error) { - reject(error); - return; - } - resolve(result); - }); - }); + return this.erc721Standard.getAssetSymbol(contract); } /** @@ -276,18 +189,41 @@ export class AssetsContractController extends BaseController< */ async getOwnerOf(address: string, tokenId: number): Promise { const contract = this.web3.eth.contract(abiERC721).at(address); - return new Promise((resolve, reject) => { - contract.ownerOf(tokenId, (error: Error, result: string) => { - /* istanbul ignore if */ - if (error) { - reject(error); - return; - } - resolve(result); - }); - }); + return this.erc721Standard.getOwnerOf(contract, tokenId); } + /** + * Query for tokenURI for a given asset. + * + * @param address - ERC1155 asset contract address. + * @param tokenId - ERC1155 asset identifier. + * @returns Promise resolving to the 'tokenURI'. + */ + getCollectibleURI = async ( + address: string, + tokenId: number, + ): Promise => { + const contract = this.web3.eth.contract(abiERC1155).at(address); + return this.erc1155Standard.getCollectibleURI(contract, tokenId); + }; + + /** + * Query for balance of a given ERC 1155 token. + * + * @param userAddress - Wallet public address. + * @param address - ERC1155 asset contract address. + * @param tokenId - ERC1155 asset identifier. + * @returns Promise resolving to the 'balanceOf'. + */ + balanceOf = async ( + userAddress: string, + address: string, + tokenId: string, + ): Promise => { + const contract = this.web3.eth.contract(abiERC1155).at(address); + return this.erc1155Standard.getBalanceOf(contract, userAddress, tokenId); + }; + /** * Get the token balance for a list of token addresses in a single call. Only non-zero balances * are returned. From a0ee10e992150042545f97508ce9e2f95aea5e72 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Fri, 15 Oct 2021 12:20:45 -0300 Subject: [PATCH 06/43] Update tests --- .../ERC1155/ERC1155Standard.test.ts | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts index f23238f0da..402c07a31c 100644 --- a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts +++ b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts @@ -7,12 +7,27 @@ const MAINNET_PROVIDER = new HttpProvider( 'https://mainnet.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', ); +const COLLECTIBLE_ADDRESS = '0x495f947276749ce646f68ac8c248420045cb7b5e'; +const COLLECTIBLE_ID = + '40815311521795738946686668571398122012172359753720345430028676522525371400193'; +const OWNER_ADDRESS = '0x5a3CA5cD63807Ce5e4d7841AB32Ce6B6d9BbBa2D'; + describe('ERC721Standard', () => { - let erc721Standard: ERC1155Standard; + let erc1155Standard: ERC1155Standard; let web3: Web3; beforeEach(() => { - erc721Standard = new ERC1155Standard(); + erc1155Standard = new ERC1155Standard(); web3 = new Web3(MAINNET_PROVIDER); }); -}); \ No newline at end of file + + it('should get the balance of a ERC-1155 collectible', async () => { + const contract = web3.eth.contract(abiERC1155).at(COLLECTIBLE_ADDRESS); + const balance = await erc1155Standard.getBalanceOf( + contract, + OWNER_ADDRESS, + COLLECTIBLE_ID, + ); + expect(balance).toBeGreaterThan(0); + }); +}); From ec7aaac2c361f0350d5159e44630c546615732b9 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Sat, 16 Oct 2021 23:48:00 -0300 Subject: [PATCH 07/43] Update AssetsContractController test --- src/assets/AssetsContractController.test.ts | 41 +++++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/assets/AssetsContractController.test.ts b/src/assets/AssetsContractController.test.ts index f7ff66aceb..b28a48b565 100644 --- a/src/assets/AssetsContractController.test.ts +++ b/src/assets/AssetsContractController.test.ts @@ -8,6 +8,11 @@ const GODSADDRESS = '0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab'; const CKADDRESS = '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d'; const SAI_ADDRESS = '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'; +const COLLECTIBLE_ADDRESS = '0x495f947276749ce646f68ac8c248420045cb7b5e'; +const COLLECTIBLE_ID = + '40815311521795738946686668571398122012172359753720345430028676522525371400193'; +const OWNER_ADDRESS = '0x5a3CA5cD63807Ce5e4d7841AB32Ce6B6d9BbBa2D'; + describe('AssetsContractController', () => { let assetsContract: AssetsContractController; @@ -27,7 +32,7 @@ describe('AssetsContractController', () => { ); }); - it('should get balance of contract correctly', async () => { + it('should get balance of ERC-20 token contract correctly', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const CKBalance = await assetsContract.getBalanceOf( CKADDRESS, @@ -41,7 +46,7 @@ describe('AssetsContractController', () => { expect(CKNoBalance.toNumber()).toStrictEqual(0); }); - it('should get collectible tokenId correctly', async () => { + it('should get ERC-721 collectible tokenId correctly', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const tokenId = await assetsContract.getCollectibleTokenId( GODSADDRESS, @@ -51,13 +56,13 @@ describe('AssetsContractController', () => { expect(tokenId).not.toStrictEqual(0); }); - it('should get collectible tokenURI correctly', async () => { + it('should get ERC-721 collectible tokenURI correctly', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const tokenId = await assetsContract.getCollectibleTokenURI(GODSADDRESS, 0); expect(tokenId).toStrictEqual('https://api.godsunchained.com/card/0'); }); - it('should return empty string as URI when address given is not an NFT', async () => { + it('should return empty string as URI when address given is not an ERC-721 NFT', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const tokenId = await assetsContract.getCollectibleTokenURI( '0x0000000000000000000000000000000000000000', @@ -66,25 +71,25 @@ describe('AssetsContractController', () => { expect(tokenId).toStrictEqual(''); }); - it('should get collectible name', async () => { + it('should get ERC-721 collectible name', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const name = await assetsContract.getAssetName(GODSADDRESS); expect(name).toStrictEqual('Gods Unchained'); }); - it('should get collectible symbol', async () => { + it('should get ERC-721 collectible symbol', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const symbol = await assetsContract.getAssetSymbol(GODSADDRESS); expect(symbol).toStrictEqual('GODS'); }); - it('should get token decimals', async () => { + it('should get ERC-20 token decimals', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const symbol = await assetsContract.getTokenDecimals(SAI_ADDRESS); expect(Number(symbol)).toStrictEqual(18); }); - it('should get collectible ownership', async () => { + it('should get ERC-721 collectible ownership', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const tokenId = await assetsContract.getOwnerOf(GODSADDRESS, 148332); expect(tokenId).not.toStrictEqual(''); @@ -97,4 +102,24 @@ describe('AssetsContractController', () => { ]); expect(balances[SAI_ADDRESS]).not.toStrictEqual(0); }); + + it('should get the balance of a ERC-1155 collectible for a given address', async () => { + assetsContract.configure({ provider: MAINNET_PROVIDER }); + const balance = await assetsContract.balanceOfERC1155( + OWNER_ADDRESS, + COLLECTIBLE_ADDRESS, + COLLECTIBLE_ID, + ); + expect(Number(balance)).toBeGreaterThan(0); + }); + + it('should get the URI of a ERC-1155 collectible', async () => { + assetsContract.configure({ provider: MAINNET_PROVIDER }); + const expectedUri = `https://api.opensea.io/api/v1/metadata/${COLLECTIBLE_ADDRESS}/0x{id}`; + const uri = await assetsContract.uriERC1155( + COLLECTIBLE_ADDRESS, + COLLECTIBLE_ID, + ); + expect(uri.toLowerCase()).toStrictEqual(expectedUri); + }); }); From 862fe9000dc064dba2013ae03dc1eea18aa6ea77 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Sat, 16 Oct 2021 23:48:25 -0300 Subject: [PATCH 08/43] Update method names --- src/assets/AssetsContractController.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/assets/AssetsContractController.ts b/src/assets/AssetsContractController.ts index 2a484a32df..851804577f 100644 --- a/src/assets/AssetsContractController.ts +++ b/src/assets/AssetsContractController.ts @@ -199,10 +199,7 @@ export class AssetsContractController extends BaseController< * @param tokenId - ERC1155 asset identifier. * @returns Promise resolving to the 'tokenURI'. */ - getCollectibleURI = async ( - address: string, - tokenId: number, - ): Promise => { + uriERC1155 = async (address: string, tokenId: string): Promise => { const contract = this.web3.eth.contract(abiERC1155).at(address); return this.erc1155Standard.getCollectibleURI(contract, tokenId); }; @@ -215,7 +212,7 @@ export class AssetsContractController extends BaseController< * @param tokenId - ERC1155 asset identifier. * @returns Promise resolving to the 'balanceOf'. */ - balanceOf = async ( + balanceOfERC1155 = async ( userAddress: string, address: string, tokenId: string, From 626a025f9635083ccdec772eb29e7681a55369df Mon Sep 17 00:00:00 2001 From: gantunesr Date: Sat, 16 Oct 2021 23:49:28 -0300 Subject: [PATCH 09/43] Update method names --- src/assets/AssetsContractController.test.ts | 4 ++-- src/assets/AssetsContractController.ts | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/assets/AssetsContractController.test.ts b/src/assets/AssetsContractController.test.ts index b28a48b565..5bc9b88576 100644 --- a/src/assets/AssetsContractController.test.ts +++ b/src/assets/AssetsContractController.test.ts @@ -105,7 +105,7 @@ describe('AssetsContractController', () => { it('should get the balance of a ERC-1155 collectible for a given address', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const balance = await assetsContract.balanceOfERC1155( + const balance = await assetsContract.balanceOfERC1155Collectible( OWNER_ADDRESS, COLLECTIBLE_ADDRESS, COLLECTIBLE_ID, @@ -116,7 +116,7 @@ describe('AssetsContractController', () => { it('should get the URI of a ERC-1155 collectible', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const expectedUri = `https://api.opensea.io/api/v1/metadata/${COLLECTIBLE_ADDRESS}/0x{id}`; - const uri = await assetsContract.uriERC1155( + const uri = await assetsContract.uriERC1155Collectible( COLLECTIBLE_ADDRESS, COLLECTIBLE_ID, ); diff --git a/src/assets/AssetsContractController.ts b/src/assets/AssetsContractController.ts index 851804577f..378bf19339 100644 --- a/src/assets/AssetsContractController.ts +++ b/src/assets/AssetsContractController.ts @@ -199,7 +199,10 @@ export class AssetsContractController extends BaseController< * @param tokenId - ERC1155 asset identifier. * @returns Promise resolving to the 'tokenURI'. */ - uriERC1155 = async (address: string, tokenId: string): Promise => { + uriERC1155Collectible = async ( + address: string, + tokenId: string, + ): Promise => { const contract = this.web3.eth.contract(abiERC1155).at(address); return this.erc1155Standard.getCollectibleURI(contract, tokenId); }; @@ -212,7 +215,7 @@ export class AssetsContractController extends BaseController< * @param tokenId - ERC1155 asset identifier. * @returns Promise resolving to the 'balanceOf'. */ - balanceOfERC1155 = async ( + balanceOfERC1155Collectible = async ( userAddress: string, address: string, tokenId: string, From 909d63c4870873ad5ebd5f92c1568caa30e90874 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Sat, 16 Oct 2021 23:49:49 -0300 Subject: [PATCH 10/43] Update standard params --- .../ERC1155/ERC1155Standard.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts index 3cb04c5b5f..86bf4395e3 100644 --- a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts +++ b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts @@ -5,14 +5,14 @@ export class ERC1155Standard { /** * Query if contract implements ERC721Metadata interface. * - * @param address - ERC721 asset contract address. + * @param contract - ERC721 asset contract. * @returns Promise resolving to whether the contract implements ERC721Metadata interface. */ contractSupportsURIMetadataInterface = async ( - address: string, + contract: any, ): Promise => { return this.contractSupportsInterface( - address, + contract, ERC1155_METADATA_URI_INTERFACE_ID, ); }; @@ -20,14 +20,14 @@ export class ERC1155Standard { /** * Query if contract implements ERC721Enumerable interface. * - * @param address - ERC721 asset contract address. + * @param contract - ERC721 asset contract. * @returns Promise resolving to whether the contract implements ERC721Enumerable interface. */ contractSupportsTokenReceiverInterface = async ( - address: string, + contract: any, ): Promise => { return this.contractSupportsInterface( - address, + contract, ERC1155_TOKEN_RECEIVER_INTERFACE_ID, ); }; @@ -41,7 +41,7 @@ export class ERC1155Standard { */ getCollectibleURI = async ( contract: any, - tokenId: number, + tokenId: string, ): Promise => { return new Promise((resolve, reject) => { contract.uri(tokenId, (error: Error, result: string) => { @@ -92,7 +92,7 @@ export class ERC1155Standard { interfaceId: string, ): Promise => { return new Promise((resolve, reject) => { - contract.methods.supportsInterface( + contract.supportsInterface( interfaceId, (error: Error, result: boolean) => { /* istanbul ignore if */ From a713b59095fd625fe7c4dcdf5c7b0b88f24f6e7c Mon Sep 17 00:00:00 2001 From: gantunesr Date: Sat, 16 Oct 2021 23:50:10 -0300 Subject: [PATCH 11/43] Update standard tests --- .../ERC1155/ERC1155Standard.test.ts | 17 ++++++----------- .../ERC721/ERC721Standard.test.ts | 2 +- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts index 402c07a31c..d3bdb2d571 100644 --- a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts +++ b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts @@ -7,27 +7,22 @@ const MAINNET_PROVIDER = new HttpProvider( 'https://mainnet.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', ); -const COLLECTIBLE_ADDRESS = '0x495f947276749ce646f68ac8c248420045cb7b5e'; -const COLLECTIBLE_ID = - '40815311521795738946686668571398122012172359753720345430028676522525371400193'; -const OWNER_ADDRESS = '0x5a3CA5cD63807Ce5e4d7841AB32Ce6B6d9BbBa2D'; +const ENJIN_COLLECTIBLE = '0xfaaFDc07907ff5120a76b34b731b278c38d6043C'; describe('ERC721Standard', () => { let erc1155Standard: ERC1155Standard; - let web3: Web3; + let web3: any; beforeEach(() => { erc1155Standard = new ERC1155Standard(); web3 = new Web3(MAINNET_PROVIDER); }); - it('should get the balance of a ERC-1155 collectible', async () => { - const contract = web3.eth.contract(abiERC1155).at(COLLECTIBLE_ADDRESS); - const balance = await erc1155Standard.getBalanceOf( + it('should determine if contract supports URI metadata interface correctly', async () => { + const contract = web3.eth.contract(abiERC1155).at(ENJIN_COLLECTIBLE); + const contractSupportsUri = await erc1155Standard.contractSupportsURIMetadataInterface( contract, - OWNER_ADDRESS, - COLLECTIBLE_ID, ); - expect(balance).toBeGreaterThan(0); + expect(contractSupportsUri).toBe(true); }); }); diff --git a/src/assets/CollectibleStandards/ERC721/ERC721Standard.test.ts b/src/assets/CollectibleStandards/ERC721/ERC721Standard.test.ts index b2a3158796..1afa3b959b 100644 --- a/src/assets/CollectibleStandards/ERC721/ERC721Standard.test.ts +++ b/src/assets/CollectibleStandards/ERC721/ERC721Standard.test.ts @@ -11,7 +11,7 @@ const CKADDRESS = '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d'; describe('ERC721Standard', () => { let erc721Standard: ERC721Standard; - let web3: Web3; + let web3: any; beforeEach(() => { erc721Standard = new ERC721Standard(); From b9e6c9453e3f95539dbf977a822d115e1ba30999 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Sun, 17 Oct 2021 18:40:20 -0300 Subject: [PATCH 12/43] Change variable name --- src/assets/AssetsContractController.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/assets/AssetsContractController.test.ts b/src/assets/AssetsContractController.test.ts index 5bc9b88576..f76e8f1929 100644 --- a/src/assets/AssetsContractController.test.ts +++ b/src/assets/AssetsContractController.test.ts @@ -8,7 +8,7 @@ const GODSADDRESS = '0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab'; const CKADDRESS = '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d'; const SAI_ADDRESS = '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'; -const COLLECTIBLE_ADDRESS = '0x495f947276749ce646f68ac8c248420045cb7b5e'; +const ERC1155_ADDRESS = '0x495f947276749ce646f68ac8c248420045cb7b5e'; const COLLECTIBLE_ID = '40815311521795738946686668571398122012172359753720345430028676522525371400193'; const OWNER_ADDRESS = '0x5a3CA5cD63807Ce5e4d7841AB32Ce6B6d9BbBa2D'; @@ -107,7 +107,7 @@ describe('AssetsContractController', () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const balance = await assetsContract.balanceOfERC1155Collectible( OWNER_ADDRESS, - COLLECTIBLE_ADDRESS, + ERC1155_ADDRESS, COLLECTIBLE_ID, ); expect(Number(balance)).toBeGreaterThan(0); @@ -115,9 +115,9 @@ describe('AssetsContractController', () => { it('should get the URI of a ERC-1155 collectible', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const expectedUri = `https://api.opensea.io/api/v1/metadata/${COLLECTIBLE_ADDRESS}/0x{id}`; + const expectedUri = `https://api.opensea.io/api/v1/metadata/${ERC1155_ADDRESS}/0x{id}`; const uri = await assetsContract.uriERC1155Collectible( - COLLECTIBLE_ADDRESS, + ERC1155_ADDRESS, COLLECTIBLE_ID, ); expect(uri.toLowerCase()).toStrictEqual(expectedUri); From fac7f5cdfb983e6fd189c175455c58f828275e16 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Sun, 17 Oct 2021 18:41:35 -0300 Subject: [PATCH 13/43] Change variable name --- src/assets/AssetsContractController.test.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/assets/AssetsContractController.test.ts b/src/assets/AssetsContractController.test.ts index f76e8f1929..6cd800466a 100644 --- a/src/assets/AssetsContractController.test.ts +++ b/src/assets/AssetsContractController.test.ts @@ -8,10 +8,11 @@ const GODSADDRESS = '0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab'; const CKADDRESS = '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d'; const SAI_ADDRESS = '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'; -const ERC1155_ADDRESS = '0x495f947276749ce646f68ac8c248420045cb7b5e'; -const COLLECTIBLE_ID = +const ERC1155_COLLECTIBLE_ADDRESS = + '0x495f947276749ce646f68ac8c248420045cb7b5e'; +const ERC1155_COLLECTIBLE_ID = '40815311521795738946686668571398122012172359753720345430028676522525371400193'; -const OWNER_ADDRESS = '0x5a3CA5cD63807Ce5e4d7841AB32Ce6B6d9BbBa2D'; +const ERC1155_OWNER_ADDRESS = '0x5a3CA5cD63807Ce5e4d7841AB32Ce6B6d9BbBa2D'; describe('AssetsContractController', () => { let assetsContract: AssetsContractController; @@ -106,9 +107,9 @@ describe('AssetsContractController', () => { it('should get the balance of a ERC-1155 collectible for a given address', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const balance = await assetsContract.balanceOfERC1155Collectible( - OWNER_ADDRESS, - ERC1155_ADDRESS, - COLLECTIBLE_ID, + ERC1155_OWNER_ADDRESS, + ERC1155_COLLECTIBLE_ADDRESS, + ERC1155_COLLECTIBLE_ID, ); expect(Number(balance)).toBeGreaterThan(0); }); @@ -117,8 +118,8 @@ describe('AssetsContractController', () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const expectedUri = `https://api.opensea.io/api/v1/metadata/${ERC1155_ADDRESS}/0x{id}`; const uri = await assetsContract.uriERC1155Collectible( - ERC1155_ADDRESS, - COLLECTIBLE_ID, + ERC1155_COLLECTIBLE_ADDRESS, + ERC1155_COLLECTIBLE_ID, ); expect(uri.toLowerCase()).toStrictEqual(expectedUri); }); From 2dd05eb259c8b47f40591ca3b0e6276f2f4ac25e Mon Sep 17 00:00:00 2001 From: gantunesr Date: Sun, 17 Oct 2021 18:49:05 -0300 Subject: [PATCH 14/43] Change variable name --- src/assets/AssetsContractController.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/AssetsContractController.test.ts b/src/assets/AssetsContractController.test.ts index 6cd800466a..3538d9f719 100644 --- a/src/assets/AssetsContractController.test.ts +++ b/src/assets/AssetsContractController.test.ts @@ -116,7 +116,7 @@ describe('AssetsContractController', () => { it('should get the URI of a ERC-1155 collectible', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const expectedUri = `https://api.opensea.io/api/v1/metadata/${ERC1155_ADDRESS}/0x{id}`; + const expectedUri = `https://api.opensea.io/api/v1/metadata/${ERC1155_COLLECTIBLE_ADDRESS}/0x{id}`; const uri = await assetsContract.uriERC1155Collectible( ERC1155_COLLECTIBLE_ADDRESS, ERC1155_COLLECTIBLE_ID, From 5282b7a75763a3b1e2a608bf128e2a2ee7e0a6b8 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Sun, 17 Oct 2021 22:08:19 -0300 Subject: [PATCH 15/43] Update AssetsContractController methods --- src/assets/AssetsContractController.ts | 28 +++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/assets/AssetsContractController.ts b/src/assets/AssetsContractController.ts index 378bf19339..a582445cfb 100644 --- a/src/assets/AssetsContractController.ts +++ b/src/assets/AssetsContractController.ts @@ -199,30 +199,34 @@ export class AssetsContractController extends BaseController< * @param tokenId - ERC1155 asset identifier. * @returns Promise resolving to the 'tokenURI'. */ - uriERC1155Collectible = async ( + async uriERC1155Collectible( address: string, tokenId: string, - ): Promise => { + ): Promise { const contract = this.web3.eth.contract(abiERC1155).at(address); return this.erc1155Standard.getCollectibleURI(contract, tokenId); - }; + } /** * Query for balance of a given ERC 1155 token. * * @param userAddress - Wallet public address. - * @param address - ERC1155 asset contract address. - * @param tokenId - ERC1155 asset identifier. + * @param collectibleaddress - ERC1155 asset contract address. + * @param collectibleId - ERC1155 asset identifier. * @returns Promise resolving to the 'balanceOf'. */ - balanceOfERC1155Collectible = async ( + async balanceOfERC1155Collectible( userAddress: string, - address: string, - tokenId: string, - ): Promise => { - const contract = this.web3.eth.contract(abiERC1155).at(address); - return this.erc1155Standard.getBalanceOf(contract, userAddress, tokenId); - }; + collectibleaddress: string, + collectibleId: string, + ): Promise { + const contract = this.web3.eth.contract(abiERC1155).at(collectibleaddress); + return await this.erc1155Standard.getBalanceOf( + contract, + userAddress, + collectibleId, + ); + } /** * Get the token balance for a list of token addresses in a single call. Only non-zero balances From c224f72eaff0d87419f09117d4898f6dbe5dea7f Mon Sep 17 00:00:00 2001 From: gantunesr Date: Sun, 17 Oct 2021 22:08:57 -0300 Subject: [PATCH 16/43] Add method to verify collectible ownership --- src/assets/CollectiblesController.ts | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index a009964114..c1666cfd92 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -649,6 +649,10 @@ export class CollectiblesController extends BaseController< private getCollectibleTokenURI: AssetsContractController['getCollectibleTokenURI']; + private getOwnerOf: AssetsContractController['getOwnerOf']; + + private balanceOfERC1155Collectible: AssetsContractController['balanceOfERC1155Collectible']; + /** * Creates a CollectiblesController instance. * @@ -658,6 +662,8 @@ export class CollectiblesController extends BaseController< * @param options.getAssetName - Gets the name of the asset at the given address. * @param options.getAssetSymbol - Gets the symbol of the asset at the given address. * @param options.getCollectibleTokenURI - Gets the URI of the NFT at the given address, with the given ID. + * @param options.getOwnerOf - Get the owner of a ERC-721 collectible. + * @param options.balanceOfERC1155Collectible - Gets balance of a ERC-1155 collectible. * @param config - Initial options used to configure this controller. * @param state - Initial state to set on this controller. */ @@ -668,6 +674,8 @@ export class CollectiblesController extends BaseController< getAssetName, getAssetSymbol, getCollectibleTokenURI, + getOwnerOf, + balanceOfERC1155Collectible, }: { onPreferencesStateChange: ( listener: (preferencesState: PreferencesState) => void, @@ -678,6 +686,8 @@ export class CollectiblesController extends BaseController< getAssetName: AssetsContractController['getAssetName']; getAssetSymbol: AssetsContractController['getAssetSymbol']; getCollectibleTokenURI: AssetsContractController['getCollectibleTokenURI']; + getOwnerOf: AssetsContractController['getOwnerOf']; + balanceOfERC1155Collectible: AssetsContractController['balanceOfERC1155Collectible']; }, config?: Partial, state?: Partial, @@ -700,6 +710,8 @@ export class CollectiblesController extends BaseController< this.getAssetName = getAssetName; this.getAssetSymbol = getAssetSymbol; this.getCollectibleTokenURI = getCollectibleTokenURI; + this.getOwnerOf = getOwnerOf; + this.balanceOfERC1155Collectible = balanceOfERC1155Collectible; onPreferencesStateChange(({ selectedAddress }) => { const { allCollectibleContracts, allCollectibles } = this.state; const { chainId } = this.config; @@ -733,6 +745,45 @@ export class CollectiblesController extends BaseController< this.openSeaApiKey = openSeaApiKey; } + /** + * Checks the ownership of a ERC-721 or ERC-1155 collectible for a given address. + * + * @param ownerAddress - User public address. + * @param collectibleAddress - Collectible contract address. + * @param collectibleId - Collectible token ID. + * @returns Promise resolving the collectible ownership. + */ + async checkCollectibleOwnership( + ownerAddress: string, + collectibleAddress: string, + collectibleId: string, + ): Promise { + // Checks the ownership of a ERC-721. + try { + const owner = await this.getOwnerOf( + collectibleAddress, + Number(collectibleId), + ); + return ownerAddress.toLowerCase() === owner.toLowerCase(); + // eslint-disable-next-line no-empty + } catch {} + + // Checks the ownership of a ERC-1155. + try { + const balance = await this.balanceOfERC1155Collectible( + ownerAddress, + collectibleAddress, + collectibleId, + ); + return balance > 0; + // eslint-disable-next-line no-empty + } catch {} + + throw new Error( + 'Error: Unable to determine ownership. Probably because the standard is not supported or the chain is incorrect', + ); + } + /** * Adds a collectible and respective collectible contract to the stored collectible and collectible contracts lists. * From d08cf1f94d2fe3d4ebdb2eea919c3dc1195f5953 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Sun, 17 Oct 2021 22:09:17 -0300 Subject: [PATCH 17/43] Update CollectiblesController tests --- src/assets/CollectiblesController.test.ts | 66 ++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/src/assets/CollectiblesController.test.ts b/src/assets/CollectiblesController.test.ts index 4ff4a7c753..5b77c8838e 100644 --- a/src/assets/CollectiblesController.test.ts +++ b/src/assets/CollectiblesController.test.ts @@ -10,6 +10,13 @@ import { AssetsContractController } from './AssetsContractController'; import { CollectiblesController } from './CollectiblesController'; const KUDOSADDRESS = '0x2aea4add166ebf38b63d09a75de1a7b94aa24163'; +const ERC721_COLLECTIBLE_ADDRESS = '0x60f80121c31a0d46b5279700f9df786054aa5ee5'; +const ERC721_COLLECTIBLE_ID = 1144858; +const ERC1155_COLLECTIBLE_ADDRESS = + '0x495f947276749ce646f68ac8c248420045cb7b5e'; +const ERC1155_COLLECTIBLE_ID = + '40815311521795738946686668571398122012172359753720345430028676522525371400193'; +const OWNER_ADDRESS = '0x5a3CA5cD63807Ce5e4d7841AB32Ce6B6d9BbBa2D'; const MAINNET_PROVIDER = new HttpProvider( 'https://mainnet.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', ); @@ -35,6 +42,10 @@ describe('CollectiblesController', () => { getCollectibleTokenURI: assetsContract.getCollectibleTokenURI.bind( assetsContract, ), + getOwnerOf: assetsContract.getOwnerOf.bind(assetsContract), + balanceOfERC1155Collectible: assetsContract.balanceOfERC1155Collectible.bind( + assetsContract, + ), }); nock(OPEN_SEA_HOST) @@ -318,7 +329,6 @@ describe('CollectiblesController', () => { true, ); - console.log(collectiblesController.state.collectibles); expect(collectiblesController.state.collectibles).toStrictEqual([ { address: '0x2aEa4Add166EBf38b63d09a75dE1a7b94Aa24163', @@ -497,4 +507,58 @@ describe('CollectiblesController', () => { collectiblesController.setApiKey('new-api-key'); expect(collectiblesController.openSeaApiKey).toBe('new-api-key'); }); + + it('should verify the ownership of a ERC-721 collectible with the correct owner address', async () => { + assetsContract.configure({ provider: MAINNET_PROVIDER }); + const isOwner = await collectiblesController.checkCollectibleOwnership( + OWNER_ADDRESS, + ERC721_COLLECTIBLE_ADDRESS, + String(ERC721_COLLECTIBLE_ID), + ); + expect(isOwner).toBe(true); + }); + + it('should not verify the ownership of a ERC-721 collectible with the wrong owner address', async () => { + assetsContract.configure({ provider: MAINNET_PROVIDER }); + const isOwner = await collectiblesController.checkCollectibleOwnership( + '0x0000000000000000000000000000000000000000', + ERC721_COLLECTIBLE_ADDRESS, + String(ERC721_COLLECTIBLE_ID), + ); + expect(isOwner).toBe(false); + }); + + it('should verify the ownership of a ERC-1155 collectible with the correct owner address', async () => { + assetsContract.configure({ provider: MAINNET_PROVIDER }); + const isOwner = await collectiblesController.checkCollectibleOwnership( + OWNER_ADDRESS, + ERC1155_COLLECTIBLE_ADDRESS, + ERC1155_COLLECTIBLE_ID, + ); + expect(isOwner).toBe(true); + }); + + it('should not verify the ownership of a ERC-1155 collectible with the wrong owner address', async () => { + assetsContract.configure({ provider: MAINNET_PROVIDER }); + const isOwner = await collectiblesController.checkCollectibleOwnership( + '0x0000000000000000000000000000000000000000', + ERC1155_COLLECTIBLE_ADDRESS, + ERC1155_COLLECTIBLE_ID, + ); + expect(isOwner).toBe(false); + }); + + it('should throw an error for an unsupported standard', async () => { + assetsContract.configure({ provider: MAINNET_PROVIDER }); + const error = + 'Error: Unable to determine ownership. Probably because the standard is not supported or the chain is incorrect'; + const result = async () => { + await collectiblesController.checkCollectibleOwnership( + '0x0000000000000000000000000000000000000000', + '0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB', + '0', + ); + }; + await expect(result).rejects.toThrow(error); + }); }); From ffe7983570b9103293c8384df159fcbd3b1d8c5e Mon Sep 17 00:00:00 2001 From: gantunesr Date: Mon, 18 Oct 2021 09:40:39 -0300 Subject: [PATCH 18/43] Nit --- src/assets/CollectiblesController.test.ts | 13 +++++++------ src/assets/CollectiblesController.ts | 10 +++++++--- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/assets/CollectiblesController.test.ts b/src/assets/CollectiblesController.test.ts index 5b77c8838e..9daa160c67 100644 --- a/src/assets/CollectiblesController.test.ts +++ b/src/assets/CollectiblesController.test.ts @@ -10,6 +10,7 @@ import { AssetsContractController } from './AssetsContractController'; import { CollectiblesController } from './CollectiblesController'; const KUDOSADDRESS = '0x2aea4add166ebf38b63d09a75de1a7b94aa24163'; +const CRYPTOPUNK_ADDRESS = '0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB'; const ERC721_COLLECTIBLE_ADDRESS = '0x60f80121c31a0d46b5279700f9df786054aa5ee5'; const ERC721_COLLECTIBLE_ID = 1144858; const ERC1155_COLLECTIBLE_ADDRESS = @@ -508,7 +509,7 @@ describe('CollectiblesController', () => { expect(collectiblesController.openSeaApiKey).toBe('new-api-key'); }); - it('should verify the ownership of a ERC-721 collectible with the correct owner address', async () => { + it('should verify the ownership of an ERC-721 collectible with the correct owner address', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const isOwner = await collectiblesController.checkCollectibleOwnership( OWNER_ADDRESS, @@ -518,7 +519,7 @@ describe('CollectiblesController', () => { expect(isOwner).toBe(true); }); - it('should not verify the ownership of a ERC-721 collectible with the wrong owner address', async () => { + it('should not verify the ownership of an ERC-721 collectible with the wrong owner address', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const isOwner = await collectiblesController.checkCollectibleOwnership( '0x0000000000000000000000000000000000000000', @@ -528,7 +529,7 @@ describe('CollectiblesController', () => { expect(isOwner).toBe(false); }); - it('should verify the ownership of a ERC-1155 collectible with the correct owner address', async () => { + it('should verify the ownership of an ERC-1155 collectible with the correct owner address', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const isOwner = await collectiblesController.checkCollectibleOwnership( OWNER_ADDRESS, @@ -538,7 +539,7 @@ describe('CollectiblesController', () => { expect(isOwner).toBe(true); }); - it('should not verify the ownership of a ERC-1155 collectible with the wrong owner address', async () => { + it('should not verify the ownership of an ERC-1155 collectible with the wrong owner address', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const isOwner = await collectiblesController.checkCollectibleOwnership( '0x0000000000000000000000000000000000000000', @@ -551,11 +552,11 @@ describe('CollectiblesController', () => { it('should throw an error for an unsupported standard', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const error = - 'Error: Unable to determine ownership. Probably because the standard is not supported or the chain is incorrect'; + 'Unable to determine ownership. Probably because the standard is not supported or the chain is incorrect'; const result = async () => { await collectiblesController.checkCollectibleOwnership( '0x0000000000000000000000000000000000000000', - '0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB', + CRYPTOPUNK_ADDRESS, '0', ); }; diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index c1666cfd92..21c068c53d 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -766,7 +766,9 @@ export class CollectiblesController extends BaseController< ); return ownerAddress.toLowerCase() === owner.toLowerCase(); // eslint-disable-next-line no-empty - } catch {} + } catch { + // Ignore ERC-721 contract error + } // Checks the ownership of a ERC-1155. try { @@ -777,10 +779,12 @@ export class CollectiblesController extends BaseController< ); return balance > 0; // eslint-disable-next-line no-empty - } catch {} + } catch { + // Ignore ERC-1155 contract error + } throw new Error( - 'Error: Unable to determine ownership. Probably because the standard is not supported or the chain is incorrect', + 'Unable to verify ownership. Probably because the standard is not supported or the chain is incorrect.', ); } From b8331d70ff61601f1bc036dc757824f26871241b Mon Sep 17 00:00:00 2001 From: gantunesr Date: Mon, 18 Oct 2021 09:55:34 -0300 Subject: [PATCH 19/43] Update test --- src/assets/CollectiblesController.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/CollectiblesController.test.ts b/src/assets/CollectiblesController.test.ts index 9daa160c67..df0db3dfcb 100644 --- a/src/assets/CollectiblesController.test.ts +++ b/src/assets/CollectiblesController.test.ts @@ -552,7 +552,7 @@ describe('CollectiblesController', () => { it('should throw an error for an unsupported standard', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const error = - 'Unable to determine ownership. Probably because the standard is not supported or the chain is incorrect'; + 'Unable to verify ownership. Probably because the standard is not supported or the chain is incorrect'; const result = async () => { await collectiblesController.checkCollectibleOwnership( '0x0000000000000000000000000000000000000000', From 3c57e51a91e474e9dcd6ac30b6ebee3ec3623be3 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Mon, 18 Oct 2021 10:00:18 -0300 Subject: [PATCH 20/43] Update tests --- src/ComposableController.test.ts | 12 ++++++++++++ src/assets/AssetsDetectionController.test.ts | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/src/ComposableController.test.ts b/src/ComposableController.test.ts index c7f335f022..c4e2518540 100644 --- a/src/ComposableController.test.ts +++ b/src/ComposableController.test.ts @@ -106,6 +106,12 @@ describe('ComposableController', () => { getCollectibleTokenURI: assetContractController.getCollectibleTokenURI.bind( assetContractController, ), + getOwnerOf: assetContractController.getOwnerOf.bind( + assetContractController, + ), + balanceOfERC1155Collectible: assetContractController.balanceOfERC1155Collectible.bind( + assetContractController, + ), }); const tokensController = new TokensController({ onPreferencesStateChange: (listener) => @@ -178,6 +184,12 @@ describe('ComposableController', () => { getCollectibleTokenURI: assetContractController.getCollectibleTokenURI.bind( assetContractController, ), + getOwnerOf: assetContractController.getOwnerOf.bind( + assetContractController, + ), + balanceOfERC1155Collectible: assetContractController.balanceOfERC1155Collectible.bind( + assetContractController, + ), }); const tokensController = new TokensController({ onPreferencesStateChange: (listener) => diff --git a/src/assets/AssetsDetectionController.test.ts b/src/assets/AssetsDetectionController.test.ts index 64e6e73271..d0900958e1 100644 --- a/src/assets/AssetsDetectionController.test.ts +++ b/src/assets/AssetsDetectionController.test.ts @@ -137,6 +137,10 @@ describe('AssetsDetectionController', () => { getCollectibleTokenURI: assetsContract.getCollectibleTokenURI.bind( assetsContract, ), + getOwnerOf: assetsContract.getOwnerOf.bind(assetsContract), + balanceOfERC1155Collectible: assetsContract.balanceOfERC1155Collectible.bind( + assetsContract, + ), }); nock(TOKEN_END_POINT_API) From 87fc46acdbba23c6c1c88b8ff7c364f0d131fb8e Mon Sep 17 00:00:00 2001 From: gantunesr Date: Tue, 19 Oct 2021 15:34:30 -0300 Subject: [PATCH 21/43] Change tokenId from number to string --- src/assets/AssetsContractController.ts | 6 +- src/assets/AssetsDetectionController.test.ts | 16 ++-- src/assets/AssetsDetectionController.ts | 4 +- .../ERC721/ERC721Standard.ts | 14 ++- src/assets/CollectiblesController.test.ts | 86 +++++++++---------- src/assets/CollectiblesController.ts | 27 +++--- 6 files changed, 74 insertions(+), 79 deletions(-) diff --git a/src/assets/AssetsContractController.ts b/src/assets/AssetsContractController.ts index a582445cfb..b6704acec2 100644 --- a/src/assets/AssetsContractController.ts +++ b/src/assets/AssetsContractController.ts @@ -134,7 +134,7 @@ export class AssetsContractController extends BaseController< address: string, selectedAddress: string, index: number, - ): Promise { + ): Promise { const contract = this.web3.eth.contract(abiERC721).at(address); return this.erc721Standard.getCollectibleTokenId( contract, @@ -152,7 +152,7 @@ export class AssetsContractController extends BaseController< */ async getCollectibleTokenURI( address: string, - tokenId: number, + tokenId: string, ): Promise { const contract = this.web3.eth.contract(abiERC721).at(address); return this.erc721Standard.getCollectibleTokenURI(contract, tokenId); @@ -187,7 +187,7 @@ export class AssetsContractController extends BaseController< * @param tokenId - ERC721 asset identifier. * @returns Promise resolving to the owner address. */ - async getOwnerOf(address: string, tokenId: number): Promise { + async getOwnerOf(address: string, tokenId: string): Promise { const contract = this.web3.eth.contract(abiERC721).at(address); return this.erc721Standard.getOwnerOf(contract, tokenId); } diff --git a/src/assets/AssetsDetectionController.test.ts b/src/assets/AssetsDetectionController.test.ts index d0900958e1..b8c3cd73b3 100644 --- a/src/assets/AssetsDetectionController.test.ts +++ b/src/assets/AssetsDetectionController.test.ts @@ -402,7 +402,7 @@ describe('AssetsDetectionController', () => { description: 'Description 2574', image: 'image/2574.png', name: 'ID 2574', - tokenId: 2574, + tokenId: '2574', }, ]); }); @@ -411,7 +411,7 @@ describe('AssetsDetectionController', () => { assetsDetection.configure({ networkType: MAINNET, selectedAddress: '0x1' }); await collectiblesController.addCollectible( '0xebE4e5E773AFD2bAc25De0cFafa084CFb3cBf1eD', - 2573, + '2573', { description: 'Description 2573', image: 'image/2573.png', @@ -425,14 +425,14 @@ describe('AssetsDetectionController', () => { description: 'Description 2573', image: 'image/2573.png', name: 'ID 2573', - tokenId: 2573, + tokenId: '2573', }, { address: '0xebE4e5E773AFD2bAc25De0cFafa084CFb3cBf1eD', description: 'Description 2574', image: 'image/2574.png', name: 'ID 2574', - tokenId: 2574, + tokenId: '2574', }, ]); }); @@ -444,7 +444,7 @@ describe('AssetsDetectionController', () => { expect(collectiblesController.state.ignoredCollectibles).toHaveLength(0); collectiblesController.removeAndIgnoreCollectible( '0x1d963688fe2209a98db35c67a041524822cf04ff', - 2577, + '2577', ); await assetsDetection.detectCollectibles(); expect(collectiblesController.state.collectibles).toHaveLength(0); @@ -477,21 +477,21 @@ describe('AssetsDetectionController', () => { description: 'Description 2574', image: 'image/2574.png', name: 'ID 2574', - tokenId: 2574, + tokenId: '2574', }; const collectibleGG2574 = { address: '0xCE7ec4B2DfB30eB6c0BB5656D33aAd6BFb4001Fc', description: 'Description 2574', image: 'image/2574.png', name: 'ID 2574', - tokenId: 2574, + tokenId: '2574', }; const collectibleII2577 = { address: '0x0B0fa4fF58D28A88d63235bd0756EDca69e49e6d', description: 'Description 2577', image: 'image/2577.png', name: 'ID 2577', - tokenId: 2577, + tokenId: '2577', }; const collectibleContractHH = { address: '0xebE4e5E773AFD2bAc25De0cFafa084CFb3cBf1eD', diff --git a/src/assets/AssetsDetectionController.ts b/src/assets/AssetsDetectionController.ts index 90d821737a..769a0cfd64 100644 --- a/src/assets/AssetsDetectionController.ts +++ b/src/assets/AssetsDetectionController.ts @@ -430,7 +430,7 @@ export class AssetsDetectionController extends BaseController< /* istanbul ignore next */ return ( c.address === toChecksumHexAddress(address) && - c.tokenId === Number(token_id) + c.tokenId === token_id ); }); } @@ -461,7 +461,7 @@ export class AssetsDetectionController extends BaseController< ); await this.addCollectible( address, - Number(token_id), + token_id, collectibleMetadata, true, ); diff --git a/src/assets/CollectibleStandards/ERC721/ERC721Standard.ts b/src/assets/CollectibleStandards/ERC721/ERC721Standard.ts index 83a6ab945b..657e0ae66d 100644 --- a/src/assets/CollectibleStandards/ERC721/ERC721Standard.ts +++ b/src/assets/CollectibleStandards/ERC721/ERC721Standard.ts @@ -1,5 +1,3 @@ -import { BN } from 'ethereumjs-util'; - const ERC721_METADATA_INTERFACE_ID = '0x5b5e139f'; const ERC721_ENUMERABLE_INTERFACE_ID = '0x780e9d63'; @@ -46,18 +44,18 @@ export class ERC721Standard { contract: any, selectedAddress: string, index: number, - ): Promise => { - return new Promise((resolve, reject) => { + ): Promise => { + return new Promise((resolve, reject) => { contract.tokenOfOwnerByIndex( selectedAddress, index, - (error: Error, result: BN) => { + (error: Error, result: string) => { /* istanbul ignore if */ if (error) { reject(error); return; } - resolve(result.toNumber()); + resolve(result); }, ); }); @@ -72,7 +70,7 @@ export class ERC721Standard { */ getCollectibleTokenURI = async ( contract: any, - tokenId: number, + tokenId: string, ): Promise => { const supportsMetadata = await this.contractSupportsMetadataInterface( contract, @@ -137,7 +135,7 @@ export class ERC721Standard { * @param tokenId - ERC721 asset identifier. * @returns Promise resolving to the owner address. */ - async getOwnerOf(contract: any, tokenId: number): Promise { + async getOwnerOf(contract: any, tokenId: string): Promise { return new Promise((resolve, reject) => { contract.ownerOf(tokenId, (error: Error, result: string) => { /* istanbul ignore if */ diff --git a/src/assets/CollectiblesController.test.ts b/src/assets/CollectiblesController.test.ts index df0db3dfcb..58c4093945 100644 --- a/src/assets/CollectiblesController.test.ts +++ b/src/assets/CollectiblesController.test.ts @@ -12,7 +12,7 @@ import { CollectiblesController } from './CollectiblesController'; const KUDOSADDRESS = '0x2aea4add166ebf38b63d09a75de1a7b94aa24163'; const CRYPTOPUNK_ADDRESS = '0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB'; const ERC721_COLLECTIBLE_ADDRESS = '0x60f80121c31a0d46b5279700f9df786054aa5ee5'; -const ERC721_COLLECTIBLE_ID = 1144858; +const ERC721_COLLECTIBLE_ID = '1144858'; const ERC1155_COLLECTIBLE_ADDRESS = '0x495f947276749ce646f68ac8c248420045cb7b5e'; const ERC1155_COLLECTIBLE_ID = @@ -132,7 +132,7 @@ describe('CollectiblesController', () => { }); it('should add collectible and collectible contract', async () => { - await collectiblesController.addCollectible('0x01', 1, { + await collectiblesController.addCollectible('0x01', '1', { name: 'name', image: 'image', description: 'description', @@ -143,7 +143,7 @@ describe('CollectiblesController', () => { description: 'description', image: 'image', name: 'name', - tokenId: 1, + tokenId: '1', }); expect(collectiblesController.state.collectibleContracts[0]).toStrictEqual({ @@ -157,7 +157,7 @@ describe('CollectiblesController', () => { }); it('should update collectible if image is different', async () => { - await collectiblesController.addCollectible('0x01', 1, { + await collectiblesController.addCollectible('0x01', '1', { name: 'name', image: 'image', description: 'description', @@ -168,10 +168,10 @@ describe('CollectiblesController', () => { description: 'description', image: 'image', name: 'name', - tokenId: 1, + tokenId: '1', }); - await collectiblesController.addCollectible('0x01', 1, { + await collectiblesController.addCollectible('0x01', '1', { name: 'name', image: 'image-updated', description: 'description', @@ -182,18 +182,18 @@ describe('CollectiblesController', () => { description: 'description', image: 'image-updated', name: 'name', - tokenId: 1, + tokenId: '1', }); }); it('should not duplicate collectible nor collectible contract if already added', async () => { - await collectiblesController.addCollectible('0x01', 1, { + await collectiblesController.addCollectible('0x01', '1', { name: 'name', image: 'image', description: 'description', }); - await collectiblesController.addCollectible('0x01', 1, { + await collectiblesController.addCollectible('0x01', '1', { name: 'name', image: 'image', description: 'description', @@ -203,13 +203,13 @@ describe('CollectiblesController', () => { }); it('should not add collectible contract if collectible contract already exists', async () => { - await collectiblesController.addCollectible('0x01', 1, { + await collectiblesController.addCollectible('0x01', '1', { name: 'name', image: 'image', description: 'description', }); - await collectiblesController.addCollectible('0x01', 2, { + await collectiblesController.addCollectible('0x01', '2', { name: 'name', image: 'image', description: 'description', @@ -219,14 +219,14 @@ describe('CollectiblesController', () => { }); it('should add collectible and get information from OpenSea', async () => { - await collectiblesController.addCollectible('0x01', 1); + await collectiblesController.addCollectible('0x01', '1'); expect(collectiblesController.state.collectibles[0]).toStrictEqual({ address: '0x01', description: 'Description', imageOriginal: 'url', name: 'Name', standard: 'ERC1155', - tokenId: 1, + tokenId: '1', }); }); @@ -242,12 +242,12 @@ describe('CollectiblesController', () => { sandbox .stub(collectiblesController, 'getCollectibleInformationFromApi' as any) .returns(undefined); - await collectiblesController.addCollectible(KUDOSADDRESS, 1203); + await collectiblesController.addCollectible(KUDOSADDRESS, '1203'); expect(collectiblesController.state.collectibles[0]).toStrictEqual({ address: '0x2aEa4Add166EBf38b63d09a75dE1a7b94Aa24163', image: 'Kudos Image', name: 'Kudos Name', - tokenId: 1203, + tokenId: '1203', }); expect(collectiblesController.state.collectibleContracts[0]).toStrictEqual({ @@ -264,16 +264,16 @@ describe('CollectiblesController', () => { .stub(collectiblesController, 'getCollectibleInformation' as any) .returns({ name: 'name', image: 'url', description: 'description' }); preferences.update({ selectedAddress: firstAddress }); - await collectiblesController.addCollectible('0x01', 1234); + await collectiblesController.addCollectible('0x01', '1234'); preferences.update({ selectedAddress: secondAddress }); - await collectiblesController.addCollectible('0x02', 4321); + await collectiblesController.addCollectible('0x02', '4321'); preferences.update({ selectedAddress: firstAddress }); expect(collectiblesController.state.collectibles[0]).toStrictEqual({ address: '0x01', description: 'description', image: 'url', name: 'name', - tokenId: 1234, + tokenId: '1234', }); }); @@ -290,7 +290,7 @@ describe('CollectiblesController', () => { chainId: NetworksChainId[firstNetworkType], }, }); - await collectiblesController.addCollectible('0x01', 1234); + await collectiblesController.addCollectible('0x01', '1234'); network.update({ provider: { type: secondNetworkType, @@ -310,14 +310,14 @@ describe('CollectiblesController', () => { description: 'description', image: 'url', name: 'name', - tokenId: 1234, + tokenId: '1234', }); }); it('should not add collectibles with no contract information when auto detecting', async () => { await collectiblesController.addCollectible( '0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab', - 123, + '123', undefined, true, ); @@ -325,7 +325,7 @@ describe('CollectiblesController', () => { expect(collectiblesController.state.collectibleContracts).toStrictEqual([]); await collectiblesController.addCollectible( '0x2aEa4Add166EBf38b63d09a75dE1a7b94Aa24163', - 1203, + '1203', undefined, true, ); @@ -337,7 +337,7 @@ describe('CollectiblesController', () => { imageOriginal: 'Kudos url', name: 'Kudos Name', standard: 'ERC721', - tokenId: 1203, + tokenId: '1203', }, ]); @@ -354,29 +354,29 @@ describe('CollectiblesController', () => { }); it('should remove collectible and collectible contract', async () => { - await collectiblesController.addCollectible('0x01', 1, { + await collectiblesController.addCollectible('0x01', '1', { name: 'name', image: 'image', description: 'description', }); - collectiblesController.removeCollectible('0x01', 1); + collectiblesController.removeCollectible('0x01', '1'); expect(collectiblesController.state.collectibles).toHaveLength(0); expect(collectiblesController.state.collectibleContracts).toHaveLength(0); }); it('should not remove collectible contract if collectible still exists', async () => { - await collectiblesController.addCollectible('0x01', 1, { + await collectiblesController.addCollectible('0x01', '1', { name: 'name', image: 'image', description: 'description', }); - await collectiblesController.addCollectible('0x01', 2, { + await collectiblesController.addCollectible('0x01', '2', { name: 'name', image: 'image', description: 'description', }); - collectiblesController.removeCollectible('0x01', 1); + collectiblesController.removeCollectible('0x01', '1'); expect(collectiblesController.state.collectibles).toHaveLength(1); expect(collectiblesController.state.collectibleContracts).toHaveLength(1); }); @@ -388,10 +388,10 @@ describe('CollectiblesController', () => { const firstAddress = '0x123'; const secondAddress = '0x321'; preferences.update({ selectedAddress: firstAddress }); - await collectiblesController.addCollectible('0x02', 4321); + await collectiblesController.addCollectible('0x02', '4321'); preferences.update({ selectedAddress: secondAddress }); - await collectiblesController.addCollectible('0x01', 1234); - collectiblesController.removeCollectible('0x01', 1234); + await collectiblesController.addCollectible('0x01', '1234'); + collectiblesController.removeCollectible('0x01', '1234'); expect(collectiblesController.state.collectibles).toHaveLength(0); preferences.update({ selectedAddress: firstAddress }); expect(collectiblesController.state.collectibles[0]).toStrictEqual({ @@ -399,7 +399,7 @@ describe('CollectiblesController', () => { description: 'description', image: 'url', name: 'name', - tokenId: 4321, + tokenId: '4321', }); }); @@ -415,16 +415,16 @@ describe('CollectiblesController', () => { chainId: NetworksChainId[firstNetworkType], }, }); - await collectiblesController.addCollectible('0x02', 4321); + await collectiblesController.addCollectible('0x02', '4321'); network.update({ provider: { type: secondNetworkType, chainId: NetworksChainId[secondNetworkType], }, }); - await collectiblesController.addCollectible('0x01', 1234); + await collectiblesController.addCollectible('0x01', '1234'); // collectiblesController.removeToken('0x01'); - collectiblesController.removeCollectible('0x01', 1234); + collectiblesController.removeCollectible('0x01', '1234'); expect(collectiblesController.state.collectibles).toHaveLength(0); network.update({ provider: { @@ -438,7 +438,7 @@ describe('CollectiblesController', () => { description: 'description', image: 'url', name: 'name', - tokenId: 4321, + tokenId: '4321', }); }); @@ -454,13 +454,13 @@ describe('CollectiblesController', () => { }); it('should not add duplicate collectibles to the ignoredCollectibles list', async () => { - await collectiblesController.addCollectible('0x01', 1, { + await collectiblesController.addCollectible('0x01', '1', { name: 'name', image: 'image', description: 'description', }); - await collectiblesController.addCollectible('0x01', 2, { + await collectiblesController.addCollectible('0x01', '2', { name: 'name', image: 'image', description: 'description', @@ -469,11 +469,11 @@ describe('CollectiblesController', () => { expect(collectiblesController.state.collectibles).toHaveLength(2); expect(collectiblesController.state.ignoredCollectibles).toHaveLength(0); - collectiblesController.removeAndIgnoreCollectible('0x01', 1); + collectiblesController.removeAndIgnoreCollectible('0x01', '1'); expect(collectiblesController.state.collectibles).toHaveLength(1); expect(collectiblesController.state.ignoredCollectibles).toHaveLength(1); - await collectiblesController.addCollectible('0x01', 1, { + await collectiblesController.addCollectible('0x01', '1', { name: 'name', image: 'image', description: 'description', @@ -481,13 +481,13 @@ describe('CollectiblesController', () => { expect(collectiblesController.state.collectibles).toHaveLength(2); expect(collectiblesController.state.ignoredCollectibles).toHaveLength(1); - collectiblesController.removeAndIgnoreCollectible('0x01', 1); + collectiblesController.removeAndIgnoreCollectible('0x01', '1'); expect(collectiblesController.state.collectibles).toHaveLength(1); expect(collectiblesController.state.ignoredCollectibles).toHaveLength(1); }); it('should be able to clear the ignoredCollectibles list', async () => { - await collectiblesController.addCollectible('0x02', 1, { + await collectiblesController.addCollectible('0x02', '1', { name: 'name', image: 'image', description: 'description', @@ -496,7 +496,7 @@ describe('CollectiblesController', () => { expect(collectiblesController.state.collectibles).toHaveLength(1); expect(collectiblesController.state.ignoredCollectibles).toHaveLength(0); - collectiblesController.removeAndIgnoreCollectible('0x02', 1); + collectiblesController.removeAndIgnoreCollectible('0x02', '1'); expect(collectiblesController.state.collectibles).toHaveLength(0); expect(collectiblesController.state.ignoredCollectibles).toHaveLength(1); diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index 21c068c53d..a1cad81d4a 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -34,7 +34,7 @@ import { compareCollectiblesMetadata } from './assetsUtil'; * @property creator - The collectible owner information object */ export interface Collectible extends CollectibleMetadata { - tokenId: number; + tokenId: string; address: string; } @@ -143,7 +143,7 @@ export class CollectiblesController extends BaseController< > { private mutex = new Mutex(); - private getCollectibleApi(contractAddress: string, tokenId: number) { + private getCollectibleApi(contractAddress: string, tokenId: string) { return `https://api.opensea.io/api/v1/asset/${contractAddress}/${tokenId}`; } @@ -160,7 +160,7 @@ export class CollectiblesController extends BaseController< */ private async getCollectibleInformationFromApi( contractAddress: string, - tokenId: number, + tokenId: string, ): Promise { const tokenURI = this.getCollectibleApi(contractAddress, tokenId); let collectibleInformation: ApiCollectible; @@ -222,7 +222,7 @@ export class CollectiblesController extends BaseController< */ private async getCollectibleInformationFromTokenURI( contractAddress: string, - tokenId: number, + tokenId: string, ): Promise { const tokenURI = await this.getCollectibleTokenURI( contractAddress, @@ -244,7 +244,7 @@ export class CollectiblesController extends BaseController< */ private async getCollectibleInformation( contractAddress: string, - tokenId: number, + tokenId: string, ): Promise { let information; // First try with OpenSea @@ -378,7 +378,7 @@ export class CollectiblesController extends BaseController< */ private async addIndividualCollectible( address: string, - tokenId: number, + tokenId: string, collectibleMetadata?: CollectibleMetadata, ): Promise { const releaseLock = await this.mutex.acquire(); @@ -530,7 +530,7 @@ export class CollectiblesController extends BaseController< */ private removeAndIgnoreIndividualCollectible( address: string, - tokenId: number, + tokenId: string, ) { address = toChecksumHexAddress(address); const { allCollectibles, collectibles, ignoredCollectibles } = this.state; @@ -571,7 +571,7 @@ export class CollectiblesController extends BaseController< * @param address - Hex address of the collectible contract. * @param tokenId - Token identifier of the collectible. */ - private removeIndividualCollectible(address: string, tokenId: number) { + private removeIndividualCollectible(address: string, tokenId: string) { address = toChecksumHexAddress(address); const { allCollectibles, collectibles } = this.state; const { chainId, selectedAddress } = this.config; @@ -760,10 +760,7 @@ export class CollectiblesController extends BaseController< ): Promise { // Checks the ownership of a ERC-721. try { - const owner = await this.getOwnerOf( - collectibleAddress, - Number(collectibleId), - ); + const owner = await this.getOwnerOf(collectibleAddress, collectibleId); return ownerAddress.toLowerCase() === owner.toLowerCase(); // eslint-disable-next-line no-empty } catch { @@ -799,7 +796,7 @@ export class CollectiblesController extends BaseController< */ async addCollectible( address: string, - tokenId: number, + tokenId: string, collectibleMetadata?: CollectibleMetadata, detection?: boolean, ) { @@ -833,7 +830,7 @@ export class CollectiblesController extends BaseController< * @param address - Hex address of the collectible contract. * @param tokenId - Token identifier of the collectible. */ - removeCollectible(address: string, tokenId: number) { + removeCollectible(address: string, tokenId: string) { address = toChecksumHexAddress(address); this.removeIndividualCollectible(address, tokenId); const { collectibles } = this.state; @@ -852,7 +849,7 @@ export class CollectiblesController extends BaseController< * @param address - Hex address of the collectible contract. * @param tokenId - Token identifier of the collectible. */ - removeAndIgnoreCollectible(address: string, tokenId: number) { + removeAndIgnoreCollectible(address: string, tokenId: string) { address = toChecksumHexAddress(address); this.removeAndIgnoreIndividualCollectible(address, tokenId); const { collectibles } = this.state; From 5363beddfc708d2dc5fe1012113b7e33237a3371 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Tue, 19 Oct 2021 15:57:00 -0300 Subject: [PATCH 22/43] Update method name --- src/assets/CollectiblesController.test.ts | 10 +++++----- src/assets/CollectiblesController.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/assets/CollectiblesController.test.ts b/src/assets/CollectiblesController.test.ts index 58c4093945..ac0a8e7c27 100644 --- a/src/assets/CollectiblesController.test.ts +++ b/src/assets/CollectiblesController.test.ts @@ -511,7 +511,7 @@ describe('CollectiblesController', () => { it('should verify the ownership of an ERC-721 collectible with the correct owner address', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const isOwner = await collectiblesController.checkCollectibleOwnership( + const isOwner = await collectiblesController.isCollectibleOwner( OWNER_ADDRESS, ERC721_COLLECTIBLE_ADDRESS, String(ERC721_COLLECTIBLE_ID), @@ -521,7 +521,7 @@ describe('CollectiblesController', () => { it('should not verify the ownership of an ERC-721 collectible with the wrong owner address', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const isOwner = await collectiblesController.checkCollectibleOwnership( + const isOwner = await collectiblesController.isCollectibleOwner( '0x0000000000000000000000000000000000000000', ERC721_COLLECTIBLE_ADDRESS, String(ERC721_COLLECTIBLE_ID), @@ -531,7 +531,7 @@ describe('CollectiblesController', () => { it('should verify the ownership of an ERC-1155 collectible with the correct owner address', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const isOwner = await collectiblesController.checkCollectibleOwnership( + const isOwner = await collectiblesController.isCollectibleOwner( OWNER_ADDRESS, ERC1155_COLLECTIBLE_ADDRESS, ERC1155_COLLECTIBLE_ID, @@ -541,7 +541,7 @@ describe('CollectiblesController', () => { it('should not verify the ownership of an ERC-1155 collectible with the wrong owner address', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const isOwner = await collectiblesController.checkCollectibleOwnership( + const isOwner = await collectiblesController.isCollectibleOwner( '0x0000000000000000000000000000000000000000', ERC1155_COLLECTIBLE_ADDRESS, ERC1155_COLLECTIBLE_ID, @@ -554,7 +554,7 @@ describe('CollectiblesController', () => { const error = 'Unable to verify ownership. Probably because the standard is not supported or the chain is incorrect'; const result = async () => { - await collectiblesController.checkCollectibleOwnership( + await collectiblesController.isCollectibleOwner( '0x0000000000000000000000000000000000000000', CRYPTOPUNK_ADDRESS, '0', diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index a1cad81d4a..4660558f82 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -753,7 +753,7 @@ export class CollectiblesController extends BaseController< * @param collectibleId - Collectible token ID. * @returns Promise resolving the collectible ownership. */ - async checkCollectibleOwnership( + async isCollectibleOwner( ownerAddress: string, collectibleAddress: string, collectibleId: string, From 68af6dab31288a8de58de8083e9192f6a93215c4 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Tue, 19 Oct 2021 15:57:35 -0300 Subject: [PATCH 23/43] Update comments --- .../ERC1155/ERC1155Standard.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts index 86bf4395e3..2d74a5d6f1 100644 --- a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts +++ b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts @@ -3,10 +3,10 @@ const ERC1155_TOKEN_RECEIVER_INTERFACE_ID = '0x4e2312e0'; export class ERC1155Standard { /** - * Query if contract implements ERC721Metadata interface. + * Query if contract implements ERC1155 URI Metadata interface. * - * @param contract - ERC721 asset contract. - * @returns Promise resolving to whether the contract implements ERC721Metadata interface. + * @param contract - ERC1155 asset contract. + * @returns Promise resolving to whether the contract implements ERC1155 URI Metadata interface. */ contractSupportsURIMetadataInterface = async ( contract: any, @@ -18,10 +18,10 @@ export class ERC1155Standard { }; /** - * Query if contract implements ERC721Enumerable interface. + * Query if contract implements ERC1155 Token Receiver interface. * - * @param contract - ERC721 asset contract. - * @returns Promise resolving to whether the contract implements ERC721Enumerable interface. + * @param contract - ERC1155 asset contract. + * @returns Promise resolving to whether the contract implements ERC1155 Token Receiver interface. */ contractSupportsTokenReceiverInterface = async ( contract: any, @@ -56,7 +56,7 @@ export class ERC1155Standard { }; /** - * Query for balance of a given ERC 1155 token. + * Query for balance of a given ERC1155 token. * * @param contract - ERC1155 asset contract. * @param address - Wallet public address. From 3efc2c39a1aff04c9e9c63fa83ff4eeade7c87ba Mon Sep 17 00:00:00 2001 From: gantunesr Date: Tue, 19 Oct 2021 16:11:25 -0300 Subject: [PATCH 24/43] Update tests --- src/assets/AssetsContractController.test.ts | 2 +- src/assets/assetsUtil.test.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/assets/AssetsContractController.test.ts b/src/assets/AssetsContractController.test.ts index 3538d9f719..c4785c9d32 100644 --- a/src/assets/AssetsContractController.test.ts +++ b/src/assets/AssetsContractController.test.ts @@ -92,7 +92,7 @@ describe('AssetsContractController', () => { it('should get ERC-721 collectible ownership', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const tokenId = await assetsContract.getOwnerOf(GODSADDRESS, 148332); + const tokenId = await assetsContract.getOwnerOf(GODSADDRESS, '148332'); expect(tokenId).not.toStrictEqual(''); }); diff --git a/src/assets/assetsUtil.test.ts b/src/assets/assetsUtil.test.ts index 717fe10765..a3b29d16a8 100644 --- a/src/assets/assetsUtil.test.ts +++ b/src/assets/assetsUtil.test.ts @@ -16,7 +16,7 @@ describe('assetsUtil', () => { }; const collectible: Collectible = { address: 'address', - tokenId: 123, + tokenId: '123', name: 'name', image: 'image', backgroundColor: 'backgroundColor', @@ -41,7 +41,7 @@ describe('assetsUtil', () => { }; const collectible: Collectible = { address: 'address', - tokenId: 123, + tokenId: '123', name: 'name', image: 'image', backgroundColor: 'backgroundColor', @@ -67,7 +67,7 @@ describe('assetsUtil', () => { }; const collectible: Collectible = { address: 'address', - tokenId: 123, + tokenId: '123', name: 'name', image: 'image', backgroundColor: 'backgroundColor', From cfafaf0152e3816e6f43a2d5dcd6825f8f4b3559 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Tue, 19 Oct 2021 16:15:39 -0300 Subject: [PATCH 25/43] Update tests --- src/assets/AssetsContractController.test.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/assets/AssetsContractController.test.ts b/src/assets/AssetsContractController.test.ts index c4785c9d32..4e0f5a97f6 100644 --- a/src/assets/AssetsContractController.test.ts +++ b/src/assets/AssetsContractController.test.ts @@ -59,7 +59,10 @@ describe('AssetsContractController', () => { it('should get ERC-721 collectible tokenURI correctly', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const tokenId = await assetsContract.getCollectibleTokenURI(GODSADDRESS, 0); + const tokenId = await assetsContract.getCollectibleTokenURI( + GODSADDRESS, + '0', + ); expect(tokenId).toStrictEqual('https://api.godsunchained.com/card/0'); }); @@ -67,7 +70,7 @@ describe('AssetsContractController', () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const tokenId = await assetsContract.getCollectibleTokenURI( '0x0000000000000000000000000000000000000000', - 0, + '0', ); expect(tokenId).toStrictEqual(''); }); From 2a265fd5157f62eb0b357bfc80d6d4d655ca8f1e Mon Sep 17 00:00:00 2001 From: gantunesr Date: Tue, 19 Oct 2021 18:07:26 -0300 Subject: [PATCH 26/43] feat(AddCustomCollectible): Update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4788eb521b..c4ce88734d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/controllers", - "version": "17.0.0", + "version": "17.0.0-erc-1155-v4", "description": "Collection of platform-agnostic modules for creating secure data models for cryptocurrency wallets", "keywords": [ "MetaMask", From 7fc748c1e09c52cff6a8d3c994f47e5fb353addf Mon Sep 17 00:00:00 2001 From: gantunesr Date: Sat, 23 Oct 2021 19:42:33 -0300 Subject: [PATCH 27/43] feat(ERC1155): Update standard --- src/assets/AssetsContractController.ts | 36 ++++++++++++++++--- src/assets/AssetsDetectionController.ts | 1 + .../ERC1155/ERC1155Standard.ts | 5 +-- src/assets/CollectiblesController.test.ts | 26 ++++++++++++++ src/assets/CollectiblesController.ts | 34 ++++++++++++------ 5 files changed, 84 insertions(+), 18 deletions(-) diff --git a/src/assets/AssetsContractController.ts b/src/assets/AssetsContractController.ts index b6704acec2..8d691069c9 100644 --- a/src/assets/AssetsContractController.ts +++ b/src/assets/AssetsContractController.ts @@ -204,23 +204,23 @@ export class AssetsContractController extends BaseController< tokenId: string, ): Promise { const contract = this.web3.eth.contract(abiERC1155).at(address); - return this.erc1155Standard.getCollectibleURI(contract, tokenId); + return this.erc1155Standard.uri(contract, tokenId); } /** * Query for balance of a given ERC 1155 token. * * @param userAddress - Wallet public address. - * @param collectibleaddress - ERC1155 asset contract address. + * @param collectibleAddress - ERC1155 asset contract address. * @param collectibleId - ERC1155 asset identifier. * @returns Promise resolving to the 'balanceOf'. */ async balanceOfERC1155Collectible( userAddress: string, - collectibleaddress: string, + collectibleAddress: string, collectibleId: string, ): Promise { - const contract = this.web3.eth.contract(abiERC1155).at(collectibleaddress); + const contract = this.web3.eth.contract(abiERC1155).at(collectibleAddress); return await this.erc1155Standard.getBalanceOf( contract, userAddress, @@ -228,6 +228,34 @@ export class AssetsContractController extends BaseController< ); } + /** + * Transfer single ERC1155 token. + * + * @param collectibleAddress - ERC1155 token address. + * @param senderAddress - ERC1155 token sender. + * @param recipientAddress - ERC1155 token recipient. + * @param collectibleId - ERC1155 token id. + * @param qty - Quantity of tokens to be sent. + * @returns Promise resolving to the 'transferSingle' ERC1155 token. + */ + async transferSingleERC1155Collectible( + collectibleAddress: string, + senderAddress: string, + recipientAddress: string, + collectibleId: string, + qty: string, + ): Promise { + const contract = this.web3.eth.contract(abiERC1155).at(collectibleAddress); + return await this.erc1155Standard.transferSingle( + contract, + collectibleAddress, + senderAddress, + recipientAddress, + collectibleId, + qty, + ); + } + /** * Get the token balance for a list of token addresses in a single call. Only non-zero balances * are returned. diff --git a/src/assets/AssetsDetectionController.ts b/src/assets/AssetsDetectionController.ts index 769a0cfd64..91200bbe71 100644 --- a/src/assets/AssetsDetectionController.ts +++ b/src/assets/AssetsDetectionController.ts @@ -402,6 +402,7 @@ export class AssetsDetectionController extends BaseController< await safelyExecute(async () => { const apiCollectibles = await this.getOwnerCollectibles(); + console.log(apiCollectibles); const addCollectiblesPromises = apiCollectibles.map( async (collectible: ApiCollectible) => { const { diff --git a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts index 2d74a5d6f1..41608a44d6 100644 --- a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts +++ b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts @@ -39,10 +39,7 @@ export class ERC1155Standard { * @param tokenId - ERC1155 asset identifier. * @returns Promise resolving to the 'tokenURI'. */ - getCollectibleURI = async ( - contract: any, - tokenId: string, - ): Promise => { + uri = async (contract: any, tokenId: string): Promise => { return new Promise((resolve, reject) => { contract.uri(tokenId, (error: Error, result: string) => { /* istanbul ignore if */ diff --git a/src/assets/CollectiblesController.test.ts b/src/assets/CollectiblesController.test.ts index ac0a8e7c27..5d9178f560 100644 --- a/src/assets/CollectiblesController.test.ts +++ b/src/assets/CollectiblesController.test.ts @@ -563,3 +563,29 @@ describe('CollectiblesController', () => { await expect(result).rejects.toThrow(error); }); }); + +// { +// description: 'Description', +// image_url: 'url', +// image_preview_url: 'preview_url', +// image_thumbnail_url: 'thumbnail_url', +// image_original_url: 'original_url', +// name: 'Collectible Name', +// symbol: 'FOO', +// total_supply: 0, +// background_color: null, +// num_sales: 3, +// external_link: 'external_link', +// asset_contract: { +// name: 'Collection Name', +// image_url: 'image_url', +// address: '0x01', +// schema_name: 'ERC1155', +// symbol: 'ABC', +// description: 'Collection description', +// asset_contract_type: 'non-fungible', +// created_date: 'date', +// total_supply: null, +// external_link: 'external_link', +// }, +// } \ No newline at end of file diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index 4660558f82..c745386448 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -144,11 +144,23 @@ export class CollectiblesController extends BaseController< private mutex = new Mutex(); private getCollectibleApi(contractAddress: string, tokenId: string) { - return `https://api.opensea.io/api/v1/asset/${contractAddress}/${tokenId}`; + const { chainId } = this.config; + switch (chainId) { + case '4': + return `https://testnets-api.opensea.io/api/v1/asset/${contractAddress}/${tokenId}`; + default: + return `https://api.opensea.io/api/v1/asset/${contractAddress}/${tokenId}`; + } } private getCollectibleContractInformationApi(contractAddress: string) { - return `https://api.opensea.io/api/v1/asset_contract/${contractAddress}`; + const { chainId } = this.config; + switch (chainId) { + case '4': + return `https://testnets-api.opensea.io/api/v1/asset_contract/${contractAddress}`; + default: + return `https://api.opensea.io/api/v1/asset_contract/${contractAddress}`; + } } /** @@ -235,6 +247,7 @@ export class CollectiblesController extends BaseController< return { image: object[image], name: object.name }; } + // LOOK HERE /** * Request individual collectible information (name, image url and description). * @@ -247,6 +260,7 @@ export class CollectiblesController extends BaseController< tokenId: string, ): Promise { let information; + // First try with OpenSea information = await safelyExecute(async () => { return await this.getCollectibleInformationFromApi( @@ -322,6 +336,7 @@ export class CollectiblesController extends BaseController< }; } + // LOOK HERE /** * Request collectible contract information from OpenSea API. * @@ -379,7 +394,7 @@ export class CollectiblesController extends BaseController< private async addIndividualCollectible( address: string, tokenId: string, - collectibleMetadata?: CollectibleMetadata, + collectibleMetadata: CollectibleMetadata, ): Promise { const releaseLock = await this.mutex.acquire(); try { @@ -391,10 +406,6 @@ export class CollectiblesController extends BaseController< collectible.address.toLowerCase() === address.toLowerCase() && collectible.tokenId === tokenId, ); - /* istanbul ignore next */ - collectibleMetadata = - collectibleMetadata || - (await this.getCollectibleInformation(address, tokenId)); if (existingEntry) { const differentMetadata = compareCollectiblesMetadata( @@ -479,7 +490,7 @@ export class CollectiblesController extends BaseController< image_url, } = contractInformation; // If being auto-detected opensea information is expected - // Oherwise at least name and symbol from contract is needed + // Otherwise at least name and symbol from contract is needed if ( (detection && !image_url) || Object.keys(contractInformation).length === 0 @@ -758,7 +769,7 @@ export class CollectiblesController extends BaseController< collectibleAddress: string, collectibleId: string, ): Promise { - // Checks the ownership of a ERC-721. + // Checks the ownership for ERC-721. try { const owner = await this.getOwnerOf(collectibleAddress, collectibleId); return ownerAddress.toLowerCase() === owner.toLowerCase(); @@ -767,7 +778,7 @@ export class CollectiblesController extends BaseController< // Ignore ERC-721 contract error } - // Checks the ownership of a ERC-1155. + // Checks the ownership for ERC-1155. try { const balance = await this.balanceOfERC1155Collectible( ownerAddress, @@ -800,6 +811,7 @@ export class CollectiblesController extends BaseController< collectibleMetadata?: CollectibleMetadata, detection?: boolean, ) { + console.log('ADD:', address, tokenId, detection); address = toChecksumHexAddress(address); const newCollectibleContracts = await this.addCollectibleContract( address, @@ -810,6 +822,8 @@ export class CollectiblesController extends BaseController< collectibleMetadata || (await this.getCollectibleInformation(address, tokenId)); + console.log(address, '->', collectibleMetadata); + // If collectible contract was not added, do not add individual collectible const collectibleContract = newCollectibleContracts.find( (contract) => contract.address.toLowerCase() === address.toLowerCase(), From a899204e14c88a727d05ef50e3290a621a2df582 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Sat, 23 Oct 2021 19:46:45 -0300 Subject: [PATCH 28/43] feat(ERC1155): Update standard --- .../ERC1155/ERC1155Standard.ts | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts index 41608a44d6..bbe1384079 100644 --- a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts +++ b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.ts @@ -77,6 +77,46 @@ export class ERC1155Standard { }); }; + /** + * Transfer single ERC1155 token. + * When minting/creating tokens, the from arg MUST be set to 0x0 (i.e. zero address). + * When burning/destroying tokens, the to arg MUST be set to 0x0 (i.e. zero address). + * + * @param contract - ERC1155 asset contract. + * @param operator - ERC1155 token address. + * @param from - ERC1155 token holder. + * @param to - ERC1155 token recipient. + * @param id - ERC1155 token id. + * @param value - Number of tokens to be sent. + * @returns Promise resolving to the 'transferSingle'. + */ + transferSingle = async ( + contract: any, + operator: string, + from: string, + to: string, + id: string, + value: string, + ): Promise => { + return new Promise((resolve, reject) => { + contract.transferSingle( + operator, + from, + to, + id, + value, + (error: Error, result: void) => { + /* istanbul ignore if */ + if (error) { + reject(error); + return; + } + resolve(result); + }, + ); + }); + }; + /** * Query if a contract implements an interface. * From a79126fac79245ac48c88b053d3c17855f192518 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Mon, 25 Oct 2021 00:59:54 -0300 Subject: [PATCH 29/43] feat(ERC1155): Get collection from OpenSea --- src/assets/AssetsDetectionController.test.ts | 55 ++++++++++++++++++++ src/assets/AssetsDetectionController.ts | 23 +++++++- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/assets/AssetsDetectionController.test.ts b/src/assets/AssetsDetectionController.test.ts index b8c3cd73b3..2295c9228e 100644 --- a/src/assets/AssetsDetectionController.test.ts +++ b/src/assets/AssetsDetectionController.test.ts @@ -181,6 +181,11 @@ describe('AssetsDetectionController', () => { { asset_contract: { address: '0x1d963688fe2209a98db35c67a041524822cf04ff', + schema_name: 'ERC721', + }, + collection: { + name: 'Collection 2577', + image_url: 'url', }, description: 'Description 2577', image_original_url: 'image/2577.png', @@ -230,6 +235,11 @@ describe('AssetsDetectionController', () => { { asset_contract: { address: '0xCE7ec4B2DfB30eB6c0BB5656D33aAd6BFb4001Fc', + schema_name: 'ERC721', + }, + collection: { + name: 'Collection 2577', + image_url: 'url', }, description: 'Description 2577', image_url: 'image/2577.png', @@ -239,6 +249,11 @@ describe('AssetsDetectionController', () => { { asset_contract: { address: '0x0B0fa4fF58D28A88d63235bd0756EDca69e49e6d', + schema_name: 'ERC721', + }, + collection: { + name: 'Collection 2577', + image_url: 'url', }, description: 'Description 2578', image_url: 'image/2578.png', @@ -248,6 +263,11 @@ describe('AssetsDetectionController', () => { { asset_contract: { address: '0xebE4e5E773AFD2bAc25De0cFafa084CFb3cBf1eD', + schema_name: 'ERC721', + }, + collection: { + name: 'Collection 2574', + image_url: 'url', }, description: 'Description 2574', image_url: 'image/2574.png', @@ -267,6 +287,11 @@ describe('AssetsDetectionController', () => { { asset_contract: { address: '0xebE4e5E773AFD2bAc25De0cFafa084CFb3cBf1eD', + schema_name: 'ERC721', + }, + collection: { + name: 'Collection 2574', + image_url: 'url', }, description: 'Description 2574', image_url: 'image/2574.png', @@ -403,6 +428,9 @@ describe('AssetsDetectionController', () => { image: 'image/2574.png', name: 'ID 2574', tokenId: '2574', + standard: 'ERC721', + collectionImage: 'url', + collectionName: 'Collection 2574', }, ]); }); @@ -433,6 +461,9 @@ describe('AssetsDetectionController', () => { image: 'image/2574.png', name: 'ID 2574', tokenId: '2574', + standard: 'ERC721', + collectionImage: 'url', + collectionName: 'Collection 2574', }, ]); }); @@ -478,6 +509,9 @@ describe('AssetsDetectionController', () => { image: 'image/2574.png', name: 'ID 2574', tokenId: '2574', + standard: 'ERC721', + collectionImage: 'url', + collectionName: 'Collection 2574', }; const collectibleGG2574 = { address: '0xCE7ec4B2DfB30eB6c0BB5656D33aAd6BFb4001Fc', @@ -485,6 +519,9 @@ describe('AssetsDetectionController', () => { image: 'image/2574.png', name: 'ID 2574', tokenId: '2574', + standard: 'ERC721', + collectionImage: 'url', + collectionName: 'Collection 2574', }; const collectibleII2577 = { address: '0x0B0fa4fF58D28A88d63235bd0756EDca69e49e6d', @@ -492,6 +529,9 @@ describe('AssetsDetectionController', () => { image: 'image/2577.png', name: 'ID 2577', tokenId: '2577', + standard: 'ERC721', + collectionImage: 'url', + collectionName: 'Collection 2577', }; const collectibleContractHH = { address: '0xebE4e5E773AFD2bAc25De0cFafa084CFb3cBf1eD', @@ -556,6 +596,11 @@ describe('AssetsDetectionController', () => { { asset_contract: { address: '0x0B0fa4fF58D28A88d63235bd0756EDca69e49e6d', + schema_name: 'ERC721', + }, + collection: { + name: 'Collection 2577', + image_url: 'url', }, description: 'Description 2577', image_url: 'image/2577.png', @@ -565,6 +610,11 @@ describe('AssetsDetectionController', () => { { asset_contract: { address: '0xCE7ec4B2DfB30eB6c0BB5656D33aAd6BFb4001Fc', + schema_name: 'ERC721', + }, + collection: { + name: 'Collection 2574', + image_url: 'url', }, description: 'Description 2574', image_url: 'image/2574.png', @@ -574,6 +624,11 @@ describe('AssetsDetectionController', () => { { asset_contract: { address: '0xebE4e5E773AFD2bAc25De0cFafa084CFb3cBf1eD', + schema_name: 'ERC721', + }, + collection: { + name: 'Collection 2574', + image_url: 'url', }, description: 'Description 2574', image_url: 'image/2574.png', diff --git a/src/assets/AssetsDetectionController.ts b/src/assets/AssetsDetectionController.ts index 91200bbe71..1db6fd1be3 100644 --- a/src/assets/AssetsDetectionController.ts +++ b/src/assets/AssetsDetectionController.ts @@ -34,6 +34,7 @@ const DEFAULT_INTERVAL = 180000; * @property assetContract - The collectible contract information object * @property creator - The collectible owner information object * @property lastSale - When this item was last sold + * @property collection - Collectible collection data object. */ export interface ApiCollectible { token_id: string; @@ -51,6 +52,7 @@ export interface ApiCollectible { asset_contract: ApiCollectibleContract; creator: ApiCollectibleCreator; last_sale: ApiCollectibleLastSale | null; + collection: ApiCollectibleCollection; } /** @@ -109,6 +111,18 @@ export interface ApiCollectibleCreator { address: string; } +/** + * @type ApiCollectibleCollection + * + * Collectible collection object from OpenSea api. + * @property name - Collection name. + * @property image_url - URI collection image. + */ +export interface ApiCollectibleCollection { + name: string; + image_url: string; +} + /** * @type AssetsConfig * @@ -402,7 +416,6 @@ export class AssetsDetectionController extends BaseController< await safelyExecute(async () => { const apiCollectibles = await this.getOwnerCollectibles(); - console.log(apiCollectibles); const addCollectiblesPromises = apiCollectibles.map( async (collectible: ApiCollectible) => { const { @@ -419,7 +432,8 @@ export class AssetsDetectionController extends BaseController< description, external_link, creator, - asset_contract: { address }, + asset_contract: { address, schema_name }, + collection, last_sale, } = collectible; @@ -457,8 +471,13 @@ export class AssetsDetectionController extends BaseController< animation_original_url && { animationOriginal: animation_original_url, }, + schema_name && { standard: schema_name }, external_link && { externalLink: external_link }, last_sale && { lastSale: last_sale }, + collection.name && { collectionName: collection.name }, + collection.image_url && { + collectionImage: collection.image_url, + }, ); await this.addCollectible( address, From 324ef91ac0b6d6e3366acef9ccbdebcdbe8d8855 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Mon, 25 Oct 2021 01:15:00 -0300 Subject: [PATCH 30/43] feat(ERC1155): Get collection from OpenSea --- src/assets/CollectiblesController.test.ts | 42 +++++++---------------- src/assets/CollectiblesController.ts | 14 +++++--- 2 files changed, 22 insertions(+), 34 deletions(-) diff --git a/src/assets/CollectiblesController.test.ts b/src/assets/CollectiblesController.test.ts index 5d9178f560..e9b9bd152f 100644 --- a/src/assets/CollectiblesController.test.ts +++ b/src/assets/CollectiblesController.test.ts @@ -57,9 +57,6 @@ describe('CollectiblesController', () => { name: 'Name', symbol: 'FOO', total_supply: 0, - asset_contract: { - schema_name: 'ERC1155', - }, }) .get(`${OPEN_SEA_PATH}/asset_contract/0x02`) .reply(200, { @@ -77,6 +74,10 @@ describe('CollectiblesController', () => { asset_contract: { schema_name: 'ERC1155', }, + collection: { + name: 'Collection Name', + image_url: 'collection.url', + }, }) .get( `${OPEN_SEA_PATH}/asset/0x2aEa4Add166EBf38b63d09a75dE1a7b94Aa24163/1203`, @@ -88,6 +89,10 @@ describe('CollectiblesController', () => { asset_contract: { schema_name: 'ERC721', }, + collection: { + name: 'Collection Name', + image_url: 'collection.url', + }, }) .get( `${OPEN_SEA_PATH}/asset/0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab/798958393`, @@ -220,6 +225,7 @@ describe('CollectiblesController', () => { it('should add collectible and get information from OpenSea', async () => { await collectiblesController.addCollectible('0x01', '1'); + console.log(collectiblesController.state.collectibles[0]); expect(collectiblesController.state.collectibles[0]).toStrictEqual({ address: '0x01', description: 'Description', @@ -227,6 +233,8 @@ describe('CollectiblesController', () => { name: 'Name', standard: 'ERC1155', tokenId: '1', + collectionName: 'Collection Name', + collectionImage: 'collection.url', }); }); @@ -338,6 +346,8 @@ describe('CollectiblesController', () => { name: 'Kudos Name', standard: 'ERC721', tokenId: '1203', + collectionImage: 'collection.url', + collectionName: 'Collection Name', }, ]); @@ -563,29 +573,3 @@ describe('CollectiblesController', () => { await expect(result).rejects.toThrow(error); }); }); - -// { -// description: 'Description', -// image_url: 'url', -// image_preview_url: 'preview_url', -// image_thumbnail_url: 'thumbnail_url', -// image_original_url: 'original_url', -// name: 'Collectible Name', -// symbol: 'FOO', -// total_supply: 0, -// background_color: null, -// num_sales: 3, -// external_link: 'external_link', -// asset_contract: { -// name: 'Collection Name', -// image_url: 'image_url', -// address: '0x01', -// schema_name: 'ERC1155', -// symbol: 'ABC', -// description: 'Collection description', -// asset_contract_type: 'non-fungible', -// created_date: 'date', -// total_supply: null, -// external_link: 'external_link', -// }, -// } \ No newline at end of file diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index c745386448..8a119bf2ec 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -83,6 +83,8 @@ export interface CollectibleContract { * @property externalLink - External link containing additional information * @property creator - The collectible owner information object * @property standard - NFT standard name for the collectible, e.g., ERC-721 or ERC-1155 + * @property collectionName - The name of the collectible collection. + * @property collectionImage - The image URI of the collectible collection. */ export interface CollectibleMetadata { name?: string; @@ -99,6 +101,8 @@ export interface CollectibleMetadata { creator?: ApiCollectibleCreator; lastSale?: ApiCollectibleLastSale; standard?: string; + collectionName?: string; + collectionImage?: string; } /** @@ -198,7 +202,8 @@ export class CollectiblesController extends BaseController< external_link, creator, last_sale, - asset_contract, + asset_contract: { schema_name }, + collection, } = collectibleInformation; /* istanbul ignore next */ @@ -219,7 +224,9 @@ export class CollectiblesController extends BaseController< }, external_link && { externalLink: external_link }, last_sale && { lastSale: last_sale }, - asset_contract.schema_name && { standard: asset_contract.schema_name }, + schema_name && { standard: schema_name }, + collection.name && { collectionName: collection.name }, + collection.image_url && { collectionImage: collection.image_url }, ); return collectibleMetadata; @@ -811,7 +818,6 @@ export class CollectiblesController extends BaseController< collectibleMetadata?: CollectibleMetadata, detection?: boolean, ) { - console.log('ADD:', address, tokenId, detection); address = toChecksumHexAddress(address); const newCollectibleContracts = await this.addCollectibleContract( address, @@ -822,8 +828,6 @@ export class CollectiblesController extends BaseController< collectibleMetadata || (await this.getCollectibleInformation(address, tokenId)); - console.log(address, '->', collectibleMetadata); - // If collectible contract was not added, do not add individual collectible const collectibleContract = newCollectibleContracts.find( (contract) => contract.address.toLowerCase() === address.toLowerCase(), From 4d9d8bcf4fd1d10d091f5a265b8c3b5e11e42b2c Mon Sep 17 00:00:00 2001 From: gantunesr Date: Mon, 25 Oct 2021 10:16:55 -0300 Subject: [PATCH 31/43] Fix version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c4ce88734d..4788eb521b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@metamask/controllers", - "version": "17.0.0-erc-1155-v4", + "version": "17.0.0", "description": "Collection of platform-agnostic modules for creating secure data models for cryptocurrency wallets", "keywords": [ "MetaMask", From 204ba1dfcd84e99cc6ae32adf98ab291e82fb04d Mon Sep 17 00:00:00 2001 From: gantunesr Date: Mon, 25 Oct 2021 10:39:46 -0300 Subject: [PATCH 32/43] Remove comments --- src/assets/CollectiblesController.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index 8a119bf2ec..b695ffc2e8 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -254,7 +254,6 @@ export class CollectiblesController extends BaseController< return { image: object[image], name: object.name }; } - // LOOK HERE /** * Request individual collectible information (name, image url and description). * @@ -343,7 +342,6 @@ export class CollectiblesController extends BaseController< }; } - // LOOK HERE /** * Request collectible contract information from OpenSea API. * From 7c9b8b1e166ac136d2f215d5b26def54fbd42110 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Tue, 26 Oct 2021 22:50:15 -0300 Subject: [PATCH 33/43] Add method to get token standard --- src/ComposableController.test.ts | 6 +++ src/assets/AssetsDetectionController.test.ts | 3 ++ src/assets/CollectiblesController.test.ts | 5 ++- src/assets/CollectiblesController.ts | 47 +++++++++++++++++++- src/constants.ts | 3 ++ 5 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/ComposableController.test.ts b/src/ComposableController.test.ts index c4e2518540..ee30ad7d62 100644 --- a/src/ComposableController.test.ts +++ b/src/ComposableController.test.ts @@ -112,6 +112,9 @@ describe('ComposableController', () => { balanceOfERC1155Collectible: assetContractController.balanceOfERC1155Collectible.bind( assetContractController, ), + uriERC1155Collectible: assetContractController.uriERC1155Collectible.bind( + assetContractController, + ), }); const tokensController = new TokensController({ onPreferencesStateChange: (listener) => @@ -190,6 +193,9 @@ describe('ComposableController', () => { balanceOfERC1155Collectible: assetContractController.balanceOfERC1155Collectible.bind( assetContractController, ), + uriERC1155Collectible: assetContractController.uriERC1155Collectible.bind( + assetContractController, + ), }); const tokensController = new TokensController({ onPreferencesStateChange: (listener) => diff --git a/src/assets/AssetsDetectionController.test.ts b/src/assets/AssetsDetectionController.test.ts index 2295c9228e..7cf2b3cd6b 100644 --- a/src/assets/AssetsDetectionController.test.ts +++ b/src/assets/AssetsDetectionController.test.ts @@ -141,6 +141,9 @@ describe('AssetsDetectionController', () => { balanceOfERC1155Collectible: assetsContract.balanceOfERC1155Collectible.bind( assetsContract, ), + uriERC1155Collectible: assetsContract.uriERC1155Collectible.bind( + assetsContract, + ), }); nock(TOKEN_END_POINT_API) diff --git a/src/assets/CollectiblesController.test.ts b/src/assets/CollectiblesController.test.ts index e9b9bd152f..0542e711cd 100644 --- a/src/assets/CollectiblesController.test.ts +++ b/src/assets/CollectiblesController.test.ts @@ -47,6 +47,9 @@ describe('CollectiblesController', () => { balanceOfERC1155Collectible: assetsContract.balanceOfERC1155Collectible.bind( assetsContract, ), + uriERC1155Collectible: assetsContract.uriERC1155Collectible.bind( + assetsContract, + ), }); nock(OPEN_SEA_HOST) @@ -225,7 +228,6 @@ describe('CollectiblesController', () => { it('should add collectible and get information from OpenSea', async () => { await collectiblesController.addCollectible('0x01', '1'); - console.log(collectiblesController.state.collectibles[0]); expect(collectiblesController.state.collectibles[0]).toStrictEqual({ address: '0x01', description: 'Description', @@ -256,6 +258,7 @@ describe('CollectiblesController', () => { image: 'Kudos Image', name: 'Kudos Name', tokenId: '1203', + standard: 'ERC721', }); expect(collectiblesController.state.collectibleContracts[0]).toStrictEqual({ diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index b695ffc2e8..3ee885b7dc 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -4,7 +4,7 @@ import { BaseController, BaseConfig, BaseState } from '../BaseController'; import type { PreferencesState } from '../user/PreferencesController'; import type { NetworkState, NetworkType } from '../network/NetworkController'; import { safelyExecute, handleFetch, toChecksumHexAddress } from '../util'; -import { MAINNET } from '../constants'; +import { MAINNET, ERC721, ERC1155 } from '../constants'; import type { ApiCollectible, ApiCollectibleCreator, @@ -247,10 +247,19 @@ export class CollectiblesController extends BaseController< contractAddress, tokenId, ); + const standard = await this.getCollectibleStandard( + contractAddress, + tokenId, + ); const object = await handleFetch(tokenURI); const image = Object.prototype.hasOwnProperty.call(object, 'image') ? 'image' : /* istanbul ignore next */ 'image_url'; + + if (standard) { + return { image: object[image], name: object.name, standard }; + } + return { image: object[image], name: object.name }; } @@ -644,6 +653,36 @@ export class CollectiblesController extends BaseController< return newCollectibleContracts; } + /** + * Method to verify the token standard by querying the metadata uri form the contract. + * + * @param address - Collectible asset contract address. + * @param tokenId - Collectible asset identifier. + * @returns Promise resolving the token standard. + */ + private async getCollectibleStandard( + address: string, + tokenId: string, + ): Promise { + try { + await this.getCollectibleTokenURI(address, tokenId); + return ERC721; + } catch { + console.log('failed for erc721'); + // Ignore error + } + + try { + await this.uriERC1155Collectible(address, tokenId); + return ERC1155; + } catch { + console.log('failed for erc1155'); + // Ignore error + } + + return ''; + } + /** * EventEmitter instance used to listen to specific EIP747 events */ @@ -669,6 +708,8 @@ export class CollectiblesController extends BaseController< private balanceOfERC1155Collectible: AssetsContractController['balanceOfERC1155Collectible']; + private uriERC1155Collectible: AssetsContractController['uriERC1155Collectible']; + /** * Creates a CollectiblesController instance. * @@ -680,6 +721,7 @@ export class CollectiblesController extends BaseController< * @param options.getCollectibleTokenURI - Gets the URI of the NFT at the given address, with the given ID. * @param options.getOwnerOf - Get the owner of a ERC-721 collectible. * @param options.balanceOfERC1155Collectible - Gets balance of a ERC-1155 collectible. + * @param options.uriERC1155Collectible - Gets uri for ERC-1155 metadata. * @param config - Initial options used to configure this controller. * @param state - Initial state to set on this controller. */ @@ -692,6 +734,7 @@ export class CollectiblesController extends BaseController< getCollectibleTokenURI, getOwnerOf, balanceOfERC1155Collectible, + uriERC1155Collectible, }: { onPreferencesStateChange: ( listener: (preferencesState: PreferencesState) => void, @@ -704,6 +747,7 @@ export class CollectiblesController extends BaseController< getCollectibleTokenURI: AssetsContractController['getCollectibleTokenURI']; getOwnerOf: AssetsContractController['getOwnerOf']; balanceOfERC1155Collectible: AssetsContractController['balanceOfERC1155Collectible']; + uriERC1155Collectible: AssetsContractController['uriERC1155Collectible']; }, config?: Partial, state?: Partial, @@ -728,6 +772,7 @@ export class CollectiblesController extends BaseController< this.getCollectibleTokenURI = getCollectibleTokenURI; this.getOwnerOf = getOwnerOf; this.balanceOfERC1155Collectible = balanceOfERC1155Collectible; + this.uriERC1155Collectible = uriERC1155Collectible; onPreferencesStateChange(({ selectedAddress }) => { const { allCollectibleContracts, allCollectibles } = this.state; const { chainId } = this.config; diff --git a/src/constants.ts b/src/constants.ts index 9f925f23b7..174bb0531c 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,3 +1,6 @@ export const MAINNET = 'mainnet'; export const RPC = 'rpc'; export const FALL_BACK_VS_CURRENCY = 'ETH'; + +export const ERC721 = 'ERC721'; +export const ERC1155 = 'ERC1155'; From 57e3623d175f053bb4b4d3af90dfa797b265746f Mon Sep 17 00:00:00 2001 From: gantunesr Date: Wed, 27 Oct 2021 12:47:46 -0300 Subject: [PATCH 34/43] Add rinkeby network id as constant --- src/assets/CollectiblesController.ts | 6 +++--- src/constants.ts | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index 3ee885b7dc..5890536470 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -4,7 +4,7 @@ import { BaseController, BaseConfig, BaseState } from '../BaseController'; import type { PreferencesState } from '../user/PreferencesController'; import type { NetworkState, NetworkType } from '../network/NetworkController'; import { safelyExecute, handleFetch, toChecksumHexAddress } from '../util'; -import { MAINNET, ERC721, ERC1155 } from '../constants'; +import { MAINNET, RINKEBY_ID, ERC721, ERC1155 } from '../constants'; import type { ApiCollectible, ApiCollectibleCreator, @@ -150,7 +150,7 @@ export class CollectiblesController extends BaseController< private getCollectibleApi(contractAddress: string, tokenId: string) { const { chainId } = this.config; switch (chainId) { - case '4': + case RINKEBY_ID: return `https://testnets-api.opensea.io/api/v1/asset/${contractAddress}/${tokenId}`; default: return `https://api.opensea.io/api/v1/asset/${contractAddress}/${tokenId}`; @@ -160,7 +160,7 @@ export class CollectiblesController extends BaseController< private getCollectibleContractInformationApi(contractAddress: string) { const { chainId } = this.config; switch (chainId) { - case '4': + case RINKEBY_ID: return `https://testnets-api.opensea.io/api/v1/asset_contract/${contractAddress}`; default: return `https://api.opensea.io/api/v1/asset_contract/${contractAddress}`; diff --git a/src/constants.ts b/src/constants.ts index 174bb0531c..bd7b3b1b13 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -2,5 +2,9 @@ export const MAINNET = 'mainnet'; export const RPC = 'rpc'; export const FALL_BACK_VS_CURRENCY = 'ETH'; +// NETWORKS ID +export const RINKEBY_ID = '4'; + +// TOKEN STANDARDS export const ERC721 = 'ERC721'; export const ERC1155 = 'ERC1155'; From 5bdb7196c1432fdc99d0dde228dfa69b1210f5c2 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Thu, 28 Oct 2021 00:11:14 -0300 Subject: [PATCH 35/43] Clean tests --- src/assets/AssetsContractController.test.ts | 54 +++++++++++---------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/assets/AssetsContractController.test.ts b/src/assets/AssetsContractController.test.ts index 4e0f5a97f6..0db52858ce 100644 --- a/src/assets/AssetsContractController.test.ts +++ b/src/assets/AssetsContractController.test.ts @@ -4,14 +4,14 @@ import { AssetsContractController } from './AssetsContractController'; const MAINNET_PROVIDER = new HttpProvider( 'https://mainnet.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', ); -const GODSADDRESS = '0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab'; -const CKADDRESS = '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d'; -const SAI_ADDRESS = '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'; +const ERC721_GODSADDRESS = '0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab'; +const ERC721_CKADDRESS = '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d'; +const ERC20_ADDRESS = '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'; -const ERC1155_COLLECTIBLE_ADDRESS = - '0x495f947276749ce646f68ac8c248420045cb7b5e'; -const ERC1155_COLLECTIBLE_ID = +const ERC1155_ADDRESS = '0x495f947276749ce646f68ac8c248420045cb7b5e'; +const ERC1155_ID = '40815311521795738946686668571398122012172359753720345430028676522525371400193'; + const ERC1155_OWNER_ADDRESS = '0x5a3CA5cD63807Ce5e4d7841AB32Ce6B6d9BbBa2D'; describe('AssetsContractController', () => { @@ -36,11 +36,11 @@ describe('AssetsContractController', () => { it('should get balance of ERC-20 token contract correctly', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const CKBalance = await assetsContract.getBalanceOf( - CKADDRESS, + ERC721_CKADDRESS, '0xb1690c08e213a35ed9bab7b318de14420fb57d8c', ); const CKNoBalance = await assetsContract.getBalanceOf( - CKADDRESS, + ERC721_CKADDRESS, '0xb1690c08e213a35ed9bab7b318de14420fb57d81', ); expect(CKBalance.toNumber()).not.toStrictEqual(0); @@ -50,7 +50,7 @@ describe('AssetsContractController', () => { it('should get ERC-721 collectible tokenId correctly', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const tokenId = await assetsContract.getCollectibleTokenId( - GODSADDRESS, + ERC721_GODSADDRESS, '0x9a90bd8d1149a88b42a99cf62215ad955d6f498a', 0, ); @@ -60,13 +60,13 @@ describe('AssetsContractController', () => { it('should get ERC-721 collectible tokenURI correctly', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const tokenId = await assetsContract.getCollectibleTokenURI( - GODSADDRESS, + ERC721_GODSADDRESS, '0', ); expect(tokenId).toStrictEqual('https://api.godsunchained.com/card/0'); }); - it('should return empty string as URI when address given is not an ERC-721 NFT', async () => { + it('should return empty string as URI when address given is not an ERC-721 collectible', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const tokenId = await assetsContract.getCollectibleTokenURI( '0x0000000000000000000000000000000000000000', @@ -77,52 +77,56 @@ describe('AssetsContractController', () => { it('should get ERC-721 collectible name', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const name = await assetsContract.getAssetName(GODSADDRESS); + const name = await assetsContract.getAssetName(ERC721_GODSADDRESS); expect(name).toStrictEqual('Gods Unchained'); }); it('should get ERC-721 collectible symbol', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const symbol = await assetsContract.getAssetSymbol(GODSADDRESS); + const symbol = await assetsContract.getAssetSymbol(ERC721_GODSADDRESS); expect(symbol).toStrictEqual('GODS'); }); it('should get ERC-20 token decimals', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const symbol = await assetsContract.getTokenDecimals(SAI_ADDRESS); + const symbol = await assetsContract.getTokenDecimals(ERC20_ADDRESS); expect(Number(symbol)).toStrictEqual(18); }); it('should get ERC-721 collectible ownership', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const tokenId = await assetsContract.getOwnerOf(GODSADDRESS, '148332'); + const tokenId = await assetsContract.getOwnerOf( + ERC721_GODSADDRESS, + '148332', + ); expect(tokenId).not.toStrictEqual(''); }); - it('should get balances in a single call', async () => { + it('should get balance of ERC-20 token in a single call', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const balances = await assetsContract.getBalancesInSingleCall(SAI_ADDRESS, [ - SAI_ADDRESS, - ]); - expect(balances[SAI_ADDRESS]).not.toStrictEqual(0); + const balances = await assetsContract.getBalancesInSingleCall( + ERC20_ADDRESS, + [ERC20_ADDRESS], + ); + expect(balances[ERC20_ADDRESS]).not.toStrictEqual(0); }); it('should get the balance of a ERC-1155 collectible for a given address', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const balance = await assetsContract.balanceOfERC1155Collectible( ERC1155_OWNER_ADDRESS, - ERC1155_COLLECTIBLE_ADDRESS, - ERC1155_COLLECTIBLE_ID, + ERC1155_ADDRESS, + ERC1155_ID, ); expect(Number(balance)).toBeGreaterThan(0); }); it('should get the URI of a ERC-1155 collectible', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const expectedUri = `https://api.opensea.io/api/v1/metadata/${ERC1155_COLLECTIBLE_ADDRESS}/0x{id}`; + const expectedUri = `https://api.opensea.io/api/v1/metadata/${ERC1155_ADDRESS}/0x{id}`; const uri = await assetsContract.uriERC1155Collectible( - ERC1155_COLLECTIBLE_ADDRESS, - ERC1155_COLLECTIBLE_ID, + ERC1155_ADDRESS, + ERC1155_ID, ); expect(uri.toLowerCase()).toStrictEqual(expectedUri); }); From fa3a558f53b761c5a5d62cd9f8fafb702b27f741 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Thu, 28 Oct 2021 00:11:44 -0300 Subject: [PATCH 36/43] Remove logs --- src/assets/CollectiblesController.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index 5890536470..1abf6535a4 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -668,7 +668,6 @@ export class CollectiblesController extends BaseController< await this.getCollectibleTokenURI(address, tokenId); return ERC721; } catch { - console.log('failed for erc721'); // Ignore error } @@ -676,7 +675,6 @@ export class CollectiblesController extends BaseController< await this.uriERC1155Collectible(address, tokenId); return ERC1155; } catch { - console.log('failed for erc1155'); // Ignore error } From 36e50e3d9c2a203f56a60f2ef594c6b1b3de51c1 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Thu, 28 Oct 2021 00:12:28 -0300 Subject: [PATCH 37/43] Add standard to CollectibleMetadata object --- src/assets/CollectiblesController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index 1abf6535a4..26200a7290 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -260,7 +260,7 @@ export class CollectiblesController extends BaseController< return { image: object[image], name: object.name, standard }; } - return { image: object[image], name: object.name }; + return { image: object[image], name: object.name, standard }; } /** From 078d9c6f68fb61fbf970eef100f1a41c8d3fb3aa Mon Sep 17 00:00:00 2001 From: gantunesr Date: Thu, 28 Oct 2021 00:18:51 -0300 Subject: [PATCH 38/43] Clean tests --- src/assets/AssetsContractController.test.ts | 28 ++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/assets/AssetsContractController.test.ts b/src/assets/AssetsContractController.test.ts index 0db52858ce..cc07d32f4a 100644 --- a/src/assets/AssetsContractController.test.ts +++ b/src/assets/AssetsContractController.test.ts @@ -4,9 +4,9 @@ import { AssetsContractController } from './AssetsContractController'; const MAINNET_PROVIDER = new HttpProvider( 'https://mainnet.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', ); -const ERC721_GODSADDRESS = '0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab'; -const ERC721_CKADDRESS = '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d'; -const ERC20_ADDRESS = '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'; +const ERC721_GODS_ADDRESS = '0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab'; +const ERC20_CK_ADDRESS = '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d'; +const ERC20_DAI_ADDRESS = '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'; const ERC1155_ADDRESS = '0x495f947276749ce646f68ac8c248420045cb7b5e'; const ERC1155_ID = @@ -36,11 +36,11 @@ describe('AssetsContractController', () => { it('should get balance of ERC-20 token contract correctly', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const CKBalance = await assetsContract.getBalanceOf( - ERC721_CKADDRESS, + ERC20_CK_ADDRESS, '0xb1690c08e213a35ed9bab7b318de14420fb57d8c', ); const CKNoBalance = await assetsContract.getBalanceOf( - ERC721_CKADDRESS, + ERC20_CK_ADDRESS, '0xb1690c08e213a35ed9bab7b318de14420fb57d81', ); expect(CKBalance.toNumber()).not.toStrictEqual(0); @@ -50,7 +50,7 @@ describe('AssetsContractController', () => { it('should get ERC-721 collectible tokenId correctly', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const tokenId = await assetsContract.getCollectibleTokenId( - ERC721_GODSADDRESS, + ERC721_GODS_ADDRESS, '0x9a90bd8d1149a88b42a99cf62215ad955d6f498a', 0, ); @@ -60,7 +60,7 @@ describe('AssetsContractController', () => { it('should get ERC-721 collectible tokenURI correctly', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const tokenId = await assetsContract.getCollectibleTokenURI( - ERC721_GODSADDRESS, + ERC721_GODS_ADDRESS, '0', ); expect(tokenId).toStrictEqual('https://api.godsunchained.com/card/0'); @@ -77,26 +77,26 @@ describe('AssetsContractController', () => { it('should get ERC-721 collectible name', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const name = await assetsContract.getAssetName(ERC721_GODSADDRESS); + const name = await assetsContract.getAssetName(ERC721_GODS_ADDRESS); expect(name).toStrictEqual('Gods Unchained'); }); it('should get ERC-721 collectible symbol', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const symbol = await assetsContract.getAssetSymbol(ERC721_GODSADDRESS); + const symbol = await assetsContract.getAssetSymbol(ERC721_GODS_ADDRESS); expect(symbol).toStrictEqual('GODS'); }); it('should get ERC-20 token decimals', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const symbol = await assetsContract.getTokenDecimals(ERC20_ADDRESS); + const symbol = await assetsContract.getTokenDecimals(ERC20_DAI_ADDRESS); expect(Number(symbol)).toStrictEqual(18); }); it('should get ERC-721 collectible ownership', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const tokenId = await assetsContract.getOwnerOf( - ERC721_GODSADDRESS, + ERC721_GODS_ADDRESS, '148332', ); expect(tokenId).not.toStrictEqual(''); @@ -105,10 +105,10 @@ describe('AssetsContractController', () => { it('should get balance of ERC-20 token in a single call', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const balances = await assetsContract.getBalancesInSingleCall( - ERC20_ADDRESS, - [ERC20_ADDRESS], + ERC20_DAI_ADDRESS, + [ERC20_DAI_ADDRESS], ); - expect(balances[ERC20_ADDRESS]).not.toStrictEqual(0); + expect(balances[ERC20_DAI_ADDRESS]).not.toStrictEqual(0); }); it('should get the balance of a ERC-1155 collectible for a given address', async () => { From 2370a31b4ace6e902e364a407c7724dd290de17a Mon Sep 17 00:00:00 2001 From: gantunesr Date: Thu, 28 Oct 2021 00:26:21 -0300 Subject: [PATCH 39/43] Update constant name --- src/assets/CollectiblesController.ts | 6 +++--- src/constants.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index 26200a7290..01fd49d87c 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -4,7 +4,7 @@ import { BaseController, BaseConfig, BaseState } from '../BaseController'; import type { PreferencesState } from '../user/PreferencesController'; import type { NetworkState, NetworkType } from '../network/NetworkController'; import { safelyExecute, handleFetch, toChecksumHexAddress } from '../util'; -import { MAINNET, RINKEBY_ID, ERC721, ERC1155 } from '../constants'; +import { MAINNET, RINKEBY_CHAIN_ID, ERC721, ERC1155 } from '../constants'; import type { ApiCollectible, ApiCollectibleCreator, @@ -150,7 +150,7 @@ export class CollectiblesController extends BaseController< private getCollectibleApi(contractAddress: string, tokenId: string) { const { chainId } = this.config; switch (chainId) { - case RINKEBY_ID: + case RINKEBY_CHAIN_ID: return `https://testnets-api.opensea.io/api/v1/asset/${contractAddress}/${tokenId}`; default: return `https://api.opensea.io/api/v1/asset/${contractAddress}/${tokenId}`; @@ -160,7 +160,7 @@ export class CollectiblesController extends BaseController< private getCollectibleContractInformationApi(contractAddress: string) { const { chainId } = this.config; switch (chainId) { - case RINKEBY_ID: + case RINKEBY_CHAIN_ID: return `https://testnets-api.opensea.io/api/v1/asset_contract/${contractAddress}`; default: return `https://api.opensea.io/api/v1/asset_contract/${contractAddress}`; diff --git a/src/constants.ts b/src/constants.ts index bd7b3b1b13..29b4a8a371 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -3,7 +3,7 @@ export const RPC = 'rpc'; export const FALL_BACK_VS_CURRENCY = 'ETH'; // NETWORKS ID -export const RINKEBY_ID = '4'; +export const RINKEBY_CHAIN_ID = '4'; // TOKEN STANDARDS export const ERC721 = 'ERC721'; From 672e00ecddeac8776bfbc0aad22dda820a1cd5f2 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Thu, 28 Oct 2021 00:49:56 -0300 Subject: [PATCH 40/43] Clean tests --- .../CollectibleStandards/ERC1155/ERC1155Standard.test.ts | 6 +++--- .../CollectibleStandards/ERC721/ERC721Standard.test.ts | 8 ++++---- src/assets/CollectiblesController.test.ts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts index d3bdb2d571..eb3956c28a 100644 --- a/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts +++ b/src/assets/CollectibleStandards/ERC1155/ERC1155Standard.test.ts @@ -7,9 +7,9 @@ const MAINNET_PROVIDER = new HttpProvider( 'https://mainnet.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', ); -const ENJIN_COLLECTIBLE = '0xfaaFDc07907ff5120a76b34b731b278c38d6043C'; +const ERC1155_ADDRESS = '0xfaaFDc07907ff5120a76b34b731b278c38d6043C'; -describe('ERC721Standard', () => { +describe('ERC1155Standard', () => { let erc1155Standard: ERC1155Standard; let web3: any; @@ -19,7 +19,7 @@ describe('ERC721Standard', () => { }); it('should determine if contract supports URI metadata interface correctly', async () => { - const contract = web3.eth.contract(abiERC1155).at(ENJIN_COLLECTIBLE); + const contract = web3.eth.contract(abiERC1155).at(ERC1155_ADDRESS); const contractSupportsUri = await erc1155Standard.contractSupportsURIMetadataInterface( contract, ); diff --git a/src/assets/CollectibleStandards/ERC721/ERC721Standard.test.ts b/src/assets/CollectibleStandards/ERC721/ERC721Standard.test.ts index 1afa3b959b..9be4c46684 100644 --- a/src/assets/CollectibleStandards/ERC721/ERC721Standard.test.ts +++ b/src/assets/CollectibleStandards/ERC721/ERC721Standard.test.ts @@ -6,8 +6,8 @@ import { ERC721Standard } from './ERC721Standard'; const MAINNET_PROVIDER = new HttpProvider( 'https://mainnet.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', ); -const GODSADDRESS = '0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab'; -const CKADDRESS = '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d'; +const ERC721_GODSADDRESS = '0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab'; +const ERC721_CKADDRESS = '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d'; describe('ERC721Standard', () => { let erc721Standard: ERC721Standard; @@ -19,11 +19,11 @@ describe('ERC721Standard', () => { }); it('should determine if contract supports interface correctly', async () => { - const ckContract = web3.eth.contract(abiERC721).at(CKADDRESS); + const ckContract = web3.eth.contract(abiERC721).at(ERC721_CKADDRESS); const CKSupportsEnumerable = await erc721Standard.contractSupportsEnumerableInterface( ckContract, ); - const godsContract = web3.eth.contract(abiERC721).at(GODSADDRESS); + const godsContract = web3.eth.contract(abiERC721).at(ERC721_GODSADDRESS); const GODSSupportsEnumerable = await erc721Standard.contractSupportsEnumerableInterface( godsContract, ); diff --git a/src/assets/CollectiblesController.test.ts b/src/assets/CollectiblesController.test.ts index 0542e711cd..545f8451ee 100644 --- a/src/assets/CollectiblesController.test.ts +++ b/src/assets/CollectiblesController.test.ts @@ -9,7 +9,7 @@ import { import { AssetsContractController } from './AssetsContractController'; import { CollectiblesController } from './CollectiblesController'; -const KUDOSADDRESS = '0x2aea4add166ebf38b63d09a75de1a7b94aa24163'; +const ERC721_KUDOSADDRESS = '0x2aea4add166ebf38b63d09a75de1a7b94aa24163'; const CRYPTOPUNK_ADDRESS = '0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB'; const ERC721_COLLECTIBLE_ADDRESS = '0x60f80121c31a0d46b5279700f9df786054aa5ee5'; const ERC721_COLLECTIBLE_ID = '1144858'; @@ -252,7 +252,7 @@ describe('CollectiblesController', () => { sandbox .stub(collectiblesController, 'getCollectibleInformationFromApi' as any) .returns(undefined); - await collectiblesController.addCollectible(KUDOSADDRESS, '1203'); + await collectiblesController.addCollectible(ERC721_KUDOSADDRESS, '1203'); expect(collectiblesController.state.collectibles[0]).toStrictEqual({ address: '0x2aEa4Add166EBf38b63d09a75dE1a7b94Aa24163', image: 'Kudos Image', From 48e094c1b7776a074069d65f927c8b952b61bc8b Mon Sep 17 00:00:00 2001 From: gantunesr Date: Thu, 28 Oct 2021 00:51:53 -0300 Subject: [PATCH 41/43] Remove standard from object --- src/assets/CollectiblesController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/CollectiblesController.ts b/src/assets/CollectiblesController.ts index 01fd49d87c..71bdd96998 100644 --- a/src/assets/CollectiblesController.ts +++ b/src/assets/CollectiblesController.ts @@ -260,7 +260,7 @@ export class CollectiblesController extends BaseController< return { image: object[image], name: object.name, standard }; } - return { image: object[image], name: object.name, standard }; + return { image: object[image], name: object.name }; } /** From 54d6eb70fce054d9ce57ca49f9bbcffb51dbb366 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Thu, 28 Oct 2021 13:18:23 -0300 Subject: [PATCH 42/43] Clean tests --- src/assets/AssetsContractController.test.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/assets/AssetsContractController.test.ts b/src/assets/AssetsContractController.test.ts index cc07d32f4a..5dc9d05773 100644 --- a/src/assets/AssetsContractController.test.ts +++ b/src/assets/AssetsContractController.test.ts @@ -4,15 +4,16 @@ import { AssetsContractController } from './AssetsContractController'; const MAINNET_PROVIDER = new HttpProvider( 'https://mainnet.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', ); -const ERC721_GODS_ADDRESS = '0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab'; -const ERC20_CK_ADDRESS = '0x06012c8cf97BEaD5deAe237070F9587f8E7A266d'; -const ERC20_DAI_ADDRESS = '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'; +const ERC20_UNI_ADDRESS = '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984'; +const ERC20_DAI_ADDRESS = '0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'; +const ERC721_GODS_ADDRESS = '0x6EbeAf8e8E946F0716E6533A6f2cefc83f60e8Ab'; const ERC1155_ADDRESS = '0x495f947276749ce646f68ac8c248420045cb7b5e'; const ERC1155_ID = '40815311521795738946686668571398122012172359753720345430028676522525371400193'; -const ERC1155_OWNER_ADDRESS = '0x5a3CA5cD63807Ce5e4d7841AB32Ce6B6d9BbBa2D'; +const TEST_ACCOUNT_PUBLIC_ADDRESS = + '0x5a3CA5cD63807Ce5e4d7841AB32Ce6B6d9BbBa2D'; describe('AssetsContractController', () => { let assetsContract: AssetsContractController; @@ -36,12 +37,12 @@ describe('AssetsContractController', () => { it('should get balance of ERC-20 token contract correctly', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const CKBalance = await assetsContract.getBalanceOf( - ERC20_CK_ADDRESS, - '0xb1690c08e213a35ed9bab7b318de14420fb57d8c', + ERC20_UNI_ADDRESS, + TEST_ACCOUNT_PUBLIC_ADDRESS, ); const CKNoBalance = await assetsContract.getBalanceOf( - ERC20_CK_ADDRESS, - '0xb1690c08e213a35ed9bab7b318de14420fb57d81', + ERC20_UNI_ADDRESS, + '0x202637dAAEfbd7f131f90338a4A6c69F6Cd5CE91', ); expect(CKBalance.toNumber()).not.toStrictEqual(0); expect(CKNoBalance.toNumber()).toStrictEqual(0); @@ -114,7 +115,7 @@ describe('AssetsContractController', () => { it('should get the balance of a ERC-1155 collectible for a given address', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); const balance = await assetsContract.balanceOfERC1155Collectible( - ERC1155_OWNER_ADDRESS, + TEST_ACCOUNT_PUBLIC_ADDRESS, ERC1155_ADDRESS, ERC1155_ID, ); From 22d7c30ae9367be4d72a42d3032be153db111318 Mon Sep 17 00:00:00 2001 From: gantunesr Date: Thu, 28 Oct 2021 13:29:34 -0300 Subject: [PATCH 43/43] Update variable names --- src/assets/AssetsContractController.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/assets/AssetsContractController.test.ts b/src/assets/AssetsContractController.test.ts index 5dc9d05773..163271ce85 100644 --- a/src/assets/AssetsContractController.test.ts +++ b/src/assets/AssetsContractController.test.ts @@ -36,16 +36,16 @@ describe('AssetsContractController', () => { it('should get balance of ERC-20 token contract correctly', async () => { assetsContract.configure({ provider: MAINNET_PROVIDER }); - const CKBalance = await assetsContract.getBalanceOf( + const UNIBalance = await assetsContract.getBalanceOf( ERC20_UNI_ADDRESS, TEST_ACCOUNT_PUBLIC_ADDRESS, ); - const CKNoBalance = await assetsContract.getBalanceOf( + const UNINoBalance = await assetsContract.getBalanceOf( ERC20_UNI_ADDRESS, '0x202637dAAEfbd7f131f90338a4A6c69F6Cd5CE91', ); - expect(CKBalance.toNumber()).not.toStrictEqual(0); - expect(CKNoBalance.toNumber()).toStrictEqual(0); + expect(UNIBalance.toNumber()).not.toStrictEqual(0); + expect(UNINoBalance.toNumber()).toStrictEqual(0); }); it('should get ERC-721 collectible tokenId correctly', async () => {