import { providers } from 'ethers'; import BaseService from '../commons/BaseService'; import { eEthereumTxType, EthereumTransactionTypeExtended, tEthereumAddress, transactionType, } from '../commons/types'; import { CrytoPunkValidator } from '../commons/validators/methodValidators'; import { is0OrPositiveAmount, isEthAddress, isPositiveAmount, } from '../commons/validators/paramValidators'; import { CryptoPunksMarket } from './typechain/CryptoPunksMarket'; import { CryptoPunksMarketFactory } from './typechain/CryptoPunksMarketFactory'; export type OfferParams = { user: tEthereumAddress; punkIndex: number; minSalePriceInWei: string; targetAddress: tEthereumAddress; }; export type PunkOffer = { isForSale: boolean; punkIndex: string; seller: string; minValue: string; onlySellTo: string; }; export interface CrytoPunkInterface { offerPunkForSaleToAddress: ( args: OfferParams, ) => EthereumTransactionTypeExtended; punksOfferedForSale: (punkIndex: number) => Promise; } export class CrytoPunkService extends BaseService implements CrytoPunkInterface { readonly crytoPunkAddress: string; constructor(provider: providers.Provider, crytoPunkAddress?: string) { super(provider, CryptoPunksMarketFactory); this.crytoPunkAddress = crytoPunkAddress ?? ''; this.offerPunkForSaleToAddress = this.offerPunkForSaleToAddress.bind(this); this.punksOfferedForSale = this.punksOfferedForSale.bind(this); } @CrytoPunkValidator public offerPunkForSaleToAddress( @isEthAddress('user') @isEthAddress('targetAddress') @isPositiveAmount('punkIndex') @is0OrPositiveAmount('minSalePriceInWei') { user, punkIndex, minSalePriceInWei, targetAddress }: OfferParams, ): EthereumTransactionTypeExtended { const punkContract: CryptoPunksMarket = this.getContractInstance( this.crytoPunkAddress, ); const txCallback: () => Promise = this.generateTxCallback({ rawTxMethod: async () => punkContract.populateTransaction.offerPunkForSaleToAddress( punkIndex, minSalePriceInWei, targetAddress, ), from: user, }); return { tx: txCallback, txType: eEthereumTxType.CRYPOPUNK_OFFER, gas: this.generateTxPriceEstimation([], txCallback), }; } @CrytoPunkValidator public async punksOfferedForSale( @isPositiveAmount() punkIndex: number, ): Promise { const punkContract: CryptoPunksMarket = this.getContractInstance( this.crytoPunkAddress, ); const offer = await punkContract.punksOfferedForSale(punkIndex); return { isForSale: offer.isForSale, punkIndex: offer.punkIndex.toString(), seller: offer.seller, minValue: offer.minValue.toString(), onlySellTo: offer.onlySellTo, }; } }