Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ipfs preferences controller #1577

Merged
merged 12 commits into from
Aug 23, 2023
44 changes: 44 additions & 0 deletions packages/assets-controllers/src/NftController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
ApprovalType,
ERC20,
NetworksTicker,
TOKEN_URI_IPFS,
} from '@metamask/controller-utils';
import type {
NetworkState,
Expand Down Expand Up @@ -982,6 +983,7 @@ describe('NftController', () => {
tokenId: '1',
favorite: false,
isCurrentlyOwned: true,
tokenURI: '',
});
});

Expand Down Expand Up @@ -1110,6 +1112,8 @@ describe('NftController', () => {
standard: 'ERC721',
favorite: false,
isCurrentlyOwned: true,
tokenURI:
'https://ipfs.gitcoin.co:443/api/v0/cat/QmPmt6EAaioN78ECnW5oCL8v2YvVSpoBjLCjrXhhsAvoov',
});

expect(
Expand Down Expand Up @@ -1234,6 +1238,8 @@ describe('NftController', () => {
isCurrentlyOwned: true,
imageOriginal: 'image.uri',
numberOfSales: 1,
tokenURI:
'https://api.opensea.io/api/v1/metadata/0x495f947276749Ce646f68AC8c248420045cb7b5e/0x5a3ca5cd63807ce5e4d7841ab32ce6b6d9bbba2d000000000000010000000001',
});
});

Expand Down Expand Up @@ -1344,6 +1350,8 @@ describe('NftController', () => {
standard: 'ERC721',
favorite: false,
isCurrentlyOwned: true,
tokenURI:
'https://ipfs.gitcoin.co:443/api/v0/cat/QmPmt6EAaioN78ECnW5oCL8v2YvVSpoBjLCjrXhhsAvoov',
});

expect(
Expand Down Expand Up @@ -1577,6 +1585,7 @@ describe('NftController', () => {
tokenId: ERC721_KUDOS_TOKEN_ID,
favorite: false,
isCurrentlyOwned: true,
tokenURI: '',
},
]);

Expand Down Expand Up @@ -1804,6 +1813,8 @@ describe('NftController', () => {
standard: 'ERC721',
favorite: false,
isCurrentlyOwned: true,
tokenURI:
'https://bafybeidf7aw7bmnmewwj4ayq3she2jfk5jrdpp24aaucf6fddzb3cfhrvm.ipfs.cloudflare-ipfs.com',
});
});

Expand Down Expand Up @@ -1941,6 +1952,7 @@ describe('NftController', () => {
standard: null,
favorite: false,
isCurrentlyOwned: true,
tokenURI: '',
});
});
});
Expand Down Expand Up @@ -2303,6 +2315,38 @@ describe('NftController', () => {
};
await expect(result).rejects.toThrow(error);
});

it('should add NFT with null metadata if the ipfs gateway is disabled and opensea is disabled', async () => {
const { assetsContract, nftController, preferences } = setupController();

preferences.update({
isIpfsGatewayEnabled: false,
openSeaEnabled: false,
});

sinon
.stub(nftController, 'getNftURIAndStandard' as any)
.returns([TOKEN_URI_IPFS, ERC1155]);

assetsContract.configure({ provider: MAINNET_PROVIDER });
const { selectedAddress, chainId } = nftController.config;

await nftController.addNft(ERC1155_NFT_ADDRESS, ERC1155_NFT_ID);

expect(
nftController.state.allNfts[selectedAddress][chainId][0],
).toStrictEqual({
address: ERC1155_NFT_ADDRESS,
name: null,
description: null,
image: null,
tokenId: ERC1155_NFT_ID,
standard: ERC1155,
favorite: false,
isCurrentlyOwned: true,
tokenURI: TOKEN_URI_IPFS,
});
});
});

