UNPKG

sparrow-controllers

Version:

Collection of platform-agnostic modules for creating secure data models for cryptocurrency wallets

367 lines (366 loc) 17.3 kB
/// <reference types="node" /> import { EventEmitter } from 'events'; import { BaseController, BaseConfig, BaseState } from '../BaseController'; import type { PreferencesState } from '../user/PreferencesController'; import type { NetworkState, NetworkType } from '../network/NetworkController'; import type { ApiCollectibleCreator, ApiCollectibleLastSale } from './CollectibleDetectionController'; import type { AssetsContractController } from './AssetsContractController'; /** * @type Collectible * * Collectible representation * @property address - Hex address of a ERC721 contract * @property description - The collectible description * @property image - URI of custom collectible image associated with this tokenId * @property name - Name associated with this tokenId and contract address * @property tokenId - The collectible identifier * @property numberOfSales - Number of sales * @property backgroundColor - The background color to be displayed with the item * @property imagePreview - URI of a smaller image associated with this collectible * @property imageThumbnail - URI of a thumbnail image associated with this collectible * @property imageOriginal - URI of the original image associated with this collectible * @property animation - URI of a animation associated with this collectible * @property animationOriginal - URI of the original animation associated with this collectible * @property externalLink - External link containing additional information * @property creator - The collectible owner information object * @property isCurrentlyOwned - Boolean indicating whether the address/chainId combination where it's currently stored currently owns this collectible */ export interface Collectible extends CollectibleMetadata { tokenId: string; address: string; isCurrentlyOwned?: boolean; } /** * @type CollectibleContract * * Collectible contract information representation * @property name - Contract name * @property logo - Contract logo * @property address - Contract address * @property symbol - Contract symbol * @property description - Contract description * @property totalSupply - Total supply of collectibles * @property assetContractType - The collectible type, it could be `semi-fungible` or `non-fungible` * @property createdDate - Creation date * @property schemaName - The schema followed by the contract, it could be `ERC721` or `ERC1155` * @property externalLink - External link containing additional information */ export interface CollectibleContract { name?: string; logo?: string; address: string; symbol?: string; description?: string; totalSupply?: string; assetContractType?: string; createdDate?: string; schemaName?: string; externalLink?: string; } /** * @type CollectibleMetadata * * Collectible custom information * @property name - Collectible custom name * @property description - The collectible description * @property numberOfSales - Number of sales * @property backgroundColor - The background color to be displayed with the item * @property image - Image custom image URI * @property imagePreview - URI of a smaller image associated with this collectible * @property imageThumbnail - URI of a thumbnail image associated with this collectible * @property imageOriginal - URI of the original image associated with this collectible * @property animation - URI of a animation associated with this collectible * @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 | null; description: string | null; image: string | null; standard: string | null; favorite?: boolean; numberOfSales?: number; backgroundColor?: string; imagePreview?: string; imageThumbnail?: string; imageOriginal?: string; animation?: string; animationOriginal?: string; externalLink?: string; creator?: ApiCollectibleCreator; lastSale?: ApiCollectibleLastSale; } interface AccountParams { userAddress: string; chainId: string; } /** * @type CollectiblesConfig * * Collectibles controller configuration * @property networkType - Network ID as per net_version * @property selectedAddress - Vault selected address */ export interface CollectiblesConfig extends BaseConfig { networkType: NetworkType; selectedAddress: string; chainId: string; ipfsGateway: string; openSeaEnabled: boolean; useIPFSSubdomains: boolean; } /** * @type CollectiblesState * * Assets controller state * @property allCollectibleContracts - Object containing collectibles contract information * @property allCollectibles - Object containing collectibles per account and network * @property collectibleContracts - List of collectibles contracts associated with the active vault * @property collectibles - List of collectibles associated with the active vault * @property ignoredCollectibles - List of collectibles that should be ignored */ export interface CollectiblesState extends BaseState { allCollectibleContracts: { [key: string]: { [key: string]: CollectibleContract[]; }; }; allCollectibles: { [key: string]: { [key: string]: Collectible[]; }; }; ignoredCollectibles: Collectible[]; } /** * Controller that stores assets and exposes convenience methods */ export declare class CollectiblesController extends BaseController<CollectiblesConfig, CollectiblesState> { private mutex; private getCollectibleApi; private getCollectibleContractInformationApi; /** * Helper method to update nested state for allCollectibles and allCollectibleContracts. * * @param newCollection - the modified piece of state to update in the controller's store * @param baseStateKey - The root key in the store to update. * @param passedConfig - An object containing the selectedAddress and chainId that are passed through the auto-detection flow. * @param passedConfig.userAddress - the address passed through the collectible detection flow to ensure detected assets are stored to the correct account * @param passedConfig.chainId - the chainId passed through the collectible detection flow to ensure detected assets are stored to the correct account */ private updateNestedCollectibleState; /** * Request individual collectible information from OpenSea API. * * @param contractAddress - Hex address of the collectible contract. * @param tokenId - The collectible identifier. * @returns Promise resolving to the current collectible name and image. */ private getCollectibleInformationFromApi; /** * Request individual collectible information from contracts that follows Metadata Interface. * * @param contractAddress - Hex address of the collectible contract. * @param tokenId - The collectible identifier. * @returns Promise resolving to the current collectible name and image. */ private getCollectibleInformationFromTokenURI; /** * Retrieve collectible uri with metadata. TODO Update method to use IPFS. * * @param contractAddress - Collectible contract address. * @param tokenId - Collectible token id. * @returns Promise resolving collectible uri and token standard. */ private getCollectibleURIAndStandard; /** * Request individual collectible information (name, image url and description). * * @param contractAddress - Hex address of the collectible contract. * @param tokenId - The collectible identifier. * @returns Promise resolving to the current collectible name and image. */ private getCollectibleInformation; /** * Request collectible contract information from OpenSea API. * * @param contractAddress - Hex address of the collectible contract. * @returns Promise resolving to the current collectible name and image. */ private getCollectibleContractInformationFromApi; /** * Request collectible contract information from the contract itself. * * @param contractAddress - Hex address of the collectible contract. * @returns Promise resolving to the current collectible name and image. */ private getCollectibleContractInformationFromContract; /** * Request collectible contract information from OpenSea API. * * @param contractAddress - Hex address of the collectible contract. * @returns Promise resolving to the collectible contract name, image and description. */ private getCollectibleContractInformation; /** * Adds an individual collectible to the stored collectible list. * * @param address - Hex address of the collectible contract. * @param tokenId - The collectible identifier. * @param collectibleMetadata - Collectible optional information (name, image and description). * @param detection - The chain ID and address of the currently selected network and account at the moment the collectible was detected. * @returns Promise resolving to the current collectible list. */ private addIndividualCollectible; /** * Adds a collectible contract to the stored collectible contracts list. * * @param address - Hex address of the collectible contract. * @param detection - The chain ID and address of the currently selected network and account at the moment the collectible was detected. * @returns Promise resolving to the current collectible contracts list. */ private addCollectibleContract; /** * Removes an individual collectible from the stored token list and saves it in ignored collectibles list. * * @param address - Hex address of the collectible contract. * @param tokenId - Token identifier of the collectible. */ private removeAndIgnoreIndividualCollectible; /** * Removes an individual collectible from the stored token list. * * @param address - Hex address of the collectible contract. * @param tokenId - Token identifier of the collectible. */ private removeIndividualCollectible; /** * Removes a collectible contract to the stored collectible contracts list. * * @param address - Hex address of the collectible contract. * @returns Promise resolving to the current collectible contracts list. */ private removeCollectibleContract; /** * EventEmitter instance used to listen to specific EIP747 events */ hub: EventEmitter; /** * Optional API key to use with opensea */ openSeaApiKey?: string; /** * Name of this controller used during composition */ name: string; private getERC721AssetName; private getERC721AssetSymbol; private getERC721TokenURI; private getERC721OwnerOf; private getERC1155BalanceOf; private getERC1155TokenURI; /** * Creates a CollectiblesController instance. * * @param options - The controller options. * @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes. * @param options.onNetworkStateChange - Allows subscribing to network controller state changes. * @param options.getERC721AssetName - Gets the name of the asset at the given address. * @param options.getERC721AssetSymbol - Gets the symbol of the asset at the given address. * @param options.getERC721TokenURI - Gets the URI of the ERC721 token at the given address, with the given ID. * @param options.getERC721OwnerOf - Get the owner of a ERC-721 collectible. * @param options.getERC1155BalanceOf - Gets balance of a ERC-1155 collectible. * @param options.getERC1155TokenURI - Gets the URI of the ERC1155 token at the given address, with the given ID. * @param config - Initial options used to configure this controller. * @param state - Initial state to set on this controller. */ constructor({ onPreferencesStateChange, onNetworkStateChange, getERC721AssetName, getERC721AssetSymbol, getERC721TokenURI, getERC721OwnerOf, getERC1155BalanceOf, getERC1155TokenURI, }: { onPreferencesStateChange: (listener: (preferencesState: PreferencesState) => void) => void; onNetworkStateChange: (listener: (networkState: NetworkState) => void) => void; getERC721AssetName: AssetsContractController['getERC721AssetName']; getERC721AssetSymbol: AssetsContractController['getERC721AssetSymbol']; getERC721TokenURI: AssetsContractController['getERC721TokenURI']; getERC721OwnerOf: AssetsContractController['getERC721OwnerOf']; getERC1155BalanceOf: AssetsContractController['getERC1155BalanceOf']; getERC1155TokenURI: AssetsContractController['getERC1155TokenURI']; }, config?: Partial<BaseConfig>, state?: Partial<CollectiblesState>); /** * Sets an OpenSea API key to retrieve collectible information. * * @param openSeaApiKey - OpenSea API key. */ setApiKey(openSeaApiKey: string): void; /** * 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. */ isCollectibleOwner(ownerAddress: string, collectibleAddress: string, collectibleId: string): Promise<boolean>; /** * Verifies currently selected address owns entered collectible address/tokenId combo and * adds the collectible and respective collectible contract to the stored collectible and collectible contracts lists. * * @param address - Hex address of the collectible contract. * @param tokenId - The collectible identifier. */ addCollectibleVerifyOwnership(address: string, tokenId: string): Promise<void>; /** * Adds a collectible and respective collectible contract to the stored collectible and collectible contracts lists. * * @param address - Hex address of the collectible contract. * @param tokenId - The collectible identifier. * @param collectibleMetadata - Collectible optional metadata. * @param detection - The chain ID and address of the currently selected network and account at the moment the collectible was detected. * @returns Promise resolving to the current collectible list. */ addCollectible(address: string, tokenId: string, collectibleMetadata?: CollectibleMetadata, detection?: AccountParams): Promise<void>; /** * Removes a collectible from the stored token list. * * @param address - Hex address of the collectible contract. * @param tokenId - Token identifier of the collectible. */ removeCollectible(address: string, tokenId: string): void; /** * Removes a collectible from the stored token list and saves it in ignored collectibles list. * * @param address - Hex address of the collectible contract. * @param tokenId - Token identifier of the collectible. */ removeAndIgnoreCollectible(address: string, tokenId: string): void; /** * Removes all collectibles from the ignored list. */ clearIgnoredCollectibles(): void; /** * Checks whether input collectible is still owned by the user * And updates the isCurrentlyOwned value on the collectible object accordingly. * * @param collectible - The collectible object to check and update. * @param batch - A boolean indicating whether this method is being called as part of a batch or single update. * @param accountParams - The userAddress and chainId to check ownership against * @param accountParams.userAddress - the address passed through the confirmed transaction flow to ensure detected assets are stored to the correct account * @param accountParams.chainId - the chainId passed through the confirmed transaction flow to ensure detected assets are stored to the correct account * @returns the collectible with the updated isCurrentlyOwned value */ checkAndUpdateSingleCollectibleOwnershipStatus(collectible: Collectible, batch: boolean, { userAddress, chainId }?: AccountParams | undefined): Promise<Collectible>; /** * Checks whether Collectibles associated with current selectedAddress/chainId combination are still owned by the user * And updates the isCurrentlyOwned value on each accordingly. */ checkAndUpdateAllCollectiblesOwnershipStatus(): Promise<void>; /** * Update collectible favorite status. * * @param address - Hex address of the collectible contract. * @param tokenId - Hex address of the collectible contract. * @param favorite - Collectible new favorite status. */ updateCollectibleFavoriteStatus(address: string, tokenId: string, favorite: boolean): void; } export default CollectiblesController;