import { constants } from '../enum/constants'; import { AsyncUtils } from '../utils/async-utils'; import { FgBaseAPI } from './base-api'; const { urls } = constants; export class FgStoreAPI extends FgBaseAPI { cache: boolean; private _tokenForURL: string; private _buyWindow: any; constructor(args) { super(args); const { token, cache = true } = args; this.cache = cache; this._tokenForURL = token; this._buyWindow = null; } protected _afterLoad() { this.baseUrl += 'api/store/'; } get productBaseUrl() { let publicBaseUrl = this.isProduction ? urls.production : urls.development; if (!publicBaseUrl.endsWith('/')) { publicBaseUrl += '/'; } let finalUrl = `${publicBaseUrl}api/store/public/product/:id?api-authorization=${this._tokenForURL}`; if (!this.cache) { finalUrl += '&cache=false'; } return finalUrl; } listUserWallets() { return this._get('blockchain/me'); } listProducts() { return this._get('product'); } listWalletProducts(address, chainId) { return this._get('product/from', { address, chainId }); } listAdquiredProducts() { return this._get('product/me'); } getAdquiredProduct(id) { return this._get(`product/me/${id}`); } useProduct(id, quantity) { return this._post(`product/me/${id}`, { quantity }); } getProductQuery(id, query) { const queries = ['canConsume', 'hasUnits', 'getUnits']; if (!queries.includes(query)) { throw new Error(`Query ${query} is not supported. Supported queries are: ${queries.join(', ')}.`); } return this._get(`product/me/${id}`, { query }); } getProductUrl(id) { const url = this.productBaseUrl.replace(':id', id); return url; } openProductPageWithRedirect(id) { location.href = this.getProductUrl(id) + '&redirect=' + encodeURIComponent(location.href); } openProductPageWindow(id, title, windowFeatures) { return new Promise((resolve, reject) => { if (this._buyWindow && !this._buyWindow.closed) { this._buyWindow.focus(); reject(new Error('Purchase window already open')); return; } let isFinished = false; this._buyWindow = window.open( this.getProductUrl(id), title || 'Store', windowFeatures || 'width=800,height=600'); AsyncUtils.waitForWithoutTimeout(() => isFinished || this._buyWindow.closed).finally(() => { if (!isFinished) { reject(new Error('Purchase window closed')); isFinished = true; } }); window.onmessage = e => { if (e.data && !isFinished) { const data = (typeof e.data === 'string') ? JSON.parse(e.data) : e.data; const isMetamaskMessage = !!e.data.target; if (typeof data.data !== 'undefined' && !isMetamaskMessage) { isFinished = true; if (data.success) { resolve(data.data); } else { reject(data.data.error); } } } }; }); } }