@chain-registry/utils
Version:
Chain Registry Utils
404 lines (403 loc) • 14.9 kB
JavaScript
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;
;