UNPKG

@yoroi/api

Version:
145 lines (142 loc) 4.55 kB
"use strict"; import { fetcher, isArray, isRecord } from '@yoroi/common'; import { CIP25_KEY_NFT, CIP25_V2, CIP26_KEY_FT } from './constants'; import { parseFtMetadataRecord, parseNftMetadataRecord } from './parsers'; import { getTokenIdentity } from '../translators/helpers/getTokenIdentity'; export const getOnChainMetadatas = (baseUrl, request = fetcher) => { return (tokenIds, fetcherConfig) => { if (tokenIds.length === 0) { return Promise.resolve({}); } const assets = tokenIds.map(id => { const [policy, nameHex] = id.split('.'); return { policy, nameHex }; }); const payload = { assets }; return request({ ...fetcherConfig, url: `${baseUrl}/multiAsset/metadata`, method: 'POST', headers: { 'Content-Type': 'application/json' }, data: payload }).then(response => { if (!isRecord(response)) return Promise.reject(new Error('Invalid asset metadatas')); const responseRecords = response; const result = {}; for (const id of tokenIds) { const { policyId, name, assetName } = getTokenIdentity(id); // API returns with utf8 name, the request sends with hex name const tokenId = `${policyId}.${name}`; const records = responseRecords[tokenId]; if (!isArray(records)) { result[id] = emptyOnChainMetadataRecord; continue; } const tokenIdentity = { policyId, name, nameHex: assetName }; result[id] = getMetadataResult(records, tokenIdentity); } return Promise.resolve(result); }); }; }; export function getMetadataResult(records, tokenIdentity) { let ftMetadataResult = { mintFtMetadata: undefined, mintFtRecordSelected: undefined }; let nftMetadataResult = { mintNftMetadata: undefined, mintNftRecordSelected: undefined }; for (const record of records) { if (!isRecord(record)) continue; const possibleMetadatas = record; // avoid casting in every usage if (possibleMetadatas?.key === CIP26_KEY_FT && !ftMetadataResult.mintFtRecordSelected) { ftMetadataResult = getFtRecord(possibleMetadatas, tokenIdentity); continue; } if (possibleMetadatas?.key === CIP25_KEY_NFT && !nftMetadataResult.mintNftRecordSelected) { nftMetadataResult = getNftRecord(possibleMetadatas, tokenIdentity); } } return { ...ftMetadataResult, ...nftMetadataResult }; } function getFtRecord(record, tokenIdentity) { const possibleFtMetadataRecord = findMetadataRecord(record, tokenIdentity); if (possibleFtMetadataRecord !== undefined && isRecord(possibleFtMetadataRecord)) { const parsedFtMetadataRecord = parseFtMetadataRecord(possibleFtMetadataRecord); if (parsedFtMetadataRecord !== undefined) { return { // record holds original tx mint metadata is safe to cast here mintFtMetadata: record, mintFtRecordSelected: parsedFtMetadataRecord }; } } return { mintFtMetadata: record, mintFtRecordSelected: undefined }; } function getNftRecord(record, tokenIdentity) { const possibleNftMetadataRecord = findMetadataRecord(record, tokenIdentity); if (possibleNftMetadataRecord !== undefined && isRecord(possibleNftMetadataRecord)) { const parsedNftMetadataRecord = parseNftMetadataRecord(possibleNftMetadataRecord); if (parsedNftMetadataRecord !== undefined) { return { // record holds original tx mint metadata is safe to cast here mintNftMetadata: record, mintNftRecordSelected: parsedNftMetadataRecord }; } } return { mintNftMetadata: record, mintNftRecordSelected: undefined }; } export function findMetadataRecord(possibleMetadataRecord, tokenIdentity) { const { policyId, name, nameHex } = tokenIdentity; const metadataRecord = possibleMetadataRecord; const { metadata } = metadataRecord; if (!isRecord(metadata)) return undefined; const { version, ...policyRecords } = metadata; const isV2 = version === CIP25_V2; const assetRecords = policyRecords[policyId]; if (!isRecord(assetRecords)) return undefined; return isV2 ? assetRecords[nameHex] : assetRecords[name]; } export const emptyOnChainMetadataRecord = { mintFtMetadata: undefined, mintFtRecordSelected: undefined, mintNftMetadata: undefined, mintNftRecordSelected: undefined }; //# sourceMappingURL=token-onchain-metadata.js.map