Skip to content

Commit d31356a

Browse files
committed
fix(cardano-services-client): enhance token metadata mapping to include on-chain metadata fields
1 parent e524e92 commit d31356a

File tree

2 files changed

+103
-8
lines changed

2 files changed

+103
-8
lines changed

packages/cardano-services-client/src/AssetInfoProvider/BlockfrostAssetProvider.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,19 @@ export class BlockfrostAssetProvider extends BlockfrostProvider implements Asset
116116
private mapTokenMetadata(assetId: Cardano.AssetId, asset: Responses['asset']): Asset.TokenMetadata {
117117
return {
118118
assetId,
119-
decimals: asset.metadata?.decimals || undefined,
119+
decimals:
120+
(typeof asset.onchain_metadata?.decimals === 'number'
121+
? asset.onchain_metadata.decimals
122+
: asset.metadata?.decimals) || undefined,
120123
desc: this.metadatumToString(
121-
asset.metadata?.description || (asset.onchain_metadata?.description as string | string[] | undefined)
124+
(asset.onchain_metadata?.description as string | string[] | undefined) || asset.metadata?.description
122125
),
123126
icon: this.metadatumToString(
124-
asset.metadata?.logo || (asset.onchain_metadata?.image as string | string[] | undefined)
127+
(asset.onchain_metadata?.image as string | string[] | undefined) || asset.metadata?.logo
125128
),
126-
name: asset.metadata?.name || (asset.onchain_metadata?.name as string | undefined),
127-
ticker: asset.metadata?.ticker || undefined,
128-
url: asset.metadata?.url || undefined,
129+
name: (asset.onchain_metadata?.name as string | undefined) || asset.metadata?.name,
130+
ticker: (asset.onchain_metadata?.ticker as string | undefined) || asset.metadata?.ticker || undefined,
131+
url: (asset.onchain_metadata?.url as string | undefined) || asset.metadata?.url || undefined,
129132
version: '1.0'
130133
};
131134
}

packages/cardano-services-client/test/AssetInfoProvider/BlockfrostAssetProvider.test.ts

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ describe('BlockfrostAssetProvider', () => {
6666
assetId: mockedAssetId,
6767
decimals: 6,
6868
desc: 'The Nut Coin',
69-
icon: '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',
70-
name: 'nutcoin',
69+
icon: mockedAssetResponse.onchain_metadata?.image as string,
70+
name: mockedAssetResponse.onchain_metadata?.name as string,
7171
ticker: 'nutc',
7272
url: 'https://www.stakenuts.com/'
7373
}
@@ -214,5 +214,97 @@ describe('BlockfrostAssetProvider', () => {
214214

215215
expect(response.nftMetadata!.version).toBe('2.0');
216216
});
217+
218+
describe('onchain_metadata undefined values', () => {
219+
const mockedAssetIdOnChainMetadata = Cardano.AssetId(
220+
'ecbe846aa1a535579d67f9480fa6173b64d7e239df0460eba36e3ad00014df1053617475726e'
221+
);
222+
223+
const baseResponse = {
224+
asset: mockedAssetIdOnChainMetadata,
225+
asset_name: '0014df1053617475726e',
226+
fingerprint: 'asset1lnu3hw2pjw8xfprg7722mh0yu2vfzvk8ta60h0',
227+
initial_mint_tx_hash: 'dcdd8ed32a71523a8393caab9d657964e50648fe0277de77add22b839e6fdb88',
228+
metadata: null,
229+
mint_or_burn_count: 1,
230+
onchain_metadata: {
231+
decimals: 6,
232+
description:
233+
'Saturn is the governance token for the Saturn Swap protocol, a fast and simple decentralized exchange on the Cardano blockchain. https://saturnswap.io/',
234+
logo: 'ipfs://Qmc2RWQxCmAaXn7YGZsXCcs2J5uwW8qQwYzmjh1gUiZBWA',
235+
mediaType: '49696d6167652f706e67',
236+
name: 'Saturn',
237+
ticker: 'SATURN',
238+
url: 'ipfs://Qmc2RWQxCmAaXn7YGZsXCcs2J5'
239+
},
240+
onchain_metadata_extra: 'd8799fff',
241+
onchain_metadata_standard: 'CIP68v1',
242+
policy_id: 'ecbe846aa1a535579d67f9480fa6173b64d7e239df0460eba36e3ad0',
243+
quantity: '100000000000000'
244+
} as Responses['asset'];
245+
246+
test('handles undefined onchain_metadata.decimals', async () => {
247+
const responseWithUndefinedDecimals = {
248+
...baseResponse,
249+
onchain_metadata: {
250+
...baseResponse.onchain_metadata,
251+
decimals: undefined
252+
}
253+
};
254+
255+
mockResponses(request, [[`assets/${mockedAssetIdOnChainMetadata}`, responseWithUndefinedDecimals]]);
256+
257+
const response = await provider.getAsset({
258+
assetId: mockedAssetIdOnChainMetadata,
259+
extraData: { tokenMetadata: true }
260+
});
261+
262+
expect(response.tokenMetadata!.decimals).toBeUndefined();
263+
expect(response.tokenMetadata!.ticker).toBe('SATURN');
264+
expect(response.tokenMetadata!.url).toBe('ipfs://Qmc2RWQxCmAaXn7YGZsXCcs2J5');
265+
});
266+
267+
test('handles undefined onchain_metadata.ticker', async () => {
268+
const responseWithUndefinedTicker = {
269+
...baseResponse,
270+
onchain_metadata: {
271+
...baseResponse.onchain_metadata,
272+
ticker: undefined
273+
}
274+
};
275+
276+
mockResponses(request, [[`assets/${mockedAssetIdOnChainMetadata}`, responseWithUndefinedTicker]]);
277+
278+
const response = await provider.getAsset({
279+
assetId: mockedAssetIdOnChainMetadata,
280+
extraData: { tokenMetadata: true }
281+
});
282+
283+
expect(response.tokenMetadata!.decimals).toBe(6);
284+
expect(response.tokenMetadata!.ticker).toBeUndefined();
285+
expect(response.tokenMetadata!.url).toBe('ipfs://Qmc2RWQxCmAaXn7YGZsXCcs2J5');
286+
});
287+
288+
test('handles undefined onchain_metadata.url', async () => {
289+
const responseWithUndefinedUrl = {
290+
...baseResponse,
291+
onchain_metadata: {
292+
...baseResponse.onchain_metadata,
293+
url: undefined
294+
}
295+
};
296+
297+
mockResponses(request, [[`assets/${mockedAssetIdOnChainMetadata}`, responseWithUndefinedUrl]]);
298+
299+
const response = await provider.getAsset({
300+
assetId: mockedAssetIdOnChainMetadata,
301+
extraData: { tokenMetadata: true }
302+
});
303+
304+
expect(response.tokenMetadata!.decimals).toBe(6);
305+
expect(response.tokenMetadata!.ticker).toBe('SATURN');
306+
expect(response.tokenMetadata!.url).toBeUndefined();
307+
});
308+
});
217309
});
218310
});

0 commit comments

Comments
 (0)