aboutsummaryrefslogblamecommitdiffstats
path: root/packages/contracts/src/utils/erc721_wrapper.ts
blob: 0c62fd5d91ff4109cd24e75eef1f5f078b8389e7 (plain) (tree)


















                                                                                               
                                                                      







                                                                                                                      
                                                                      





































                                                                                                                       

                                                                                               




                                                                   
                                                                                                                    

                         
                                                                                                                     
                     


                                                                                                                 
















                                                                                                                
                                                                      








                                                                                                                


                                                                                                   



































                                                                                                 
import { ZeroEx } from '0x.js';
import { Deployer } from '@0xproject/deployer';
import { Provider } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';

import { DummyERC721TokenContract } from '../contract_wrappers/generated/dummy_e_r_c721_token';
import { ERC721ProxyContract } from '../contract_wrappers/generated/e_r_c721_proxy';

import { constants } from './constants';
import { ContractName, ERC721BalancesByOwner } from './types';

export class ERC721Wrapper {
    private _tokenOwnerAddresses: string[];
    private _contractOwnerAddress: string;
    private _deployer: Deployer;
    private _provider: Provider;
    private _dummyERC721TokenContracts?: DummyERC721TokenContract[];
    private _erc721ProxyContract?: ERC721ProxyContract;
    private _initialERC721BalancesByOwner: ERC721BalancesByOwner = {};
    constructor(deployer: Deployer, provider: Provider, tokenOwnerAddresses: string[], contractOwnerAddress: string) {
        this._deployer = deployer;
        this._provider = provider;
        this._tokenOwnerAddresses = tokenOwnerAddresses;
        this._contractOwnerAddress = contractOwnerAddress;
    }
    public async deployDummyERC721TokensAsync(): Promise<DummyERC721TokenContract[]> {
        const tokenContractInstances = await Promise.all(
            _.map(_.range(constants.NUM_DUMMY_ERC721_TO_DEPLOY), () =>
                this._deployer.deployAsync(ContractName.DummyERC721Token, constants.DUMMY_ERC721_TOKEN_ARGS),
            ),
        );
        this._dummyERC721TokenContracts = _.map(
            tokenContractInstances,
            tokenContractInstance =>
                new DummyERC721TokenContract(tokenContractInstance.abi, tokenContractInstance.address, this._provider),
        );
        return this._dummyERC721TokenContracts;
    }
    public async deployERC721ProxyAsync(): Promise<ERC721ProxyContract> {
        const proxyContractInstance = await this._deployer.deployAsync(ContractName.ERC721Proxy);
        this._erc721ProxyContract = new ERC721ProxyContract(
            proxyContractInstance.abi,
            proxyContractInstance.address,
            this._provider,
        );
        return this._erc721ProxyContract;
    }
    public async setBalancesAndAllowancesAsync() {
        if (_.isUndefined(this._dummyERC721TokenContracts)) {
            throw new Error('Dummy ERC721 tokens not yet deployed, please call "deployDummyERC721TokensAsync"');
        }
        if (_.isUndefined(this._erc721ProxyContract)) {
            throw new Error('ERC721 proxy contract not yet deployed, please call "deployERC721ProxyAsync"');
        }
        const setBalancePromises: any[] = [];
        const setAllowancePromises: any[] = [];
        this._initialERC721BalancesByOwner = {};
        _.forEach(this._dummyERC721TokenContracts, dummyERC721TokenContract => {
            _.forEach(this._tokenOwnerAddresses, tokenOwnerAddress => {
                _.forEach(_.range(constants.NUM_ERC721_TOKENS_TO_MINT), () => {
                    const tokenId = ZeroEx.generatePseudoRandomSalt();
                    setBalancePromises.push(
                        dummyERC721TokenContract.mint.sendTransactionAsync(tokenOwnerAddress, tokenId, {
                            from: this._contractOwnerAddress,
                        }),
                    );
                    if (_.isUndefined(this._initialERC721BalancesByOwner[tokenOwnerAddress])) {
                        this._initialERC721BalancesByOwner[tokenOwnerAddress] = {
                            [dummyERC721TokenContract.address]: [],
                        };
                    }
                    if (
                        _.isUndefined(
                            this._initialERC721BalancesByOwner[tokenOwnerAddress][dummyERC721TokenContract.address],
                        )
                    ) {
                        this._initialERC721BalancesByOwner[tokenOwnerAddress][dummyERC721TokenContract.address] = [];
                    }
                    this._initialERC721BalancesByOwner[tokenOwnerAddress][dummyERC721TokenContract.address].push(
                        tokenId,
                    );
                });
                const approval = true;
                setAllowancePromises.push(
                    dummyERC721TokenContract.setApprovalForAll.sendTransactionAsync(
                        (this._erc721ProxyContract as ERC721ProxyContract).address,
                        approval,
                        { from: tokenOwnerAddress },
                    ),
                );
            });
        });
        await Promise.all([...setBalancePromises, ...setAllowancePromises]);
    }
    public async getBalancesAsync(): Promise<ERC721BalancesByOwner> {
        if (_.isUndefined(this._dummyERC721TokenContracts)) {
            throw new Error('Dummy ERC721 tokens not yet deployed, please call "deployDummyERC721TokensAsync"');
        }
        if (_.keys(this._initialERC721BalancesByOwner).length === 0) {
            throw new Error(
                'Dummy ERC721 balances and allowances not yet set, please call "setBalancesAndAllowancesAsync"',
            );
        }
        const balancesByOwner: ERC721BalancesByOwner = {};
        const tokenOwnerPromises: any[] = [];
        const tokenInfo: Array<{ tokenId: BigNumber; tokenAddress: string }> = [];
        _.forEach(this._dummyERC721TokenContracts, dummyERC721TokenContract => {
            _.forEach(this._tokenOwnerAddresses, tokenOwnerAddress => {
                const initialTokenOwnerIds = this._initialERC721BalancesByOwner[tokenOwnerAddress][
                    dummyERC721TokenContract.address
                ];
                _.forEach(initialTokenOwnerIds, tokenId => {
                    tokenOwnerPromises.push(dummyERC721TokenContract.ownerOf.callAsync(tokenId));
                    tokenInfo.push({
                        tokenId,
                        tokenAddress: dummyERC721TokenContract.address,
                    });
                });
            });
        });
        const tokenOwnerAddresses = await Promise.all(tokenOwnerPromises);
        _.forEach(tokenOwnerAddresses, (tokenOwnerAddress, ownerIndex) => {
            const tokenAddress = tokenInfo[ownerIndex].tokenAddress;
            const tokenId = tokenInfo[ownerIndex].tokenId;
            if (_.isUndefined(balancesByOwner[tokenOwnerAddress])) {
                balancesByOwner[tokenOwnerAddress] = {
                    [tokenAddress]: [],
                };
            }
            if (_.isUndefined(balancesByOwner[tokenOwnerAddress][tokenAddress])) {
                balancesByOwner[tokenOwnerAddress][tokenAddress] = [];
            }
            balancesByOwner[tokenOwnerAddress][tokenAddress].push(tokenId);
        });
        return balancesByOwner;
    }
    public getTokenOwnerAddresses(): string[] {
        return this._tokenOwnerAddresses;
    }
    public getTokenAddresses(): string[] {
        const tokenAddresses = _.map(
            this._dummyERC721TokenContracts,
            dummyERC721TokenContract => dummyERC721TokenContract.address,
        );
        return tokenAddresses;
    }
}