@yoroi/api
Version:
The API package of Yoroi SDK
145 lines (142 loc) • 4.55 kB
JavaScript
;
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