@yoroi/portfolio
Version:
The Portfolio package of Yoroi SDK
257 lines (255 loc) • 8.91 kB
JavaScript
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