UNPKG

picasso-sdk

Version:

Picasso sdk for cosmos, ethereum, solana, and polkadot ibc transfer

354 lines (353 loc) 16.5 kB
"use strict"; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getNetworkFromAddress = exports.getEthereumAddressNetwork = exports.getSolanaAddressNetwork = exports.getCosmosAddressNetwork = exports.getPolkadotAddressNetwork = exports.getExplorerUrl = exports.getXcmInfo = exports.getSourceChannel = exports.getChannelIdsFromMemo = exports.createForwardPathRecursive = exports.convertAddressToStr = exports.convertCosmosAddress = exports.getPolkadotAddressStr = exports.getSupportedType = exports.getChainIdsByChannels = exports.channelList = exports.getAllowedTokensForPath = exports.buildIbcPath = exports.getForbiddenChains = exports.findSourceChannelId = exports.getTimeOut = exports.memoBuilder = exports.emitter = void 0; var eventemitter3_1 = __importDefault(require("eventemitter3")); var big_js_1 = __importDefault(require("big.js")); var config_1 = require("../../config"); var encoding_1 = require("@cosmjs/encoding"); var util_crypto_1 = require("@polkadot/util-crypto"); var cosmos_1 = require("../cosmos"); exports.emitter = new eventemitter3_1.default(); var bech32_1 = require("bech32"); var solana_1 = require("../solana"); var memoBuilder = function (_a) { var destChannel = _a.destChannel, destAddress = _a.destAddress; return JSON.stringify({ forward: { receiver: destAddress, port: 'transfer', channel: "channel-".concat(destChannel), timeout: cosmos_1.TIMEOUT_IBC_MAX, retries: 0, }, }); }; exports.memoBuilder = memoBuilder; var getTimeOut = function (plusMin) { if (plusMin === void 0) { plusMin = 30; } var now = new Date(); var minutesLater = new Date(now.getTime() + plusMin * 60 * 1000); return new big_js_1.default(minutesLater.getTime()).mul(1000000).toNumber(); }; exports.getTimeOut = getTimeOut; var findSourceChannelId = function (sourceChainId, destChainId) { return Object.keys(config_1.networks[sourceChainId]).find(function (key) { return key === destChainId; }); }; exports.findSourceChannelId = findSourceChannelId; var getForbiddenChains = function (fromChainId, toChainId) { if (fromChainId === toChainId || (fromChainId === 'solana' && config_1.networks[toChainId].chainType === 'polkadot') || (fromChainId === 'ethereum' && config_1.networks[toChainId].chainType === 'polkadot')) return true; return false; }; exports.getForbiddenChains = getForbiddenChains; var buildIbcPath = function (fromChainId, toChainId) { if ((0, exports.getForbiddenChains)(fromChainId, toChainId)) return null; var visited = new Set(); var queue = [[fromChainId, []]]; while (queue.length > 0) { var _a = __read(queue.shift(), 2), currentChainId = _a[0], path = _a[1]; if (currentChainId === toChainId) { return path; } visited.add(currentChainId); var connections = config_1.tokensPerChannel[currentChainId]; if (connections) { for (var destinationId in connections) { var nextChainId = connections[destinationId].chainId; if (!visited.has(nextChainId)) { var newPath = __spreadArray(__spreadArray([], __read(path), false), [ { chainId: currentChainId, channelId: Number(destinationId) }, ], false); queue.push([nextChainId, newPath]); } } } } return null; }; exports.buildIbcPath = buildIbcPath; var getAllowedTokensForPath = function (originChainId, destinationChainId) { var _a, _b, _c, _d; var result = (0, exports.buildIbcPath)(originChainId, destinationChainId); console.log(result); var supportedType = (0, exports.getSupportedType)(originChainId, destinationChainId); if (supportedType === 'xcm') { var xcmInfo = (0, exports.getXcmInfo)(originChainId, destinationChainId); return xcmInfo.tokens; } if (!!supportedType) { return result.reduce(function (acc, item) { if (acc.length > 0) { acc = acc.filter(function (token) { return config_1.tokensPerChannel[item.chainId][item.channelId].tokens.includes(token); }); } else { acc = __spreadArray([], __read(config_1.tokensPerChannel[item.chainId][item.channelId].tokens), false); } return acc; }, []); } if (((_b = (_a = config_1.networks === null || config_1.networks === void 0 ? void 0 : config_1.networks[originChainId]) === null || _a === void 0 ? void 0 : _a.polkadot) === null || _b === void 0 ? void 0 : _b.relayChain) === 'polkadot' || ((_d = (_c = config_1.networks === null || config_1.networks === void 0 ? void 0 : config_1.networks[destinationChainId]) === null || _c === void 0 ? void 0 : _c.polkadot) === null || _d === void 0 ? void 0 : _d.relayChain) === 'polkadot') return ['DOT']; return []; }; exports.getAllowedTokensForPath = getAllowedTokensForPath; exports.channelList = Object.values(config_1.networks); var getChainIdsByChannels = function (channels) { var _a, _b; var chainIdsByChannels = Object.keys(config_1.tokensPerChannel); var chainIds = channels.map(function (channel, i) { if (i === 0) { return chainIdsByChannels.find(function (chainId) { return Object.keys((config_1.tokensPerChannel === null || config_1.tokensPerChannel === void 0 ? void 0 : config_1.tokensPerChannel[chainId]) || {}).some(function (v) { var _a; return v === ((_a = channels[i]) === null || _a === void 0 ? void 0 : _a.toString()); }); }); } return chainIdsByChannels.find(function (chainId) { return Object.keys((config_1.tokensPerChannel === null || config_1.tokensPerChannel === void 0 ? void 0 : config_1.tokensPerChannel[chainId]) || {}).some(function (v) { return v === (channel === null || channel === void 0 ? void 0 : channel.toString()); }); }); }); var lastChannel = channels[channels.length - 1]; var lastChainId = (_b = (_a = Object.values(config_1.tokensPerChannel).find(function (v) { var _a; return !!((_a = v === null || v === void 0 ? void 0 : v[lastChannel.toString()]) === null || _a === void 0 ? void 0 : _a.chainId); })) === null || _a === void 0 ? void 0 : _a[lastChannel.toString()]) === null || _b === void 0 ? void 0 : _b.chainId; if (lastChainId) chainIds.push(lastChainId); return chainIds; }; exports.getChainIdsByChannels = getChainIdsByChannels; var getSupportedType = function (fromChainId, toChainId) { var _a, _b, _c, _d, _e, _f; if (fromChainId === toChainId || !fromChainId || !toChainId) return; if ((0, exports.getSourceChannel)(fromChainId, toChainId)) return 'channel'; if (((_a = config_1.networks[fromChainId]) === null || _a === void 0 ? void 0 : _a.polkadot) && ((_b = config_1.networks[toChainId]) === null || _b === void 0 ? void 0 : _b.polkadot) && ((_d = (_c = config_1.networks[fromChainId]) === null || _c === void 0 ? void 0 : _c.polkadot) === null || _d === void 0 ? void 0 : _d.relayChain) === ((_f = (_e = config_1.networks[toChainId]) === null || _e === void 0 ? void 0 : _e.polkadot) === null || _f === void 0 ? void 0 : _f.relayChain)) return 'xcm'; if ((0, exports.buildIbcPath)(fromChainId, toChainId)) { if (fromChainId === 'solana') return 'pfm'; return 'multihop'; } return; }; exports.getSupportedType = getSupportedType; var getPolkadotAddressStr = function (accountId, prefix) { try { return (0, util_crypto_1.encodeAddress)(accountId, prefix || 0); } catch (e) { return accountId; } }; exports.getPolkadotAddressStr = getPolkadotAddressStr; var convertCosmosAddress = function (address, newPrefix) { try { var data_1 = (0, encoding_1.fromBech32)(address).data; return (0, encoding_1.toBech32)(newPrefix, data_1); } catch (e) { throw new Error('유효하지 않은 Bech32 주소입니다.'); } }; exports.convertCosmosAddress = convertCosmosAddress; var convertAddressToStr = function (address, fromChainId) { var _a, _b, _c; if (!config_1.networks[fromChainId]) return address; if (address.startsWith('0x')) { if (['ethereum', 'solana', '2004', '2023'].some(function (v) { return v === fromChainId; })) { return address; } else if (((_a = config_1.networks[origin]) === null || _a === void 0 ? void 0 : _a.chainType) === 'polkadot' && ((_c = (_b = config_1.networks[origin]) === null || _b === void 0 ? void 0 : _b.polkadot) === null || _c === void 0 ? void 0 : _c.ss58Format)) { return (0, exports.getPolkadotAddressStr)(address, Number(config_1.networks[origin].polkadot.ss58Format)); } else if (config_1.networks[origin].chainType === 'cosmos' && config_1.networks[origin].cosmos.bech32Config.bech32PrefixAccAddr) { return (0, exports.convertCosmosAddress)(address, config_1.networks[origin].cosmos.bech32Config.bech32PrefixAccAddr); } else { return address; } } return address; }; exports.convertAddressToStr = convertAddressToStr; var createForwardPathRecursive = function (ibcPath, index, timeout) { if (index === void 0) { index = 0; } if (timeout === void 0) { timeout = cosmos_1.TIMEOUT_IBC_MAX; } if (index === ibcPath.length - 1) { return { forward: { receiver: ibcPath[index].receiver, port: 'transfer', channel: "channel-".concat(ibcPath[index].channelId), timeout: timeout, retries: 0, }, }; } return { forward: { receiver: ibcPath[index].receiver, port: 'transfer', channel: "channel-".concat(ibcPath[index].channelId), timeout: timeout, retries: 0, next: (0, exports.createForwardPathRecursive)(ibcPath, index + 1), }, }; }; exports.createForwardPathRecursive = createForwardPathRecursive; var getChannelIdsFromMemo = function (memo) { var memoObj; try { memoObj = JSON.parse(memo); } catch (e) { return { channels: [], finalReceiver: '' }; } var findInfos = function (obj) { if (!obj || typeof obj !== 'object') return { channels: [], finalReceiver: '' }; var channels = []; var finalReceiver = obj.receiver; if (obj.channel && typeof obj.channel === 'string') { var channelId = obj.channel.split('-')[1]; if (channelId) channels.push(Number(channelId)); } if (obj.next) { var next = findInfos(obj.next); channels = channels === null || channels === void 0 ? void 0 : channels.concat(next === null || next === void 0 ? void 0 : next.channels); finalReceiver = next === null || next === void 0 ? void 0 : next.finalReceiver; } return { channels: channels, finalReceiver: finalReceiver }; }; var _a = findInfos(memoObj.forward), channels = _a.channels, finalReceiver = _a.finalReceiver; if (channels.length > 0) { return { channels: channels, finalReceiver: finalReceiver }; } return { channels: [], finalReceiver: '' }; }; exports.getChannelIdsFromMemo = getChannelIdsFromMemo; var getSourceChannel = function (fromChainId, toChainId) { if (config_1.tokensPerChannel === null || config_1.tokensPerChannel === void 0 ? void 0 : config_1.tokensPerChannel[fromChainId]) return Object.keys(config_1.tokensPerChannel === null || config_1.tokensPerChannel === void 0 ? void 0 : config_1.tokensPerChannel[fromChainId]).find(function (key) { var _a; return ((_a = config_1.tokensPerChannel === null || config_1.tokensPerChannel === void 0 ? void 0 : config_1.tokensPerChannel[fromChainId][key]) === null || _a === void 0 ? void 0 : _a.chainId) === toChainId; }); }; exports.getSourceChannel = getSourceChannel; var getXcmInfo = function (fromChainId, toChainId) { var _a, _b, _c; return (_c = (_b = (_a = config_1.networks === null || config_1.networks === void 0 ? void 0 : config_1.networks[fromChainId]) === null || _a === void 0 ? void 0 : _a.polkadot) === null || _b === void 0 ? void 0 : _b.hops) === null || _c === void 0 ? void 0 : _c[toChainId]; }; exports.getXcmInfo = getXcmInfo; var getExplorerUrl = function (chainId, infoType, info) { var _a, _b; var explorer = (_b = (_a = config_1.networks[chainId]) === null || _a === void 0 ? void 0 : _a.explorer) === null || _b === void 0 ? void 0 : _b[0]; if (!explorer || !['tx', 'address'].includes(infoType)) { return ''; } switch (explorer.type) { case 'mintscan': case 'solscan': case 'etherscan': return "".concat(explorer.url, "/").concat(infoType, "/").concat(info); case 'pingPub': return "".concat(explorer.url, "/").concat(infoType === 'tx' ? 'tx' : 'account', "/").concat(info); case 'subscan': return "".concat(explorer.url, "/").concat(infoType === 'tx' ? 'extrinsic' : 'account', "/").concat(info); default: return ''; } }; exports.getExplorerUrl = getExplorerUrl; var getPolkadotAddressNetwork = function (accountId) { var _a; try { return (((_a = Object.values(config_1.networks).find(function (v) { var _a; var encoded = (0, util_crypto_1.encodeAddress)((0, util_crypto_1.decodeAddress)(accountId), (_a = v.polkadot) === null || _a === void 0 ? void 0 : _a.ss58Format); if (encoded === accountId) return v.chainId; })) === null || _a === void 0 ? void 0 : _a.chainId) || ''); } catch (e) { return ''; } }; exports.getPolkadotAddressNetwork = getPolkadotAddressNetwork; var getCosmosAddressNetwork = function (accountId) { var found = ''; try { var decoded_1 = bech32_1.bech32.decode(accountId); Object.values(config_1.keplrChains).forEach(function (v) { if (v.bech32Config.bech32PrefixAccAddr === decoded_1.prefix) found = v.chainId; }); return found; } catch (e) { return found; } }; exports.getCosmosAddressNetwork = getCosmosAddressNetwork; var getSolanaAddressNetwork = function (accountId) { try { (0, solana_1.getPublicKey)(accountId); return 'solana'; } catch (e) { return ''; } }; exports.getSolanaAddressNetwork = getSolanaAddressNetwork; var getEthereumAddressNetwork = function (accountId) { if (accountId.startsWith('0x')) { return 'ethereum'; } return ''; }; exports.getEthereumAddressNetwork = getEthereumAddressNetwork; var getNetworkFromAddress = function (address) { var ethereumNetwork = (0, exports.getEthereumAddressNetwork)(address); var cosmosNetwork = (0, exports.getCosmosAddressNetwork)(address); var solanaNetwork = (0, exports.getSolanaAddressNetwork)(address); var polkadotNetwork = (0, exports.getPolkadotAddressNetwork)(address); return (ethereumNetwork || cosmosNetwork || solanaNetwork || polkadotNetwork || ''); }; exports.getNetworkFromAddress = getNetworkFromAddress;