UNPKG

@yoroi/portfolio

Version:

The Portfolio package of Yoroi SDK

257 lines (255 loc) 8.91 kB
import { PromiseAllLimited, fetchData, isLeft, isRight } from '@yoroi/common'; import { Api, Chain } from '@yoroi/types'; import { freeze } from 'immer'; import { toDullahanRequest, toProcessedMediaRequest, toSecondaryTokenInfos, toTokenActivity, toTokenHistory } from './transformers'; import { parseTokenDiscovery } from '../../validators/token-discovery'; import { parseTokenTraits } from '../../validators/token-traits'; import { parseTokenInfo } from '../../validators/token-info'; export const portfolioApiMaker = _ref => { let { network, maxIdsPerRequest, maxConcurrentRequests, request = fetchData } = _ref; const config = apiConfig[network]; return freeze({ async tokenDiscovery(id) { const response = await request({ method: 'get', url: `${config.tokenDiscovery}/${id}`, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } }); if (isRight(response)) { const discovery = parseTokenDiscovery(response.value.data); if (!discovery) { return freeze({ tag: 'left', error: { status: -3, message: 'Failed to transform token discovery response', responseData: response.value.data } }, true); } return freeze({ tag: 'right', value: { status: response.value.status, data: discovery } }, true); } return response; }, async tokenInfos(idsWithCache) { const chunks = []; for (let i = 0; i < idsWithCache.length; i += maxIdsPerRequest) chunks.push(idsWithCache.slice(i, i + maxIdsPerRequest)); const tasks = chunks.map(ids => () => request({ method: 'post', url: config.tokenInfos, data: toDullahanRequest(ids), headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } })); const responses = await PromiseAllLimited(tasks, maxConcurrentRequests); const infos = responses.filter(isRight).reduce((acc, _ref2) => { let { value: { data } } = _ref2; return Object.assign(acc, data); }, {}); // return with the first error only if none of responses were successful const firstError = responses.find(isLeft); if (Object.keys(infos).length === 0 && firstError) return firstError; const transformedResponseData = toSecondaryTokenInfos(infos); const transformedResponse = freeze({ tag: 'right', value: { status: Api.HttpStatusCode.Ok, data: transformedResponseData } }, true); return transformedResponse; }, async tokenInfo(id) { const response = await request({ method: 'get', url: `${config.tokenInfo}/${id}`, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } }); if (isRight(response)) { const tokenInfo = parseTokenInfo(response.value.data); if (!tokenInfo) { return freeze({ tag: 'left', error: { status: -3, message: 'Failed to transform token info response', responseData: response.value.data } }, true); } return freeze({ tag: 'right', value: { status: response.value.status, data: tokenInfo } }, true); } return response; }, async tokenTraits(id) { const response = await request({ method: 'get', url: `${config.tokenTraits}/${id}`, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } }); if (isRight(response)) { const traits = parseTokenTraits(response.value.data); if (!traits) { return freeze({ tag: 'left', error: { status: -3, message: 'Failed to transform token traits response', responseData: response.value.data } }, true); } return freeze({ tag: 'right', value: { status: response.value.status, data: traits } }, true); } return response; }, async tokenActivity(requestedIds, window) { const chunks = []; for (let i = 0; i < requestedIds.length; i += maxIdsPerRequest) chunks.push(requestedIds.slice(i, i + maxIdsPerRequest)); const tasks = chunks.map(ids => () => request({ method: 'post', url: `${config.tokenActivity}/${window}`, data: ids, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } })); const responses = await PromiseAllLimited(tasks, maxConcurrentRequests); const activities = responses.filter(isRight).reduce((acc, _ref3) => { let { value: { data } } = _ref3; return Object.assign(acc, data); }, {}); // return with the first error only if none of responses were successful const firstError = responses.find(isLeft); if (Object.keys(activities).length === 0 && firstError) return firstError; const transformedResponseData = toTokenActivity(activities); const transformedResponse = freeze({ tag: 'right', value: { status: Api.HttpStatusCode.Ok, data: transformedResponseData } }, true); return transformedResponse; }, async tokenHistory(tokenId, period) { const response = await request({ method: 'post', url: config.tokenHistory, data: { tokenId, period }, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' } }); if (isRight(response)) { const history = toTokenHistory(response.value.data); if (!history) { return freeze({ tag: 'left', error: { status: -3, message: 'Failed to transform token history response', responseData: response.value.data } }, true); } return freeze({ tag: 'right', value: { status: response.value.status, data: history } }, true); } return response; }, async tokenImageInvalidate(ids) { const tasks = ids.map(id => () => request({ method: 'post', url: config.tokenImageInvalidate, data: toProcessedMediaRequest(id), headers: { 'Content-Type': 'application/json' } })); await PromiseAllLimited(tasks, maxConcurrentRequests); } }, true); }; export const apiConfig = freeze({ [Chain.Network.Mainnet]: { tokenDiscovery: 'https://zero.yoroiwallet.com/tokens/discovery', tokenInfo: 'https://zero.yoroiwallet.com/tokens/info', tokenInfos: 'https://zero.yoroiwallet.com/tokens/info/multi', tokenTraits: 'https://zero.yoroiwallet.com/tokens/nft/traits', tokenActivity: 'https://zero.yoroiwallet.com/tokens/activity/multi', tokenHistory: 'https://zero.yoroiwallet.com/tokens/history/price', tokenImageInvalidate: 'https://mainnet.processed-media.yoroiwallet.com/invalidate' }, [Chain.Network.Preprod]: { tokenDiscovery: 'https://yoroi-backend-zero-preprod.emurgornd.com/tokens/discovery', tokenInfo: 'https://yoroi-backend-zero-preprod.emurgornd.com/tokens/info', tokenInfos: 'https://yoroi-backend-zero-preprod.emurgornd.com/tokens/info/multi', tokenTraits: 'https://yoroi-backend-zero-preprod.emurgornd.com/tokens/nft/traits', tokenActivity: 'https://yoroi-backend-zero-preprod.emurgornd.com/tokens/activity/multi', tokenHistory: 'https://yoroi-backend-zero-preprod.emurgornd.com/tokens/history/price', tokenImageInvalidate: 'https://preprod.processed-media.yoroiwallet.com/invalidate' }, [Chain.Network.Preview]: { tokenDiscovery: 'https://yoroi-backend-zero-preview.emurgornd.com/tokens/discovery', tokenInfo: 'https://yoroi-backend-zero-preview.emurgornd.com/tokens/info', tokenInfos: 'https://yoroi-backend-zero-preview.emurgornd.com/tokens/info/multi', tokenTraits: 'https://yoroi-backend-zero-preview.emurgornd.com/tokens/nft/traits', tokenActivity: 'https://yoroi-backend-zero-preview.emurgornd.com/tokens/activity/multi', tokenHistory: 'https://yoroi-backend-zero-preview.emurgornd.com/tokens/history/price', tokenImageInvalidate: 'https://preview.processed-media.yoroiwallet.com/invalidate' } }, true); //# sourceMappingURL=api-maker.js.map