describe('updateNftFavoriteStatus', () => {
Expand Down
37 changes: 33 additions & 4 deletions packages/assets-controllers/src/NftController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export interface NftMetadata {
creator?: ApiNftCreator;
lastSale?: ApiNftLastSale;
transactionId?: string;
tokenURI?: string | null;
}

interface AccountParams {
Expand All @@ -158,6 +159,7 @@ export interface NftConfig extends BaseConfig {
ipfsGateway: string;
openSeaEnabled: boolean;
useIPFSSubdomains: boolean;
isIpfsGatewayEnabled: boolean;
}

/**
Expand Down Expand Up @@ -352,12 +354,25 @@ export class NftController extends BaseController<NftConfig, NftState> {
contractAddress: string,
tokenId: string,
): Promise<NftMetadata> {
const { ipfsGateway, useIPFSSubdomains } = this.config;
const { ipfsGateway, useIPFSSubdomains, isIpfsGatewayEnabled } =
this.config;
const result = await this.getNftURIAndStandard(contractAddress, tokenId);
let tokenURI = result[0];
const standard = result[1];

if (tokenURI.startsWith('ipfs://')) {
const hasIpfsTokenURI = tokenURI.startsWith('ipfs://');

if (hasIpfsTokenURI && !isIpfsGatewayEnabled) {
return {
image: null,
name: null,
description: null,
standard: standard || null,
favorite: false,
tokenURI: tokenURI ?? null,
};
}
if (hasIpfsTokenURI) {
tokenURI = getFormattedIpfsUrl(ipfsGateway, tokenURI, useIPFSSubdomains);
}

Expand All @@ -374,6 +389,7 @@ export class NftController extends BaseController<NftConfig, NftState> {
description: object.description,
standard,
favorite: false,
tokenURI: tokenURI ?? null,
};
} catch {
return {
Expand All @@ -382,6 +398,7 @@ export class NftController extends BaseController<NftConfig, NftState> {
description: null,
standard: standard || null,
favorite: false,
tokenURI: tokenURI ?? null,
};
}
}
Expand Down Expand Up @@ -459,6 +476,7 @@ export class NftController extends BaseController<NftConfig, NftState> {
image: blockchainMetadata.image ?? openSeaMetadata?.image ?? null,
standard:
blockchainMetadata.standard ?? openSeaMetadata?.standard ?? null,
tokenURI: blockchainMetadata.tokenURI ?? null,
};
}

Expand Down Expand Up @@ -955,6 +973,7 @@ export class NftController extends BaseController<NftConfig, NftState> {
ipfsGateway: IPFS_DEFAULT_GATEWAY_URL,
openSeaEnabled: false,
useIPFSSubdomains: true,
isIpfsGatewayEnabled: true,
};

this.defaultState = {
Expand All @@ -973,8 +992,18 @@ export class NftController extends BaseController<NftConfig, NftState> {
this.messagingSystem = messenger;

onPreferencesStateChange(
({ selectedAddress, ipfsGateway, openSeaEnabled }) => {
this.configure({ selectedAddress, ipfsGateway, openSeaEnabled });
({
selectedAddress,
ipfsGateway,
openSeaEnabled,
isIpfsGatewayEnabled,
}) => {
this.configure({
selectedAddress,
ipfsGateway,
openSeaEnabled,
isIpfsGatewayEnabled,
});
},
);

Expand Down
1 change: 1 addition & 0 deletions packages/controller-utils/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { NetworkType, NetworksTicker, ChainId, NetworkId } from './types';
export const RPC = 'rpc';
export const FALL_BACK_VS_CURRENCY = 'ETH';
export const IPFS_DEFAULT_GATEWAY_URL = 'https://cloudflare-ipfs.com/ipfs/';
export const TOKEN_URI_IPFS = 'ipfs://*';
tommasini marked this conversation as resolved.
Show resolved Hide resolved

// NETWORKS ID
// `toHex` not invoked to avoid cyclic dependency
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe('PreferencesController', () => {
},
isMultiAccountBalancesEnabled: true,
showTestNetworks: false,
isIpfsGatewayEnabled: true,
});
});

Expand Down Expand Up @@ -200,4 +201,9 @@ describe('PreferencesController', () => {
controller.setShowTestNetworks(true);
expect(controller.state.showTestNetworks).toBe(true);
});
it('should set isIpfsGatewayEnabled', () => {
tommasini marked this conversation as resolved.
Show resolved Hide resolved
const controller = new PreferencesController();
controller.setIsIpfsGatewayEnabled(true);
expect(controller.state.isIpfsGatewayEnabled).toBe(true);
});
});
11 changes: 11 additions & 0 deletions packages/preferences-controller/src/PreferencesController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export interface PreferencesState extends BaseState {
[methodName: string]: boolean;
};
showTestNetworks: boolean;
isIpfsGatewayEnabled: boolean;
}

/**
Expand Down Expand Up @@ -76,6 +77,7 @@ export class PreferencesController extends BaseController<
eth_sign: false,
},
showTestNetworks: false,
isIpfsGatewayEnabled: true,
};
this.initialize();
}
Expand Down Expand Up @@ -310,6 +312,15 @@ export class PreferencesController extends BaseController<
setShowTestNetworks(showTestNetworks: boolean) {
this.update({ showTestNetworks });
}

/**
* A setter for the user allow to be fetched IPFS content
*
* @param isIpfsGatewayEnabled - true to enable ipfs source
*/
setIsIpfsGatewayEnabled(isIpfsGatewayEnabled: boolean) {
this.update({ isIpfsGatewayEnabled });
}
}

export default PreferencesController;
Loading