pragma Singleton import QtQuick 2.13 import "../shared/xss.js" as XSS import "../shared/polyfill.number.toLocaleString.js" as NumberPolyFill QtObject { function isHex(value) { return /^(-0x|0x)?[0-9a-fA-F]*$/i.test(value) } function startsWith0x(value) { return value.startsWith('0x') } function isChatKey(value) { return startsWith0x(value) && isHex(value) && value.length === 132 } function isValidETHNamePrefix(value) { return !(value.trim() === "" || value.endsWith(".") || value.indexOf("..") > -1) } function isAddress(value) { return startsWith0x(value) && isHex(value) && value.length === 42 } function isPrivateKey(value) { return isHex(value) && ((startsWith0x(value) && value.length === 66) || (!startsWith0x(value) && value.length === 64)) } function isMnemonic(value) { if(!value.match(/^([a-z\s]+)$/)){ return false; } var len = value.split(/\s|,/).length; return len >= 12 && len <= 24 && len % 3 == 0; } function compactAddress(addr, numberOfChars) { if(addr.length <= 5 + (numberOfChars * 2)){ // 5 represents these chars 0x... return addr; } return addr.substring(0, 2 + numberOfChars) + "..." + addr.substring(addr.length - numberOfChars); } function linkifyAndXSS(inputText) { //URLs starting with http://, https://, or ftp:// var replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim; var replacedText = inputText.replace(replacePattern1, "$1"); //URLs starting with "www." (without // before it, or it'd re-link the ones done above). var replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim; replacedText = replacedText.replace(replacePattern2, "$1$2"); return XSS.filterXSS(replacedText) } function filterXSS(inputText) { return XSS.filterXSS(inputText) } function toLocaleString(val, locale, options) { return NumberPolyFill.toLocaleString(val, locale, options) } function isOnlyEmoji(inputText) { var emoji_regex = /^(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c[\ude32-\ude3a]|[\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff]|\s)+$/; return emoji_regex.test(inputText); } function removeStatusEns(userName){ return userName.endsWith(".stateofus.eth") ? userName.substr(0, userName.length - 14) : userName } function isValidAddress(inputValue) { return inputValue !== "0x" && /^0x[a-fA-F0-9]{40}$/.test(inputValue) } function isValidEns(inputValue) { if (!inputValue) { return false } const isEmail = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/.test(inputValue) const isDomain = /(?:(?:(?[\w\-]*)(?:\.))?(?[\w\-]*))\.(?[\w\-]*)/.test(inputValue) return isEmail || isDomain || (inputValue.startsWith("@") && inputValue.length > 1) } /** * Removes trailing zeros from a string-representation of a number. Throws * if parameter is not a string */ function stripTrailingZeros(strNumber) { if (!(typeof strNumber === "string")) { try { strNumber = strNumber.toString() } catch(e) { throw "[Utils.stripTrailingZeros] input parameter must be a string" } } return strNumber.replace(/(\.[0-9]*[1-9])0+$|\.0*$/,'$1') } /** * Removes starting zeros from a string-representation of a number. Throws * if parameter is not a string */ function stripStartingZeros(strNumber) { if (!(typeof strNumber === "string")) { try { strNumber = strNumber.toString() } catch(e) { throw "[Utils.stripStartingZeros] input parameter must be a string" } } return strNumber.replace(/^(0*)([0-9\.]+)/, "$2") } function setColorAlpha(color, alpha) { return Qt.hsla(color.hslHue, color.hslSaturation, color.hslLightness, alpha) } function formatTime(timestamp) { let messageDate = new Date(Math.floor(timestamp)) let minutes = messageDate.getMinutes(); let hours = messageDate.getHours(); return (hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes) } function findAssetBySymbol(assets, symbolToFind) { for(var i=0; i|\?|,|\.|\/)/.test(c) } function getTick(wordCount) { return (wordCount === 12 || wordCount === 15 || wordCount === 18 || wordCount === 21 || wordCount === 24) ? "✓ " : ""; } function countWords(text) { if (text.trim() === "") return 0; return text.trim().split(" ").length; } /** * Returns text in the format "✓ 12 words" for seed phrases input boxes */ function seedPhraseWordCountText(text) { let wordCount = countWords(text); return qsTr("%1%2 words").arg(getTick(wordCount)).arg(wordCount.toString()); } function uuid() { return Date.now().toString(36) + Math.random().toString(36).substr(2, 5) } function getNetworkName(network){ switch(network){ case Constants.networkMainnet: return qsTr("Mainnet with upstream RPC") case Constants.networkPOA: return qsTr("POA Network") case Constants.networkXDai: return qsTr("xDai Chain") case Constants.networkGoerli: return qsTr("Goerli with upstream RPC") case Constants.networkRinkeby: return qsTr("Rinkeby with upstream RPC") case Constants.networkRopsten: return qsTr("Ropsten with upstream RPC") default: return network } } }