UNPKG

@chain-registry/utils

Version:
404 lines (403 loc) 14.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getNativeAssetLists = exports.getAssetLists = exports.getCw20Assets = exports.getIbcAssets = exports.getIbcDenomByBase = exports.getIbcAssetPath = exports.getWasmChannel = exports.getNonTransferChannel = exports.getTransferChannel = exports.getIBCData = exports.ibcDenom = void 0; const sha_js_1 = require("sha.js"); const utils_1 = require("./utils"); const ibcDenom = (paths, coinMinimalDenom) => { const prefixes = []; for (const path of paths) { prefixes.push(`${path.portId}/${path.channelId}`); } const prefix = prefixes.join('/'); const denom = `${prefix}/${coinMinimalDenom}`; return ('ibc/' + Buffer.from(new Uint8Array(new sha_js_1.sha256().update(Buffer.from(denom)).digest())) .toString('hex') .toUpperCase()); }; exports.ibcDenom = ibcDenom; const findInfo = (ibc, to, from) => ibc.find((i) => i.chain1.chainName === from && i.chain2.chainName === to); const getIBCData = (ibc, chain, counterparty) => { return (findInfo(ibc, chain, counterparty) || findInfo(ibc, counterparty, chain)); }; exports.getIBCData = getIBCData; const getTransferChannel = (info) => { return info.channels.find((channel) => channel.chain1.portId === 'transfer' && channel.chain2.portId === 'transfer'); }; exports.getTransferChannel = getTransferChannel; const getNonTransferChannel = (info) => { return info.channels.find((channel) => (channel.chain1.portId !== 'transfer' && channel.chain2.portId === 'transfer') || (channel.chain1.portId === 'transfer' && channel.chain2.portId !== 'transfer')); }; exports.getNonTransferChannel = getNonTransferChannel; const getWasmChannel = (info) => { return info.channels.find((channel) => (channel.chain1.portId.startsWith('wasm.') && channel.chain2.portId === 'transfer') || (channel.chain1.portId === 'transfer' && channel.chain2.portId.startsWith('wasm'))); }; exports.getWasmChannel = getWasmChannel; const getIbcAssetPath = (ibc, chain, counterparty, assets, base) => { const ibcInfo = (0, exports.getIBCData)(ibc, chain, counterparty); if (!ibcInfo) { return []; } const channel = base.startsWith('cw20:') ? (0, exports.getWasmChannel)(ibcInfo) : (0, exports.getTransferChannel)(ibcInfo); if (!channel) { return []; } let channelInfo; if (ibcInfo.chain1.chainName === chain) { channelInfo = channel.chain1; } else { channelInfo = channel.chain2; } const memo = [channelInfo]; const assetList = assets.find(({ chainName }) => chainName === counterparty); if (!assetList) { return memo; } const asset = assetList.assets.find((asset) => asset.base === base); if (!asset) { console.log(`no ${base} found in ${counterparty}`); return memo; } const traces = asset.traces?.filter?.((trace) => { return trace.type === 'ibc' || trace.type === 'ibc-cw20'; }) ?? []; if (!traces.length) { return memo; } if (traces.length > 1) { console.log(traces); console.warn('contact maintainers: multi-hop not yet supported'); } const [trace] = traces; return [ ...memo, ...(0, exports.getIbcAssetPath)(ibc, counterparty, trace.counterparty.chainName, assets, trace.counterparty.baseDenom // base ) ]; }; exports.getIbcAssetPath = getIbcAssetPath; const getIbcDenomByBase = (ibc, chain, counterparty, assets, base) => { const ibcInfo = (0, exports.getIBCData)(ibc, chain, counterparty); if (ibcInfo) { const channel = base.startsWith('cw20:') ? (0, exports.getWasmChannel)(ibcInfo) : (0, exports.getTransferChannel)(ibcInfo); if (!channel) { return; } const ibcPath = (0, exports.getIbcAssetPath)(ibc, chain, counterparty, assets, base); const assetList = assets.find(({ chainName }) => chainName === counterparty); if (!assetList) { console.warn(`missing asset list for ${counterparty}`); // could be incorrect... return (0, exports.ibcDenom)(ibcPath, base); } const asset = assetList.assets.find((asset) => asset.base === base); if (!asset) { console.warn(`no ${base} found in ${counterparty}`); return (0, exports.ibcDenom)(ibcPath, base); } const ibcTrace = asset.traces?.find?.((trace) => trace.type === 'ibc'); const baseDenom = ibcTrace?.counterparty?.baseDenom ?? asset.base; return (0, exports.ibcDenom)(ibcPath, baseDenom); } }; exports.getIbcDenomByBase = getIbcDenomByBase; const getIbcAssets = (chainName, ibc, assets) => { const chainIbcInfo = ibc.filter((i) => { return (i.chain1.chainName === chainName || i.chain2.chainName === chainName); }); const ibcAssetLists = chainIbcInfo .map((ibcInfo) => { const counterpartyIs = ibcInfo.chain1.chainName === chainName ? 'chain2' : 'chain1'; const chainIs = ibcInfo.chain1.chainName === chainName ? 'chain1' : 'chain2'; const counterparty = ibcInfo[counterpartyIs].chainName; const counterpartyIbc = ibcInfo[counterpartyIs]; const chainIbc = ibcInfo[chainIs]; const baseCounterpartyAssets = assets.find((a) => { return a.chainName === counterparty; }); if (!baseCounterpartyAssets) { // console.warn('asset not found: ' + counterparty); return; } // const counterpartyAssets = baseCounterpartyAssets; const counterpartyAssets = { ...baseCounterpartyAssets, assets: baseCounterpartyAssets.assets.filter((a) => { if ( // https://github.com/cosmos/chain-registry/issues/1535 baseCounterpartyAssets.chainName === 'carbon' && a.base.startsWith('ibc/')) { return false; } else { return true; } }) }; const ibcAssets = counterpartyAssets.assets .filter((a) => !a.base.startsWith('cw20:')) .map((asset) => { const denom = (0, exports.getIbcDenomByBase)(ibc, chainName, counterparty, // assets, asset.base); const newAsset = { ...asset }; newAsset.base = denom; newAsset.denomUnits = newAsset.denomUnits.map((unit) => { if (unit.denom === asset.base) { const newUnit = { ...unit }; newUnit.denom = denom; newUnit.aliases = [unit.denom]; return newUnit; } return unit; }); return newAsset; }); const channel = (0, exports.getTransferChannel)(ibcInfo); if (!channel) { return; } return { chain: { ...chainIbc, ...channel[chainIs] }, counterparty: { ...counterpartyIbc, ...channel[counterpartyIs] }, assets: ibcAssets }; }) .filter(Boolean); const hash = ibcAssetLists.reduce((m, v) => { m[v.chain.chainName] = m[v.chain.chainName] || []; const assets = v.assets .map((asset) => { try { return { ...asset, traces: [ { type: 'ibc', counterparty: { // source_channel channel_id: v.counterparty.channelId, // source_denom base_denom: asset.denomUnits[0]?.aliases?.[0] ?? asset.denomUnits[0].denom, chain_name: v.counterparty.chainName // port: v.counterparty.port_id }, chain: { // dst_denom channel_id: v.chain.channelId // chain_name: v.chain.chain_name, // port: v.chain.port_id } } ] }; } catch (e) { console.log('problem creating assets:'); console.log(asset); } }) .filter(Boolean); const obj = { ...v, assets }; m[v.chain.chainName].push(obj); return m; }, {}); return Object.keys(hash).map((chain) => { return { chainName: chain, assets: hash[chain].reduce((m, v) => { return [...m, ...v.assets]; }, []) }; }); }; exports.getIbcAssets = getIbcAssets; const getCw20Assets = (chainName, ibc, assets) => { const chainIbcInfo = ibc.filter((i) => { return (i.chain1.chainName === chainName || i.chain2.chainName === chainName); }); const cw20AssetLists = chainIbcInfo .map((ibcInfo) => { const counterpartyIs = ibcInfo.chain1.chainName === chainName ? 'chain2' : 'chain1'; const chainIs = ibcInfo.chain1.chainName === chainName ? 'chain1' : 'chain2'; const counterparty = ibcInfo[counterpartyIs].chainName; const counterpartyIbc = ibcInfo[counterpartyIs]; const chainIbc = ibcInfo[chainIs]; const counterpartyAssets = assets.find((a) => { return a.chainName === counterparty; }); if (!counterpartyAssets) { // console.warn('asset not found: ' + counterparty); return; } const cw20Assets = counterpartyAssets.assets .filter((a) => a.base.startsWith('cw20:')) .map((asset) => { const denom = (0, exports.getIbcDenomByBase)(ibc, chainName, counterparty, // assets, asset.base); const newAsset = { ...asset }; newAsset.base = denom; newAsset.denomUnits = newAsset.denomUnits.map((unit) => { if (unit.denom === asset.base) { const newUnit = { ...unit }; newUnit.denom = denom; newUnit.aliases = [unit.denom]; return newUnit; } return unit; }); return newAsset; }); if (!cw20Assets.length) return; const channel = (0, exports.getWasmChannel)(ibcInfo); if (!channel) { // console.warn( // chainIbc.chain_name, // '<>', // counterpartyIbc.chain_name, // 'MISSING cw20 IBC info' // ); return; } return { chain: { ...chainIbc, ...channel[chainIs] }, counterparty: { ...counterpartyIbc, ...channel[counterpartyIs] }, assets: cw20Assets }; }) .filter(Boolean); const hash = cw20AssetLists.reduce((m, v) => { const assetList = v; m[assetList.chain.chainName] = m[assetList.chain.chainName] || []; const assets = assetList.assets .map((asset) => { try { return { ...asset, traces: [ { type: 'ibc-cw20', counterparty: { port: v.counterparty.portId, // source_channel channel_id: v.counterparty.channelId, // source_denom base_denom: asset.denomUnits[0]?.aliases?.[0] ?? asset.denomUnits[0].denom, chain_name: v.counterparty.chainName }, chain: { // dst_denom port: v.chain.portId, channel_id: v.chain.channelId // chain_name: v.chain.chain_name, } } ] }; } catch (e) { console.log('problem creating cw20 assets'); console.log(asset); } }) .filter(Boolean); const obj = { ...v, assets }; m[v.chain.chainName].push(obj); return m; }, {}); return Object.keys(hash).map((chain) => { return { chainName: chain, assets: hash[chain].reduce((m, v) => { return [...m, ...v.assets]; }, []) }; }); }; exports.getCw20Assets = getCw20Assets; const getAssetLists = (chainName, ibc, assets) => { const ibcAssetLists = (0, exports.getIbcAssets)(chainName, ibc, assets); const cw20Assets = (0, exports.getCw20Assets)(chainName, ibc, assets); return ibcAssetLists.reduce((m, v) => { const chain = v.chainName; const assets = [...v.assets]; const cw20 = cw20Assets.find((a) => a.chainName === chain); if (cw20) { // @ts-ignore [].push.apply(assets, cw20.assets); } return [ { chainName: chain, assets }, ...m ]; }, []); }; exports.getAssetLists = getAssetLists; const getNativeAssetLists = (chainName, ibc, _assets) => { const assets = (0, utils_1.getNativeAssets)(_assets); const ibcAssetLists = (0, exports.getIbcAssets)(chainName, ibc, assets); const cw20Assets = (0, exports.getCw20Assets)(chainName, ibc, assets); return ibcAssetLists.reduce((m, v) => { const chain = v.chainName; const assets = [...v.assets]; const cw20 = cw20Assets.find((a) => a.chainName === chain); if (cw20) { // @ts-ignore [].push.apply(assets, cw20.assets); } return [ { chainName: chain, assets }, ...m ]; }, []); }; exports.getNativeAssetLists = getNativeAssetLists;