/** * Component: Accounts * Author: Nearblocks Pte Ltd * License: Business Source License 1.1 * Description: Accounts component enable users to view information related to their accounts. * @interface Props * @param {string} [network] - The network data to show, either mainnet or testnet * @param {Function} [t] - A function for internationalization (i18n) provided by the next-translate package. * @param {string} [id] - The account identifier passed as a string. */ /* INCLUDE COMPONENT: "includes/icons/FaExternalLinkAlt.jsx" */ const FaExternalLinkAlt = () => { return ( <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512"> <path d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z" /> </svg> ); };/* END_INCLUDE COMPONENT: "includes/icons/FaExternalLinkAlt.jsx" */ /* INCLUDE: "includes/libs.jsx" */ function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function fiatValue(big, price) { const value = Big(big).mul(Big(price)); const stringValue = value.toFixed(6); // Set the desired maximum fraction digits const [integerPart, fractionalPart] = stringValue.split('.'); // Format integer part with commas const formattedIntegerPart = integerPart.replace( /\B(?=(\d{3})+(?!\d))/g, ',', ); // Combine formatted integer and fractional parts const formattedNumber = fractionalPart ? `${formattedIntegerPart}.${fractionalPart}` : formattedIntegerPart; return formattedNumber; } function nanoToMilli(nano) { return Big(nano).div(Big(10).pow(6)).round().toNumber(); } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function getConfig(network) { switch (network) { case 'mainnet': return { ownerId: 'nearblocks.near', nodeUrl: 'https://rpc.mainnet.near.org', backendUrl: 'https://api3.nearblocks.io/v1/', rpcUrl: 'https://archival-rpc.testnet.near.org', appUrl: 'https://nearblocks.io/', }; case 'testnet': return { ownerId: 'nearblocks.testnet', nodeUrl: 'https://rpc.testnet.near.org', backendUrl: 'https://api3-testnet.nearblocks.io/v1/', rpcUrl: 'https://archival-rpc.testnet.near.org', appUrl: 'https://testnet.nearblocks.io/', }; default: return {}; } } function debounce( delay, func, ) { let timer; let active = true; const debounced = (arg) => { if (active) { clearTimeout(timer); timer = setTimeout(() => { active && func(arg); timer = undefined; }, delay); } else { func(arg); } }; debounced.isPending = () => { return timer !== undefined; }; debounced.cancel = () => { active = false; }; debounced.flush = (arg) => func(arg); return debounced; } function timeAgo(unixTimestamp) { const currentTimestamp = Math.floor(Date.now() / 1000); const secondsAgo = currentTimestamp - unixTimestamp; if (secondsAgo < 5) { return 'Just now'; } else if (secondsAgo < 60) { return `${secondsAgo} seconds ago`; } else if (secondsAgo < 3600) { const minutesAgo = Math.floor(secondsAgo / 60); return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`; } else if (secondsAgo < 86400) { const hoursAgo = Math.floor(secondsAgo / 3600); return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`; } else { const daysAgo = Math.floor(secondsAgo / 86400); return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`; } } function shortenAddress(address) { const string = String(address); if (string.length <= 20) return string; return `${string.substr(0, 10)}...${string.substr(-7)}`; } function urlHostName(url) { try { const domain = new URL(url); return domain?.hostname ?? null; } catch (e) { return null; } } function holderPercentage(supply, quantity) { return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100); } function isAction(type) { const actions = [ 'DEPLOY_CONTRACT', 'TRANSFER', 'STAKE', 'ADD_KEY', 'DELETE_KEY', 'DELETE_ACCOUNT', ]; return actions.includes(type.toUpperCase()); } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function formatWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function formatWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } function fiatValue(big, price) { const value = Big(big).mul(Big(price)); const stringValue = value.toFixed(6); // Set the desired maximum fraction digits const [integerPart, fractionalPart] = stringValue.split('.'); // Format integer part with commas const formattedIntegerPart = integerPart.replace( /\B(?=(\d{3})+(?!\d))/g, ',', ); // Combine formatted integer and fractional parts const formattedNumber = fractionalPart ? `${formattedIntegerPart}.${fractionalPart}` : formattedIntegerPart; return formattedNumber; } function nanoToMilli(nano) { return Big(nano).div(Big(10).pow(6)).round().toNumber(); } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function getConfig(network) { switch (network) { case 'mainnet': return { ownerId: 'nearblocks.near', nodeUrl: 'https://rpc.mainnet.near.org', backendUrl: 'https://api3.nearblocks.io/v1/', rpcUrl: 'https://archival-rpc.testnet.near.org', appUrl: 'https://nearblocks.io/', }; case 'testnet': return { ownerId: 'nearblocks.testnet', nodeUrl: 'https://rpc.testnet.near.org', backendUrl: 'https://api3-testnet.nearblocks.io/v1/', rpcUrl: 'https://archival-rpc.testnet.near.org', appUrl: 'https://testnet.nearblocks.io/', }; default: return {}; } } function debounce( delay, func, ) { let timer; let active = true; const debounced = (arg) => { if (active) { clearTimeout(timer); timer = setTimeout(() => { active && func(arg); timer = undefined; }, delay); } else { func(arg); } }; debounced.isPending = () => { return timer !== undefined; }; debounced.cancel = () => { active = false; }; debounced.flush = (arg) => func(arg); return debounced; } function timeAgo(unixTimestamp) { const currentTimestamp = Math.floor(Date.now() / 1000); const secondsAgo = currentTimestamp - unixTimestamp; if (secondsAgo < 5) { return 'Just now'; } else if (secondsAgo < 60) { return `${secondsAgo} seconds ago`; } else if (secondsAgo < 3600) { const minutesAgo = Math.floor(secondsAgo / 60); return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`; } else if (secondsAgo < 86400) { const hoursAgo = Math.floor(secondsAgo / 3600); return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`; } else { const daysAgo = Math.floor(secondsAgo / 86400); return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`; } } function shortenAddress(address) { const string = String(address); if (string.length <= 20) return string; return `${string.substr(0, 10)}...${string.substr(-7)}`; } function urlHostName(url) { try { const domain = new URL(url); return domain?.hostname ?? null; } catch (e) { return null; } } function holderPercentage(supply, quantity) { return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100); } function isAction(type) { const actions = [ 'DEPLOY_CONTRACT', 'TRANSFER', 'STAKE', 'ADD_KEY', 'DELETE_KEY', 'DELETE_ACCOUNT', ]; return actions.includes(type.toUpperCase()); } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function formatWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } function nanoToMilli(nano) { return Big(nano).div(Big(10).pow(6)).round().toNumber(); } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function getConfig(network) { switch (network) { case 'mainnet': return { ownerId: 'nearblocks.near', nodeUrl: 'https://rpc.mainnet.near.org', backendUrl: 'https://api3.nearblocks.io/v1/', rpcUrl: 'https://archival-rpc.testnet.near.org', appUrl: 'https://nearblocks.io/', }; case 'testnet': return { ownerId: 'nearblocks.testnet', nodeUrl: 'https://rpc.testnet.near.org', backendUrl: 'https://api3-testnet.nearblocks.io/v1/', rpcUrl: 'https://archival-rpc.testnet.near.org', appUrl: 'https://testnet.nearblocks.io/', }; default: return {}; } } function debounce( delay, func, ) { let timer; let active = true; const debounced = (arg) => { if (active) { clearTimeout(timer); timer = setTimeout(() => { active && func(arg); timer = undefined; }, delay); } else { func(arg); } }; debounced.isPending = () => { return timer !== undefined; }; debounced.cancel = () => { active = false; }; debounced.flush = (arg) => func(arg); return debounced; } function timeAgo(unixTimestamp) { const currentTimestamp = Math.floor(Date.now() / 1000); const secondsAgo = currentTimestamp - unixTimestamp; if (secondsAgo < 5) { return 'Just now'; } else if (secondsAgo < 60) { return `${secondsAgo} seconds ago`; } else if (secondsAgo < 3600) { const minutesAgo = Math.floor(secondsAgo / 60); return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`; } else if (secondsAgo < 86400) { const hoursAgo = Math.floor(secondsAgo / 3600); return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`; } else { const daysAgo = Math.floor(secondsAgo / 86400); return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`; } } function shortenAddress(address) { const string = String(address); if (string.length <= 20) return string; return `${string.substr(0, 10)}...${string.substr(-7)}`; } function urlHostName(url) { try { const domain = new URL(url); return domain?.hostname ?? null; } catch (e) { return null; } } function holderPercentage(supply, quantity) { return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100); } function isAction(type) { const actions = [ 'DEPLOY_CONTRACT', 'TRANSFER', 'STAKE', 'ADD_KEY', 'DELETE_KEY', 'DELETE_ACCOUNT', ]; return actions.includes(type.toUpperCase()); } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function formatWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } function shortenAddress(address) { const string = String(address); if (string.length <= 20) return string; return `${string.substr(0, 10)}...${string.substr(-7)}`; } function urlHostName(url) { try { const domain = new URL(url); return domain?.hostname ?? null; } catch (e) { return null; } } function holderPercentage(supply, quantity) { return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100); } function isAction(type) { const actions = [ 'DEPLOY_CONTRACT', 'TRANSFER', 'STAKE', 'ADD_KEY', 'DELETE_KEY', 'DELETE_ACCOUNT', ]; return actions.includes(type.toUpperCase()); } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function formatWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } function getConfig(network) { switch (network) { case 'mainnet': return { ownerId: 'nearblocks.near', nodeUrl: 'https://rpc.mainnet.near.org', backendUrl: 'https://api3.nearblocks.io/v1/', rpcUrl: 'https://archival-rpc.testnet.near.org', appUrl: 'https://nearblocks.io/', }; case 'testnet': return { ownerId: 'nearblocks.testnet', nodeUrl: 'https://rpc.testnet.near.org', backendUrl: 'https://api3-testnet.nearblocks.io/v1/', rpcUrl: 'https://archival-rpc.testnet.near.org', appUrl: 'https://testnet.nearblocks.io/', }; default: return {}; } } function debounce( delay, func, ) { let timer; let active = true; const debounced = (arg) => { if (active) { clearTimeout(timer); timer = setTimeout(() => { active && func(arg); timer = undefined; }, delay); } else { func(arg); } }; debounced.isPending = () => { return timer !== undefined; }; debounced.cancel = () => { active = false; }; debounced.flush = (arg) => func(arg); return debounced; } function timeAgo(unixTimestamp) { const currentTimestamp = Math.floor(Date.now() / 1000); const secondsAgo = currentTimestamp - unixTimestamp; if (secondsAgo < 5) { return 'Just now'; } else if (secondsAgo < 60) { return `${secondsAgo} seconds ago`; } else if (secondsAgo < 3600) { const minutesAgo = Math.floor(secondsAgo / 60); return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`; } else if (secondsAgo < 86400) { const hoursAgo = Math.floor(secondsAgo / 3600); return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`; } else { const daysAgo = Math.floor(secondsAgo / 86400); return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`; } } function shortenAddress(address) { const string = String(address); if (string.length <= 20) return string; return `${string.substr(0, 10)}...${string.substr(-7)}`; } function urlHostName(url) { try { const domain = new URL(url); return domain?.hostname ?? null; } catch (e) { return null; } } function holderPercentage(supply, quantity) { return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100); } function isAction(type) { const actions = [ 'DEPLOY_CONTRACT', 'TRANSFER', 'STAKE', 'ADD_KEY', 'DELETE_KEY', 'DELETE_ACCOUNT', ]; return actions.includes(type.toUpperCase()); } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function formatWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } /* END_INCLUDE: "includes/libs.jsx" */ /* INCLUDE: "includes/formats.jsx" */ function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function dollarNonCentFormat(number) { const bigNumber = new Big(number).toFixed(0); // Extract integer part and format with commas const integerPart = bigNumber.toString(); const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ','); return formattedInteger; } function weight(number) { let sizeInBytes = new Big(number); if (sizeInBytes.lt(0)) { throw new Error('Invalid input. Please provide a non-negative number.'); } const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; let suffixIndex = 0; while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) { sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes suffixIndex++; } const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex]; return formattedSize; } function convertToUTC(timestamp, hour) { const date = new Date(timestamp); // Get UTC date components const utcYear = date.getUTCFullYear(); const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based const utcDay = ('0' + date.getUTCDate()).slice(-2); const utcHours = ('0' + date.getUTCHours()).slice(-2); const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2); const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2); // Array of month abbreviations const monthAbbreviations = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; const monthIndex = Number(utcMonth) - 1; // Format the date as required (Jul-25-2022 16:25:37) let formattedDate = monthAbbreviations[monthIndex] + '-' + utcDay + '-' + utcYear + ' ' + utcHours + ':' + utcMinutes + ':' + utcSeconds; if (hour) { // Convert hours to 12-hour format let hour12 = parseInt(utcHours); const ampm = hour12 >= 12 ? 'PM' : 'AM'; hour12 = hour12 % 12 || 12; // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM) formattedDate = monthAbbreviations[monthIndex] + '-' + utcDay + '-' + utcYear + ' ' + hour12 + ':' + utcMinutes + ':' + utcSeconds + ' ' + ampm; } return formattedDate; } function getTimeAgoString(timestamp) { const currentUTC = Date.now(); const date = new Date(timestamp); const seconds = Math.floor((currentUTC - date.getTime()) / 1000); const intervals = { year: seconds / (60 * 60 * 24 * 365), month: seconds / (60 * 60 * 24 * 30), week: seconds / (60 * 60 * 24 * 7), day: seconds / (60 * 60 * 24), hour: seconds / (60 * 60), minute: seconds / 60, }; if (intervals.year >= 1) { return ( Math.floor(intervals.year) + ' year' + (Math.floor(intervals.year) > 1 ? 's' : '') + ' ago' ); } else if (intervals.month >= 1) { return ( Math.floor(intervals.month) + ' month' + (Math.floor(intervals.month) > 1 ? 's' : '') + ' ago' ); } else if (intervals.day >= 1) { return ( Math.floor(intervals.day) + ' day' + (Math.floor(intervals.day) > 1 ? 's' : '') + ' ago' ); } else if (intervals.hour >= 1) { return ( Math.floor(intervals.hour) + ' hour' + (Math.floor(intervals.hour) > 1 ? 's' : '') + ' ago' ); } else if (intervals.minute >= 1) { return ( Math.floor(intervals.minute) + ' minute' + (Math.floor(intervals.minute) > 1 ? 's' : '') + ' ago' ); } else { return 'a few seconds ago'; } } function formatWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } function formatTimestampToString(timestamp) { const date = new Date(timestamp); // Format the date to 'YYYY-MM-DD HH:mm:ss' format const formattedDate = date.toISOString().replace('T', ' ').split('.')[0]; return formattedDate; } function convertToMetricPrefix(numberStr) { const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes let result = new Big(numberStr); let count = 0; while (result.abs().gte('1e3') && count < prefixes.length - 1) { result = result.div(1e3); count++; } // Check if the value is an integer or has more than two digits before the decimal point if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) { result = result.toFixed(2); } else { result = result.toFixed(0); } return result.toString() + ' ' + prefixes[count]; } function formatNumber(value) { let bigValue = new Big(value); const suffixes = ['', 'K', 'M', 'B', 'T']; let suffixIndex = 0; while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) { bigValue = bigValue.div(1000); suffixIndex++; } const formattedValue = bigValue.toFixed(1).replace(/\.0+$/, ''); return `${formattedValue} ${suffixes[suffixIndex]}`; } function gasFee(gas, price) { const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true); return `${near}`; } function currency(number) { let absNumber = new Big(number).abs(); const suffixes = ['', 'K', 'M', 'B', 'T', 'Q']; let suffixIndex = 0; while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) { absNumber = absNumber.div(1000); // Divide using big.js's div method suffixIndex++; } const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places return ( (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex] ); } function formatDate(dateString) { const inputDate = new Date(dateString); const days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', ]; const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', ]; const dayOfWeek = days[inputDate.getDay()]; const month = months[inputDate.getMonth()]; const day = inputDate.getDate(); const year = inputDate.getFullYear(); const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year; return formattedDate; } function formatCustomDate(inputDate) { var date = new Date(inputDate); // Array of month names var monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; // Get month and day var month = monthNames[date.getMonth()]; var day = date.getDate(); // Create formatted date string in "MMM DD" format var formattedDate = month + ' ' + (day < 10 ? '0' + day : day); return formattedDate; } function shortenHex(address) { return `${address && address.substr(0, 6)}...${address.substr(-4)}`; } function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } function shortenToken(token) { return truncateString(token, 14, ''); } function shortenTokenSymbol(token) { return truncateString(token, 5, ''); } function gasPercentage(gasUsed, gasAttached) { if (!gasAttached) return 'N/A'; const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2); return `${formattedNumber}%`; } function serialNumber(index, page, perPage) { return index + 1 + (page - 1) * perPage; } function capitalizeWords(str) { const words = str.split('_'); const capitalizedWords = words.map( (word) => word.charAt(0).toUpperCase() + word.slice(1), ); const result = capitalizedWords.join(' '); return result; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function dollarNonCentFormat(number) { const bigNumber = new Big(number).toFixed(0); // Extract integer part and format with commas const integerPart = bigNumber.toString(); const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ','); return formattedInteger; } function weight(number) { let sizeInBytes = new Big(number); if (sizeInBytes.lt(0)) { throw new Error('Invalid input. Please provide a non-negative number.'); } const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; let suffixIndex = 0; while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) { sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes suffixIndex++; } const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex]; return formattedSize; } function convertToUTC(timestamp, hour) { const date = new Date(timestamp); // Get UTC date components const utcYear = date.getUTCFullYear(); const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based const utcDay = ('0' + date.getUTCDate()).slice(-2); const utcHours = ('0' + date.getUTCHours()).slice(-2); const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2); const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2); // Array of month abbreviations const monthAbbreviations = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; const monthIndex = Number(utcMonth) - 1; // Format the date as required (Jul-25-2022 16:25:37) let formattedDate = monthAbbreviations[monthIndex] + '-' + utcDay + '-' + utcYear + ' ' + utcHours + ':' + utcMinutes + ':' + utcSeconds; if (hour) { // Convert hours to 12-hour format let hour12 = parseInt(utcHours); const ampm = hour12 >= 12 ? 'PM' : 'AM'; hour12 = hour12 % 12 || 12; // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM) formattedDate = monthAbbreviations[monthIndex] + '-' + utcDay + '-' + utcYear + ' ' + hour12 + ':' + utcMinutes + ':' + utcSeconds + ' ' + ampm; } return formattedDate; } function getTimeAgoString(timestamp) { const currentUTC = Date.now(); const date = new Date(timestamp); const seconds = Math.floor((currentUTC - date.getTime()) / 1000); const intervals = { year: seconds / (60 * 60 * 24 * 365), month: seconds / (60 * 60 * 24 * 30), week: seconds / (60 * 60 * 24 * 7), day: seconds / (60 * 60 * 24), hour: seconds / (60 * 60), minute: seconds / 60, }; if (intervals.year >= 1) { return ( Math.floor(intervals.year) + ' year' + (Math.floor(intervals.year) > 1 ? 's' : '') + ' ago' ); } else if (intervals.month >= 1) { return ( Math.floor(intervals.month) + ' month' + (Math.floor(intervals.month) > 1 ? 's' : '') + ' ago' ); } else if (intervals.day >= 1) { return ( Math.floor(intervals.day) + ' day' + (Math.floor(intervals.day) > 1 ? 's' : '') + ' ago' ); } else if (intervals.hour >= 1) { return ( Math.floor(intervals.hour) + ' hour' + (Math.floor(intervals.hour) > 1 ? 's' : '') + ' ago' ); } else if (intervals.minute >= 1) { return ( Math.floor(intervals.minute) + ' minute' + (Math.floor(intervals.minute) > 1 ? 's' : '') + ' ago' ); } else { return 'a few seconds ago'; } } function formatWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } function formatTimestampToString(timestamp) { const date = new Date(timestamp); // Format the date to 'YYYY-MM-DD HH:mm:ss' format const formattedDate = date.toISOString().replace('T', ' ').split('.')[0]; return formattedDate; } function convertToMetricPrefix(numberStr) { const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes let result = new Big(numberStr); let count = 0; while (result.abs().gte('1e3') && count < prefixes.length - 1) { result = result.div(1e3); count++; } // Check if the value is an integer or has more than two digits before the decimal point if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) { result = result.toFixed(2); } else { result = result.toFixed(0); } return result.toString() + ' ' + prefixes[count]; } function formatNumber(value) { let bigValue = new Big(value); const suffixes = ['', 'K', 'M', 'B', 'T']; let suffixIndex = 0; while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) { bigValue = bigValue.div(1000); suffixIndex++; } const formattedValue = bigValue.toFixed(1).replace(/\.0+$/, ''); return `${formattedValue} ${suffixes[suffixIndex]}`; } function gasFee(gas, price) { const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true); return `${near}`; } function currency(number) { let absNumber = new Big(number).abs(); const suffixes = ['', 'K', 'M', 'B', 'T', 'Q']; let suffixIndex = 0; while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) { absNumber = absNumber.div(1000); // Divide using big.js's div method suffixIndex++; } const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places return ( (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex] ); } function formatDate(dateString) { const inputDate = new Date(dateString); const days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', ]; const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', ]; const dayOfWeek = days[inputDate.getDay()]; const month = months[inputDate.getMonth()]; const day = inputDate.getDate(); const year = inputDate.getFullYear(); const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year; return formattedDate; } function formatCustomDate(inputDate) { var date = new Date(inputDate); // Array of month names var monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; // Get month and day var month = monthNames[date.getMonth()]; var day = date.getDate(); // Create formatted date string in "MMM DD" format var formattedDate = month + ' ' + (day < 10 ? '0' + day : day); return formattedDate; } function shortenHex(address) { return `${address && address.substr(0, 6)}...${address.substr(-4)}`; } function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } function shortenToken(token) { return truncateString(token, 14, ''); } function shortenTokenSymbol(token) { return truncateString(token, 5, ''); } function gasPercentage(gasUsed, gasAttached) { if (!gasAttached) return 'N/A'; const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2); return `${formattedNumber}%`; } function serialNumber(index, page, perPage) { return index + 1 + (page - 1) * perPage; } function capitalizeWords(str) { const words = str.split('_'); const capitalizedWords = words.map( (word) => word.charAt(0).toUpperCase() + word.slice(1), ); const result = capitalizedWords.join(' '); return result; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function weight(number) { let sizeInBytes = new Big(number); if (sizeInBytes.lt(0)) { throw new Error('Invalid input. Please provide a non-negative number.'); } const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; let suffixIndex = 0; while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) { sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes suffixIndex++; } const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex]; return formattedSize; } function convertToUTC(timestamp, hour) { const date = new Date(timestamp); // Get UTC date components const utcYear = date.getUTCFullYear(); const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based const utcDay = ('0' + date.getUTCDate()).slice(-2); const utcHours = ('0' + date.getUTCHours()).slice(-2); const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2); const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2); // Array of month abbreviations const monthAbbreviations = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; const monthIndex = Number(utcMonth) - 1; // Format the date as required (Jul-25-2022 16:25:37) let formattedDate = monthAbbreviations[monthIndex] + '-' + utcDay + '-' + utcYear + ' ' + utcHours + ':' + utcMinutes + ':' + utcSeconds; if (hour) { // Convert hours to 12-hour format let hour12 = parseInt(utcHours); const ampm = hour12 >= 12 ? 'PM' : 'AM'; hour12 = hour12 % 12 || 12; // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM) formattedDate = monthAbbreviations[monthIndex] + '-' + utcDay + '-' + utcYear + ' ' + hour12 + ':' + utcMinutes + ':' + utcSeconds + ' ' + ampm; } return formattedDate; } function getTimeAgoString(timestamp) { const currentUTC = Date.now(); const date = new Date(timestamp); const seconds = Math.floor((currentUTC - date.getTime()) / 1000); const intervals = { year: seconds / (60 * 60 * 24 * 365), month: seconds / (60 * 60 * 24 * 30), week: seconds / (60 * 60 * 24 * 7), day: seconds / (60 * 60 * 24), hour: seconds / (60 * 60), minute: seconds / 60, }; if (intervals.year >= 1) { return ( Math.floor(intervals.year) + ' year' + (Math.floor(intervals.year) > 1 ? 's' : '') + ' ago' ); } else if (intervals.month >= 1) { return ( Math.floor(intervals.month) + ' month' + (Math.floor(intervals.month) > 1 ? 's' : '') + ' ago' ); } else if (intervals.day >= 1) { return ( Math.floor(intervals.day) + ' day' + (Math.floor(intervals.day) > 1 ? 's' : '') + ' ago' ); } else if (intervals.hour >= 1) { return ( Math.floor(intervals.hour) + ' hour' + (Math.floor(intervals.hour) > 1 ? 's' : '') + ' ago' ); } else if (intervals.minute >= 1) { return ( Math.floor(intervals.minute) + ' minute' + (Math.floor(intervals.minute) > 1 ? 's' : '') + ' ago' ); } else { return 'a few seconds ago'; } } function formatWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } function formatTimestampToString(timestamp) { const date = new Date(timestamp); // Format the date to 'YYYY-MM-DD HH:mm:ss' format const formattedDate = date.toISOString().replace('T', ' ').split('.')[0]; return formattedDate; } function convertToMetricPrefix(numberStr) { const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes let result = new Big(numberStr); let count = 0; while (result.abs().gte('1e3') && count < prefixes.length - 1) { result = result.div(1e3); count++; } // Check if the value is an integer or has more than two digits before the decimal point if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) { result = result.toFixed(2); } else { result = result.toFixed(0); } return result.toString() + ' ' + prefixes[count]; } function formatNumber(value) { let bigValue = new Big(value); const suffixes = ['', 'K', 'M', 'B', 'T']; let suffixIndex = 0; while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) { bigValue = bigValue.div(1000); suffixIndex++; } const formattedValue = bigValue.toFixed(1).replace(/\.0+$/, ''); return `${formattedValue} ${suffixes[suffixIndex]}`; } function gasFee(gas, price) { const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true); return `${near}`; } function currency(number) { let absNumber = new Big(number).abs(); const suffixes = ['', 'K', 'M', 'B', 'T', 'Q']; let suffixIndex = 0; while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) { absNumber = absNumber.div(1000); // Divide using big.js's div method suffixIndex++; } const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places return ( (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex] ); } function formatDate(dateString) { const inputDate = new Date(dateString); const days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', ]; const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', ]; const dayOfWeek = days[inputDate.getDay()]; const month = months[inputDate.getMonth()]; const day = inputDate.getDate(); const year = inputDate.getFullYear(); const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year; return formattedDate; } function formatCustomDate(inputDate) { var date = new Date(inputDate); // Array of month names var monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; // Get month and day var month = monthNames[date.getMonth()]; var day = date.getDate(); // Create formatted date string in "MMM DD" format var formattedDate = month + ' ' + (day < 10 ? '0' + day : day); return formattedDate; } function shortenHex(address) { return `${address && address.substr(0, 6)}...${address.substr(-4)}`; } function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } function shortenToken(token) { return truncateString(token, 14, ''); } function shortenTokenSymbol(token) { return truncateString(token, 5, ''); } function gasPercentage(gasUsed, gasAttached) { if (!gasAttached) return 'N/A'; const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2); return `${formattedNumber}%`; } function serialNumber(index, page, perPage) { return index + 1 + (page - 1) * perPage; } function capitalizeWords(str) { const words = str.split('_'); const capitalizedWords = words.map( (word) => word.charAt(0).toUpperCase() + word.slice(1), ); const result = capitalizedWords.join(' '); return result; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function convertToUTC(timestamp, hour) { const date = new Date(timestamp); // Get UTC date components const utcYear = date.getUTCFullYear(); const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based const utcDay = ('0' + date.getUTCDate()).slice(-2); const utcHours = ('0' + date.getUTCHours()).slice(-2); const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2); const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2); // Array of month abbreviations const monthAbbreviations = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; const monthIndex = Number(utcMonth) - 1; // Format the date as required (Jul-25-2022 16:25:37) let formattedDate = monthAbbreviations[monthIndex] + '-' + utcDay + '-' + utcYear + ' ' + utcHours + ':' + utcMinutes + ':' + utcSeconds; if (hour) { // Convert hours to 12-hour format let hour12 = parseInt(utcHours); const ampm = hour12 >= 12 ? 'PM' : 'AM'; hour12 = hour12 % 12 || 12; // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM) formattedDate = monthAbbreviations[monthIndex] + '-' + utcDay + '-' + utcYear + ' ' + hour12 + ':' + utcMinutes + ':' + utcSeconds + ' ' + ampm; } return formattedDate; } function getTimeAgoString(timestamp) { const currentUTC = Date.now(); const date = new Date(timestamp); const seconds = Math.floor((currentUTC - date.getTime()) / 1000); const intervals = { year: seconds / (60 * 60 * 24 * 365), month: seconds / (60 * 60 * 24 * 30), week: seconds / (60 * 60 * 24 * 7), day: seconds / (60 * 60 * 24), hour: seconds / (60 * 60), minute: seconds / 60, }; if (intervals.year >= 1) { return ( Math.floor(intervals.year) + ' year' + (Math.floor(intervals.year) > 1 ? 's' : '') + ' ago' ); } else if (intervals.month >= 1) { return ( Math.floor(intervals.month) + ' month' + (Math.floor(intervals.month) > 1 ? 's' : '') + ' ago' ); } else if (intervals.day >= 1) { return ( Math.floor(intervals.day) + ' day' + (Math.floor(intervals.day) > 1 ? 's' : '') + ' ago' ); } else if (intervals.hour >= 1) { return ( Math.floor(intervals.hour) + ' hour' + (Math.floor(intervals.hour) > 1 ? 's' : '') + ' ago' ); } else if (intervals.minute >= 1) { return ( Math.floor(intervals.minute) + ' minute' + (Math.floor(intervals.minute) > 1 ? 's' : '') + ' ago' ); } else { return 'a few seconds ago'; } } function formatWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } function formatTimestampToString(timestamp) { const date = new Date(timestamp); // Format the date to 'YYYY-MM-DD HH:mm:ss' format const formattedDate = date.toISOString().replace('T', ' ').split('.')[0]; return formattedDate; } function convertToMetricPrefix(numberStr) { const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes let result = new Big(numberStr); let count = 0; while (result.abs().gte('1e3') && count < prefixes.length - 1) { result = result.div(1e3); count++; } // Check if the value is an integer or has more than two digits before the decimal point if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) { result = result.toFixed(2); } else { result = result.toFixed(0); } return result.toString() + ' ' + prefixes[count]; } function formatNumber(value) { let bigValue = new Big(value); const suffixes = ['', 'K', 'M', 'B', 'T']; let suffixIndex = 0; while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) { bigValue = bigValue.div(1000); suffixIndex++; } const formattedValue = bigValue.toFixed(1).replace(/\.0+$/, ''); return `${formattedValue} ${suffixes[suffixIndex]}`; } function gasFee(gas, price) { const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true); return `${near}`; } function currency(number) { let absNumber = new Big(number).abs(); const suffixes = ['', 'K', 'M', 'B', 'T', 'Q']; let suffixIndex = 0; while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) { absNumber = absNumber.div(1000); // Divide using big.js's div method suffixIndex++; } const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places return ( (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex] ); } function formatDate(dateString) { const inputDate = new Date(dateString); const days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', ]; const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', ]; const dayOfWeek = days[inputDate.getDay()]; const month = months[inputDate.getMonth()]; const day = inputDate.getDate(); const year = inputDate.getFullYear(); const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year; return formattedDate; } function formatCustomDate(inputDate) { var date = new Date(inputDate); // Array of month names var monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; // Get month and day var month = monthNames[date.getMonth()]; var day = date.getDate(); // Create formatted date string in "MMM DD" format var formattedDate = month + ' ' + (day < 10 ? '0' + day : day); return formattedDate; } function shortenHex(address) { return `${address && address.substr(0, 6)}...${address.substr(-4)}`; } function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } function shortenToken(token) { return truncateString(token, 14, ''); } function shortenTokenSymbol(token) { return truncateString(token, 5, ''); } function gasPercentage(gasUsed, gasAttached) { if (!gasAttached) return 'N/A'; const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2); return `${formattedNumber}%`; } function serialNumber(index, page, perPage) { return index + 1 + (page - 1) * perPage; } function capitalizeWords(str) { const words = str.split('_'); const capitalizedWords = words.map( (word) => word.charAt(0).toUpperCase() + word.slice(1), ); const result = capitalizedWords.join(' '); return result; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } /* END_INCLUDE: "includes/formats.jsx" */ /* INCLUDE COMPONENT: "includes/icons/TokenImage.jsx" */ /** * @interface Props * @param {string} [src] - The URL string pointing to the image source. * @param {string} [alt] - The alternate text description for the image. * @param {string} [className] - The CSS class name(s) for styling purposes. * @param {string} [appUrl] - The URL of the application. */ const TokenImage = ({ appUrl, src, alt, className, onLoad, onSetSrc, }) => { const placeholder = `${appUrl}images/tokenplaceholder.svg`; const handleLoad = () => { if (onLoad) { onLoad(); } }; const handleError = () => { if (onSetSrc) { onSetSrc(placeholder); } if (onLoad) { onLoad(); } }; return ( <img src={src || placeholder} alt={alt} className={className} onLoad={handleLoad} onError={handleError} /> ); };/* END_INCLUDE COMPONENT: "includes/icons/TokenImage.jsx" */ /* INCLUDE COMPONENT: "includes/Common/TokenHoldings.jsx" */ /** * @interface Props * @param {string} [id] - Optional identifier for the account, passed as a string. * @param {boolean} [loading] - Flag indicating whether data is currently loading. * @param {InventoryInfo} [data] - Information related to the inventory. * @param {Object} [ft] - Object containing details about the tokens. * @param {number} [ft.amount] - amount in USD of tokens. * @param {Object[]} [ft.tokens] - Array containing 'TokenListInfo' objects, providing information about individual token details. * @param {string} [appUrl] - The URL of the application. */ /* INCLUDE: "includes/libs.jsx" */ function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function getConfig(network) { switch (network) { case 'mainnet': return { ownerId: 'nearblocks.near', nodeUrl: 'https://rpc.mainnet.near.org', backendUrl: 'https://api3.nearblocks.io/v1/', rpcUrl: 'https://archival-rpc.testnet.near.org', appUrl: 'https://nearblocks.io/', }; case 'testnet': return { ownerId: 'nearblocks.testnet', nodeUrl: 'https://rpc.testnet.near.org', backendUrl: 'https://api3-testnet.nearblocks.io/v1/', rpcUrl: 'https://archival-rpc.testnet.near.org', appUrl: 'https://testnet.nearblocks.io/', }; default: return {}; } } function debounce( delay, func, ) { let timer; let active = true; const debounced = (arg) => { if (active) { clearTimeout(timer); timer = setTimeout(() => { active && func(arg); timer = undefined; }, delay); } else { func(arg); } }; debounced.isPending = () => { return timer !== undefined; }; debounced.cancel = () => { active = false; }; debounced.flush = (arg) => func(arg); return debounced; } function timeAgo(unixTimestamp) { const currentTimestamp = Math.floor(Date.now() / 1000); const secondsAgo = currentTimestamp - unixTimestamp; if (secondsAgo < 5) { return 'Just now'; } else if (secondsAgo < 60) { return `${secondsAgo} seconds ago`; } else if (secondsAgo < 3600) { const minutesAgo = Math.floor(secondsAgo / 60); return `${minutesAgo} minute${minutesAgo > 1 ? 's' : ''} ago`; } else if (secondsAgo < 86400) { const hoursAgo = Math.floor(secondsAgo / 3600); return `${hoursAgo} hour${hoursAgo > 1 ? 's' : ''} ago`; } else { const daysAgo = Math.floor(secondsAgo / 86400); return `${daysAgo} day${daysAgo > 1 ? 's' : ''} ago`; } } function shortenAddress(address) { const string = String(address); if (string.length <= 20) return string; return `${string.substr(0, 10)}...${string.substr(-7)}`; } function urlHostName(url) { try { const domain = new URL(url); return domain?.hostname ?? null; } catch (e) { return null; } } function holderPercentage(supply, quantity) { return Math.min(Big(quantity).div(Big(supply)).mul(Big(100)).toFixed(2), 100); } function isAction(type) { const actions = [ 'DEPLOY_CONTRACT', 'TRANSFER', 'STAKE', 'ADD_KEY', 'DELETE_KEY', 'DELETE_ACCOUNT', ]; return actions.includes(type.toUpperCase()); } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function formatWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } /* END_INCLUDE: "includes/libs.jsx" */ /** * @interface Props * @param {string} [className] - The CSS class name(s) for styling purposes. */ const ArrowDown = (props) => { return ( <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width={24} height={24} {...props} > <path fill="none" d="M0 0h24v24H0z" /> <path d="M12 13.172l4.95-4.95 1.414 1.414L12 16 5.636 9.636 7.05 8.222z" /> </svg> ); }; /* INCLUDE: "includes/formats.jsx" */ function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function dollarNonCentFormat(number) { const bigNumber = new Big(number).toFixed(0); // Extract integer part and format with commas const integerPart = bigNumber.toString(); const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ','); return formattedInteger; } function weight(number) { let sizeInBytes = new Big(number); if (sizeInBytes.lt(0)) { throw new Error('Invalid input. Please provide a non-negative number.'); } const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; let suffixIndex = 0; while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) { sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes suffixIndex++; } const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex]; return formattedSize; } function convertToUTC(timestamp, hour) { const date = new Date(timestamp); // Get UTC date components const utcYear = date.getUTCFullYear(); const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based const utcDay = ('0' + date.getUTCDate()).slice(-2); const utcHours = ('0' + date.getUTCHours()).slice(-2); const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2); const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2); // Array of month abbreviations const monthAbbreviations = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; const monthIndex = Number(utcMonth) - 1; // Format the date as required (Jul-25-2022 16:25:37) let formattedDate = monthAbbreviations[monthIndex] + '-' + utcDay + '-' + utcYear + ' ' + utcHours + ':' + utcMinutes + ':' + utcSeconds; if (hour) { // Convert hours to 12-hour format let hour12 = parseInt(utcHours); const ampm = hour12 >= 12 ? 'PM' : 'AM'; hour12 = hour12 % 12 || 12; // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM) formattedDate = monthAbbreviations[monthIndex] + '-' + utcDay + '-' + utcYear + ' ' + hour12 + ':' + utcMinutes + ':' + utcSeconds + ' ' + ampm; } return formattedDate; } function getTimeAgoString(timestamp) { const currentUTC = Date.now(); const date = new Date(timestamp); const seconds = Math.floor((currentUTC - date.getTime()) / 1000); const intervals = { year: seconds / (60 * 60 * 24 * 365), month: seconds / (60 * 60 * 24 * 30), week: seconds / (60 * 60 * 24 * 7), day: seconds / (60 * 60 * 24), hour: seconds / (60 * 60), minute: seconds / 60, }; if (intervals.year >= 1) { return ( Math.floor(intervals.year) + ' year' + (Math.floor(intervals.year) > 1 ? 's' : '') + ' ago' ); } else if (intervals.month >= 1) { return ( Math.floor(intervals.month) + ' month' + (Math.floor(intervals.month) > 1 ? 's' : '') + ' ago' ); } else if (intervals.day >= 1) { return ( Math.floor(intervals.day) + ' day' + (Math.floor(intervals.day) > 1 ? 's' : '') + ' ago' ); } else if (intervals.hour >= 1) { return ( Math.floor(intervals.hour) + ' hour' + (Math.floor(intervals.hour) > 1 ? 's' : '') + ' ago' ); } else if (intervals.minute >= 1) { return ( Math.floor(intervals.minute) + ' minute' + (Math.floor(intervals.minute) > 1 ? 's' : '') + ' ago' ); } else { return 'a few seconds ago'; } } function formatWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } function formatTimestampToString(timestamp) { const date = new Date(timestamp); // Format the date to 'YYYY-MM-DD HH:mm:ss' format const formattedDate = date.toISOString().replace('T', ' ').split('.')[0]; return formattedDate; } function convertToMetricPrefix(numberStr) { const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes let result = new Big(numberStr); let count = 0; while (result.abs().gte('1e3') && count < prefixes.length - 1) { result = result.div(1e3); count++; } // Check if the value is an integer or has more than two digits before the decimal point if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) { result = result.toFixed(2); } else { result = result.toFixed(0); } return result.toString() + ' ' + prefixes[count]; } function formatNumber(value) { let bigValue = new Big(value); const suffixes = ['', 'K', 'M', 'B', 'T']; let suffixIndex = 0; while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) { bigValue = bigValue.div(1000); suffixIndex++; } const formattedValue = bigValue.toFixed(1).replace(/\.0+$/, ''); return `${formattedValue} ${suffixes[suffixIndex]}`; } function gasFee(gas, price) { const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true); return `${near}`; } function currency(number) { let absNumber = new Big(number).abs(); const suffixes = ['', 'K', 'M', 'B', 'T', 'Q']; let suffixIndex = 0; while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) { absNumber = absNumber.div(1000); // Divide using big.js's div method suffixIndex++; } const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places return ( (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex] ); } function formatDate(dateString) { const inputDate = new Date(dateString); const days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', ]; const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', ]; const dayOfWeek = days[inputDate.getDay()]; const month = months[inputDate.getMonth()]; const day = inputDate.getDate(); const year = inputDate.getFullYear(); const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year; return formattedDate; } function formatCustomDate(inputDate) { var date = new Date(inputDate); // Array of month names var monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; // Get month and day var month = monthNames[date.getMonth()]; var day = date.getDate(); // Create formatted date string in "MMM DD" format var formattedDate = month + ' ' + (day < 10 ? '0' + day : day); return formattedDate; } function shortenHex(address) { return `${address && address.substr(0, 6)}...${address.substr(-4)}`; } function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } function shortenToken(token) { return truncateString(token, 14, ''); } function shortenTokenSymbol(token) { return truncateString(token, 5, ''); } function gasPercentage(gasUsed, gasAttached) { if (!gasAttached) return 'N/A'; const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2); return `${formattedNumber}%`; } function serialNumber(index, page, perPage) { return index + 1 + (page - 1) * perPage; } function capitalizeWords(str) { const words = str.split('_'); const capitalizedWords = words.map( (word) => word.charAt(0).toUpperCase() + word.slice(1), ); const result = capitalizedWords.join(' '); return result; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function dollarNonCentFormat(number) { const bigNumber = new Big(number).toFixed(0); // Extract integer part and format with commas const integerPart = bigNumber.toString(); const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ','); return formattedInteger; } function weight(number) { let sizeInBytes = new Big(number); if (sizeInBytes.lt(0)) { throw new Error('Invalid input. Please provide a non-negative number.'); } const suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; let suffixIndex = 0; while (sizeInBytes.gte(1000) && suffixIndex < suffixes.length - 1) { sizeInBytes = sizeInBytes.div(1000); // Assign the result back to sizeInBytes suffixIndex++; } const formattedSize = sizeInBytes.toFixed(2) + ' ' + suffixes[suffixIndex]; return formattedSize; } function convertToUTC(timestamp, hour) { const date = new Date(timestamp); // Get UTC date components const utcYear = date.getUTCFullYear(); const utcMonth = ('0' + (date.getUTCMonth() + 1)).slice(-2); // Adding 1 because months are zero-based const utcDay = ('0' + date.getUTCDate()).slice(-2); const utcHours = ('0' + date.getUTCHours()).slice(-2); const utcMinutes = ('0' + date.getUTCMinutes()).slice(-2); const utcSeconds = ('0' + date.getUTCSeconds()).slice(-2); // Array of month abbreviations const monthAbbreviations = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; const monthIndex = Number(utcMonth) - 1; // Format the date as required (Jul-25-2022 16:25:37) let formattedDate = monthAbbreviations[monthIndex] + '-' + utcDay + '-' + utcYear + ' ' + utcHours + ':' + utcMinutes + ':' + utcSeconds; if (hour) { // Convert hours to 12-hour format let hour12 = parseInt(utcHours); const ampm = hour12 >= 12 ? 'PM' : 'AM'; hour12 = hour12 % 12 || 12; // Add AM/PM to the formatted date (Jul-25-2022 4:25:37 PM) formattedDate = monthAbbreviations[monthIndex] + '-' + utcDay + '-' + utcYear + ' ' + hour12 + ':' + utcMinutes + ':' + utcSeconds + ' ' + ampm; } return formattedDate; } function getTimeAgoString(timestamp) { const currentUTC = Date.now(); const date = new Date(timestamp); const seconds = Math.floor((currentUTC - date.getTime()) / 1000); const intervals = { year: seconds / (60 * 60 * 24 * 365), month: seconds / (60 * 60 * 24 * 30), week: seconds / (60 * 60 * 24 * 7), day: seconds / (60 * 60 * 24), hour: seconds / (60 * 60), minute: seconds / 60, }; if (intervals.year >= 1) { return ( Math.floor(intervals.year) + ' year' + (Math.floor(intervals.year) > 1 ? 's' : '') + ' ago' ); } else if (intervals.month >= 1) { return ( Math.floor(intervals.month) + ' month' + (Math.floor(intervals.month) > 1 ? 's' : '') + ' ago' ); } else if (intervals.day >= 1) { return ( Math.floor(intervals.day) + ' day' + (Math.floor(intervals.day) > 1 ? 's' : '') + ' ago' ); } else if (intervals.hour >= 1) { return ( Math.floor(intervals.hour) + ' hour' + (Math.floor(intervals.hour) > 1 ? 's' : '') + ' ago' ); } else if (intervals.minute >= 1) { return ( Math.floor(intervals.minute) + ' minute' + (Math.floor(intervals.minute) > 1 ? 's' : '') + ' ago' ); } else { return 'a few seconds ago'; } } function formatWithCommas(number) { return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } function formatTimestampToString(timestamp) { const date = new Date(timestamp); // Format the date to 'YYYY-MM-DD HH:mm:ss' format const formattedDate = date.toISOString().replace('T', ' ').split('.')[0]; return formattedDate; } function convertToMetricPrefix(numberStr) { const prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']; // Metric prefixes let result = new Big(numberStr); let count = 0; while (result.abs().gte('1e3') && count < prefixes.length - 1) { result = result.div(1e3); count++; } // Check if the value is an integer or has more than two digits before the decimal point if (result.abs().lt(1e2) && result.toFixed(2) !== result.toFixed(0)) { result = result.toFixed(2); } else { result = result.toFixed(0); } return result.toString() + ' ' + prefixes[count]; } function formatNumber(value) { let bigValue = new Big(value); const suffixes = ['', 'K', 'M', 'B', 'T']; let suffixIndex = 0; while (bigValue.gte(10000) && suffixIndex < suffixes.length - 1) { bigValue = bigValue.div(1000); suffixIndex++; } const formattedValue = bigValue.toFixed(1).replace(/\.0+$/, ''); return `${formattedValue} ${suffixes[suffixIndex]}`; } function gasFee(gas, price) { const near = yoctoToNear(Big(gas).mul(Big(price)).toString(), true); return `${near}`; } function currency(number) { let absNumber = new Big(number).abs(); const suffixes = ['', 'K', 'M', 'B', 'T', 'Q']; let suffixIndex = 0; while (absNumber.gte(1000) && suffixIndex < suffixes.length - 1) { absNumber = absNumber.div(1000); // Divide using big.js's div method suffixIndex++; } const formattedNumber = absNumber.toFixed(2); // Format with 2 decimal places return ( (number < '0' ? '-' : '') + formattedNumber + ' ' + suffixes[suffixIndex] ); } function formatDate(dateString) { const inputDate = new Date(dateString); const days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', ]; const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', ]; const dayOfWeek = days[inputDate.getDay()]; const month = months[inputDate.getMonth()]; const day = inputDate.getDate(); const year = inputDate.getFullYear(); const formattedDate = dayOfWeek + ', ' + month + ' ' + day + ', ' + year; return formattedDate; } function formatCustomDate(inputDate) { var date = new Date(inputDate); // Array of month names var monthNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; // Get month and day var month = monthNames[date.getMonth()]; var day = date.getDate(); // Create formatted date string in "MMM DD" format var formattedDate = month + ' ' + (day < 10 ? '0' + day : day); return formattedDate; } function shortenHex(address) { return `${address && address.substr(0, 6)}...${address.substr(-4)}`; } function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } function shortenToken(token) { return truncateString(token, 14, ''); } function shortenTokenSymbol(token) { return truncateString(token, 5, ''); } function gasPercentage(gasUsed, gasAttached) { if (!gasAttached) return 'N/A'; const formattedNumber = (Big(gasUsed).div(Big(gasAttached)) * 100).toFixed(2); return `${formattedNumber}%`; } function serialNumber(index, page, perPage) { return index + 1 + (page - 1) * perPage; } function capitalizeWords(str) { const words = str.split('_'); const capitalizedWords = words.map( (word) => word.charAt(0).toUpperCase() + word.slice(1), ); const result = capitalizedWords.join(' '); return result; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function truncateString(str, maxLength, suffix) { if (str.length <= maxLength) { return str; } return str.substring(0, maxLength) + suffix; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } /* END_INCLUDE: "includes/formats.jsx" */ const TokenHoldings = (props) => { const Loading = (props) => { return ( <div className={`bg-gray-200 h-5 rounded shadow-sm animate-pulse ${props.className}`} ></div> ); }; const nfts = props.data?.nfts || []; if (props.loading) { return <Loading className="h-full" wrapperClassName="flex w-full h-7" />; } if (!props.ft?.tokens?.length && !nfts?.length) { return ( <select className="appearance-none w-full h-8 text-xs px-2 outline-none rounded bg-white border"> <option>N/A</option> </select> ); } return ( <Select.Root> <Select.Trigger className="w-96 h-8 text-sm px-2 rounded border outline-none flex items-center justify-between cursor-pointer"> <span> $ {props.ft?.amount ? dollarFormat(props.ft?.amount) : props.ft?.amount ?? ''} <span className="bg-green-500 text-xs text-white rounded ml-2 px-1 p-1"> {(props.ft?.tokens?.length || 0) + (nfts?.length || 0)} </span> </span> <ArrowDown className="w-4 h-4 fill-current text-gray-500 pointer-events-none" /> </Select.Trigger> <Select.Content> <ScrollArea.Root className="w-96 h-72 overflow-hidden rounded-b-xl soft-shadow bg-white"> <ScrollArea.Viewport className="w-full h-full border z-50 pb-2"> <div className="max-h-60"> {props.ft?.tokens?.length > 0 && ( <> <div className="bg-gray-50 font-semibold px-3 py-2"> Tokens{' '} <span className="font-normal"> ({props.ft?.tokens?.length}) </span> </div> <div className="text-gray-600 text-xs divide-y outline-none"> {props.ft?.tokens?.map((token, index) => ( <div key={token?.contract}> <a href={`/token/${token?.contract}?a=${props.id}`} className="hover:no-underline" > <a className="flex justify-between items-center px-3 py-2 hover:bg-gray-100 truncate hover:no-underline"> <div key={index}> <div className="flex items-center"> <div className="flex mr-1"> <img src={ token?.ft_metas?.icon || `${props.appUrl}images/tokenplaceholder.svg` } alt={token.ft_metas?.name} className="w-4 h-4" /> </div> <span> {token?.ft_metas?.name ? truncateString( token?.ft_metas?.name, 15, '...', ) : ''} ({token?.ft_metas?.symbol}) </span> </div> <div className="text-gray-400 flex items-center mt-1"> {token?.rpcAmount ? localFormat(token?.rpcAmount) : token?.rpcAmount ?? ''} </div> </div> {token?.ft_metas?.price && ( <div className="text-right"> <div> $ {token?.amountUsd ? dollarFormat(token?.amountUsd) : token.amountUsd ?? ''} </div> <div className="text-gray-400"> @ {token?.ft_metas?.price ? Big(token?.ft_metas?.price).toString() : token?.ft_metas?.price ?? ''} </div> </div> )} </a> </a> </div> ))} </div> </> )} {nfts?.length > 0 && ( <> <div className="bg-gray-50 font-semibold px-3 py-2"> NFT Tokens{' '} <span className="font-normal">({nfts?.length})</span> </div> <div className="text-gray-600 text-xs divide-y outline-none"> {nfts.map((nft) => ( <div key={nft?.contract}> <a href={`/nft-token/${nft?.contract}?a=${props.id}`} className="hover:no-underline" > <a className="flex justify-between items-center px-3 py-2 hover:bg-gray-100 truncate hover:no-underline"> <div> <div className="flex items-center"> <div className="flex mr-1"> <img src={ nft?.nft_meta?.icon || `${props.appUrl}images/tokenplaceholder.svg` } alt={nft?.nft_meta?.name} className="w-4 h-4" /> </div> <span> {nft?.nft_meta?.name ? truncateString( nft?.nft_meta?.name, 15, '...', ) : nft?.nft_meta?.name ?? ''} ({nft?.nft_meta?.symbol}) </span> </div> <div className="text-gray-400 flex items-center mt-1"> {nft?.quantity ? localFormat(nft?.quantity) : nft?.quantity ?? ''} </div> </div> </a> </a> </div> ))} </div> </> )} </div> </ScrollArea.Viewport> <ScrollArea.Scrollbar className="flex select-none touch-none p-0.5 bg-neargray-25 transition-colors duration-[160ms] ease-out hover:bg-neargray-25 data-[orientation=vertical]:w-2.5 data-[orientation=horizontal]:flex-col data-[orientation=horizontal]:h-2.5" orientation="vertical" > <ScrollArea.Thumb className="flex-1 bg-neargray-50 rounded-[10px] relative before:content-[''] before:absolute before:top-1/2 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2 before:w-full before:h-full before:min-w-[44px] before:min-h-[44px]" /> </ScrollArea.Scrollbar> <ScrollArea.Scrollbar className="flex select-none touch-none p-0.5 bg-neargray-25 transition-colors duration-[160ms] ease-out hover:bg-neargray-25 data-[orientation=vertical]:w-2.5 data-[orientation=horizontal]:flex-col data-[orientation=horizontal]:h-2.5" orientation="horizontal" > <ScrollArea.Thumb className="flex-1 bg-neargray-50 rounded-[10px] relative before:content-[''] before:absolute before:top-1/2 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2 before:w-full before:h-full before:min-w-[44px] before:min-h-[44px]" /> </ScrollArea.Scrollbar> <ScrollArea.Corner className="bg-neargray-50" /> </ScrollArea.Root> </Select.Content> </Select.Root> ); };/* END_INCLUDE COMPONENT: "includes/Common/TokenHoldings.jsx" */ /* INCLUDE: "includes/near.jsx" */ function encodeArgs(args) { if (!args || typeof args === 'undefined') return ''; return Buffer.from(JSON.stringify(args)).toString('base64'); } function decodeArgs(args) { if (!args || typeof args === 'undefined') return {}; const encodedString = Buffer.from(args).toString('base64'); return JSON.parse(Buffer.from(encodedString, 'base64').toString()); } function txnMethod( actions, t, ) { const count = actions?.length || 0; if (!count) return t ? t('txns:unknownType') : 'Unknown'; if (count > 1) return t ? t('txns:batchTxns') : 'Batch Transaction'; const action = actions[0]; if (action.action === 'FUNCTION_CALL') { return action.method; } return action.action; } function gasPrice(yacto) { const near = Big(yoctoToNear(yacto, false)).mul(Big(10).pow(12)).toString(); return `${localFormat(near)} Ⓝ / Tgas`; } function tokenAmount(amount, decimal, format) { if (amount === undefined || amount === null) return 'N/A'; const near = Big(amount).div(Big(10).pow(decimal)); const formattedValue = format ? near.toFixed(8).replace(/\.?0+$/, '') : near.toFixed(Big(decimal, 10)).replace(/\.?0+$/, ''); return formattedValue; } function tokenPercentage( supply, amount, decimal, ) { const nearAmount = Big(amount).div(Big(10).pow(decimal)); const nearSupply = Big(supply); return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2); } function price(amount, decimal, price) { const nearAmount = Big(amount).div(Big(10).pow(decimal)); return dollarFormat(nearAmount.mul(Big(price || 0)).toString()); } function mapRpcActionToAction(action) { if (action === 'CreateAccount') { return { action_kind: 'CreateAccount', args: {}, }; } if (typeof action === 'object') { const kind = Object.keys(action)[0]; return { action_kind: kind, args: action[kind], }; } return null; } function valueFromObj(obj) { const keys = Object.keys(obj); for (let i = 0; i < keys.length; i++) { const key = keys[i]; const value = obj[key]; if (typeof value === 'string') { return value; } if (typeof value === 'object') { const nestedValue = valueFromObj(value ); if (nestedValue) { return nestedValue; } } } return undefined; } function txnLogs(txn) { let txLogs = []; const outcomes = txn?.receipts_outcome || []; for (let i = 0; i < outcomes.length; i++) { const outcome = outcomes[i]; let logs = outcome?.outcome?.logs || []; if (logs.length > 0) { const mappedLogs = logs.map((log) => ({ contract: outcome?.outcome?.executor_id || '', logs: log, })); txLogs = [...txLogs, ...mappedLogs]; } } return txLogs; } function txnActions(txn) { const txActions = []; const receipts = txn?.receipts || []; for (let i = 0; i < receipts.length; i++) { const receipt = receipts[i]; const from = receipt?.predecessor_id; const to = receipt?.receiver_id; if (Array.isArray(receipt?.receipt)) { const actions = receipt.receipt; for (let j = 0; j < actions.length; j++) { const action = actions[j]; txActions.push({ from, to, ...action }); } } else { const actions = receipt?.receipt?.Action?.actions || []; for (let j = 0; j < actions.length; j++) { const action = mapRpcActionToAction(actions[j]); txActions.push({ from, to, ...action }); } } } return txActions.filter( (action) => action.action_kind !== 'FunctionCall' && action.from !== 'system', ); } function txnErrorMessage(txn) { const kind = txn?.status?.Failure?.ActionError?.kind; if (typeof kind === 'string') return kind; if (typeof kind === 'object') { return valueFromObj(kind); } return null; } function formatLine(line, offset, format) { let result = `${offset.toString(16).padStart(8, '0')} `; const hexValues = line.match(/[0-9a-fA-F]{2}/g) || []; hexValues.forEach((byte, index) => { if (index > 0 && index % 4 === 0) { result += ' '; } result += byte.toUpperCase().padEnd(2, ' ') + ' '; }); if (format === 'twos') { result = result.replace(/(.{4})/g, '$1 '); } else if (format === 'default') { result += ` ${String.fromCharCode( ...hexValues.map((b) => parseInt(b, 16)), )}`; } return result.trimEnd(); } function collectNestedReceiptWithOutcomeOld( idOrHash, parsedMap, ) { const parsedElement = parsedMap.get(idOrHash); if (!parsedElement) { return { id: idOrHash }; } const { receiptIds, ...restOutcome } = parsedElement.outcome; return { ...parsedElement, outcome: { ...restOutcome, nestedReceipts: receiptIds.map((id) => collectNestedReceiptWithOutcomeOld(id, parsedMap), ), }, }; } function parseReceipt( receipt, outcome, transaction, ) { if (!receipt) { return { id: outcome.id, predecessorId: transaction.signer_id, receiverId: transaction.receiver_id, actions: transaction.actions.map(mapRpcActionToAction1), }; } return { id: receipt.receipt_id, predecessorId: receipt.predecessor_id, receiverId: receipt.receiver_id, actions: 'Action' in receipt.receipt ? receipt.receipt.Action.actions.map(mapRpcActionToAction1) : [], }; } function mapNonDelegateRpcActionToAction( rpcAction, ) { if (rpcAction === 'CreateAccount') { return { kind: 'createAccount', args: {}, }; } if ('DeployContract' in rpcAction) { return { kind: 'deployContract', args: rpcAction.DeployContract, }; } if ('FunctionCall' in rpcAction) { return { kind: 'functionCall', args: { methodName: rpcAction.FunctionCall.method_name, args: rpcAction.FunctionCall.args, deposit: rpcAction.FunctionCall.deposit, gas: rpcAction.FunctionCall.gas, }, }; } if ('Transfer' in rpcAction) { return { kind: 'transfer', args: rpcAction.Transfer, }; } if ('Stake' in rpcAction) { return { kind: 'stake', args: { publicKey: rpcAction.Stake.public_key, stake: rpcAction.Stake.stake, }, }; } if ('AddKey' in rpcAction) { return { kind: 'addKey', args: { publicKey: rpcAction.AddKey.public_key, accessKey: { nonce: rpcAction.AddKey.access_key.nonce, permission: rpcAction.AddKey.access_key.permission === 'FullAccess' ? { type: 'fullAccess', } : { type: 'functionCall', contractId: rpcAction.AddKey.access_key.permission.FunctionCall .receiver_id, methodNames: rpcAction.AddKey.access_key.permission.FunctionCall .method_names, }, }, }, }; } if ('DeleteKey' in rpcAction) { return { kind: 'deleteKey', args: { publicKey: rpcAction.DeleteKey.public_key, }, }; } return { kind: 'deleteAccount', args: { beneficiaryId: rpcAction.DeleteAccount.beneficiary_id, }, }; } function mapRpcInvalidAccessKeyError(error) { const UNKNOWN_ERROR = { type: 'unknown' }; if (error === 'DepositWithFunctionCall') { return { type: 'depositWithFunctionCall', }; } if (error === 'RequiresFullAccess') { return { type: 'requiresFullAccess', }; } if ('AccessKeyNotFound' in error) { const { account_id, public_key } = error.AccessKeyNotFound; return { type: 'accessKeyNotFound', accountId: account_id, publicKey: public_key, }; } if ('ReceiverMismatch' in error) { const { ak_receiver, tx_receiver } = error.ReceiverMismatch; return { type: 'receiverMismatch', akReceiver: ak_receiver, transactionReceiver: tx_receiver, }; } if ('MethodNameMismatch' in error) { const { method_name } = error.MethodNameMismatch; return { type: 'methodNameMismatch', methodName: method_name, }; } if ('NotEnoughAllowance' in error) { const { account_id, allowance, cost, public_key } = error.NotEnoughAllowance; return { type: 'notEnoughAllowance', accountId: account_id, allowance: allowance, cost: cost, publicKey: public_key, }; } return UNKNOWN_ERROR; } function mapRpcCompilationError(error) { const UNKNOWN_ERROR = { type: 'unknown' }; if ('CodeDoesNotExist' in error) { return { type: 'codeDoesNotExist', accountId: error.CodeDoesNotExist.account_id, }; } if ('PrepareError' in error) { return { type: 'prepareError', }; } if ('WasmerCompileError' in error) { return { type: 'wasmerCompileError', msg: error.WasmerCompileError.msg, }; } if ('UnsupportedCompiler' in error) { return { type: 'unsupportedCompiler', msg: error.UnsupportedCompiler.msg, }; } return UNKNOWN_ERROR; } function mapRpcFunctionCallError(error) { const UNKNOWN_ERROR = { type: 'unknown' }; if ('CompilationError' in error) { return { type: 'compilationError', error: mapRpcCompilationError(error.CompilationError), }; } if ('LinkError' in error) { return { type: 'linkError', msg: error.LinkError.msg, }; } if ('MethodResolveError' in error) { return { type: 'methodResolveError', }; } if ('WasmTrap' in error) { return { type: 'wasmTrap', }; } if ('WasmUnknownError' in error) { return { type: 'wasmUnknownError', }; } if ('HostError' in error) { return { type: 'hostError', }; } if ('_EVMError' in error) { return { type: 'evmError', }; } if ('ExecutionError' in error) { return { type: 'executionError', error: error.ExecutionError, }; } return UNKNOWN_ERROR; } function mapRpcNewReceiptValidationError(error) { const UNKNOWN_ERROR = { type: 'unknown' }; if ('InvalidPredecessorId' in error) { return { type: 'invalidPredecessorId', accountId: error.InvalidPredecessorId.account_id, }; } if ('InvalidReceiverId' in error) { return { type: 'invalidReceiverId', accountId: error.InvalidReceiverId.account_id, }; } if ('InvalidSignerId' in error) { return { type: 'invalidSignerId', accountId: error.InvalidSignerId.account_id, }; } if ('InvalidDataReceiverId' in error) { return { type: 'invalidDataReceiverId', accountId: error.InvalidDataReceiverId.account_id, }; } if ('ReturnedValueLengthExceeded' in error) { return { type: 'returnedValueLengthExceeded', length: error.ReturnedValueLengthExceeded.length, limit: error.ReturnedValueLengthExceeded.limit, }; } if ('NumberInputDataDependenciesExceeded' in error) { return { type: 'numberInputDataDependenciesExceeded', numberOfInputDataDependencies: error.NumberInputDataDependenciesExceeded .number_of_input_data_dependencies, limit: error.NumberInputDataDependenciesExceeded.limit, }; } if ('ActionsValidation' in error) { return { type: 'actionsValidation', }; } return UNKNOWN_ERROR; } function mapRpcReceiptActionError(error) { const UNKNOWN_ERROR = { type: 'unknown' }; const { kind } = error; if (kind === 'DelegateActionExpired') { return { type: 'delegateActionExpired', }; } if (kind === 'DelegateActionInvalidSignature') { return { type: 'delegateActionInvalidSignature', }; } if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) { return { type: 'delegateActionSenderDoesNotMatchTxReceiver', receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id, senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id, }; } if ('DelegateActionAccessKeyError' in kind) { return { type: 'delegateActionAccessKeyError', error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError), }; } if ('DelegateActionInvalidNonce' in kind) { return { type: 'delegateActionInvalidNonce', akNonce: kind.DelegateActionInvalidNonce.ak_nonce, delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce, }; } if ('DelegateActionNonceTooLarge' in kind) { return { type: 'delegateActionNonceTooLarge', delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce, upperBound: kind.DelegateActionNonceTooLarge.upper_bound, }; } if ('AccountAlreadyExists' in kind) { return { type: 'accountAlreadyExists', accountId: kind.AccountAlreadyExists.account_id, }; } if ('AccountDoesNotExist' in kind) { return { type: 'accountDoesNotExist', accountId: kind.AccountDoesNotExist.account_id, }; } if ('CreateAccountOnlyByRegistrar' in kind) { return { type: 'createAccountOnlyByRegistrar', accountId: kind.CreateAccountOnlyByRegistrar.account_id, registrarAccountId: kind.CreateAccountOnlyByRegistrar.registrar_account_id, predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id, }; } if ('CreateAccountNotAllowed' in kind) { return { type: 'createAccountNotAllowed', accountId: kind.CreateAccountNotAllowed.account_id, predecessorId: kind.CreateAccountNotAllowed.predecessor_id, }; } if ('ActorNoPermission' in kind) { return { type: 'actorNoPermission', accountId: kind.ActorNoPermission.account_id, actorId: kind.ActorNoPermission.actor_id, }; } if ('DeleteKeyDoesNotExist' in kind) { return { type: 'deleteKeyDoesNotExist', accountId: kind.DeleteKeyDoesNotExist.account_id, publicKey: kind.DeleteKeyDoesNotExist.public_key, }; } if ('AddKeyAlreadyExists' in kind) { return { type: 'addKeyAlreadyExists', accountId: kind.AddKeyAlreadyExists.account_id, publicKey: kind.AddKeyAlreadyExists.public_key, }; } if ('DeleteAccountStaking' in kind) { return { type: 'deleteAccountStaking', accountId: kind.DeleteAccountStaking.account_id, }; } if ('LackBalanceForState' in kind) { return { type: 'lackBalanceForState', accountId: kind.LackBalanceForState.account_id, amount: kind.LackBalanceForState.amount, }; } if ('TriesToUnstake' in kind) { return { type: 'triesToUnstake', accountId: kind.TriesToUnstake.account_id, }; } if ('TriesToStake' in kind) { return { type: 'triesToStake', accountId: kind.TriesToStake.account_id, stake: kind.TriesToStake.stake, locked: kind.TriesToStake.locked, balance: kind.TriesToStake.balance, }; } if ('InsufficientStake' in kind) { return { type: 'insufficientStake', accountId: kind.InsufficientStake.account_id, stake: kind.InsufficientStake.stake, minimumStake: kind.InsufficientStake.minimum_stake, }; } if ('FunctionCallError' in kind) { return { type: 'functionCallError', error: mapRpcFunctionCallError(kind.FunctionCallError), }; } if ('NewReceiptValidationError' in kind) { return { type: 'newReceiptValidationError', error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError), }; } if ('OnlyImplicitAccountCreationAllowed' in kind) { return { type: 'onlyImplicitAccountCreationAllowed', accountId: kind.OnlyImplicitAccountCreationAllowed.account_id, }; } if ('DeleteAccountWithLargeState' in kind) { return { type: 'deleteAccountWithLargeState', accountId: kind.DeleteAccountWithLargeState.account_id, }; } return UNKNOWN_ERROR; } function mapRpcReceiptInvalidTxError(error) { const UNKNOWN_ERROR = { type: 'unknown' }; if ('InvalidAccessKeyError' in error) { return { type: 'invalidAccessKeyError', error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError), }; } if ('InvalidSignerId' in error) { return { type: 'invalidSignerId', signerId: error.InvalidSignerId.signer_id, }; } if ('SignerDoesNotExist' in error) { return { type: 'signerDoesNotExist', signerId: error.SignerDoesNotExist.signer_id, }; } if ('InvalidNonce' in error) { return { type: 'invalidNonce', transactionNonce: error.InvalidNonce.tx_nonce, akNonce: error.InvalidNonce.ak_nonce, }; } if ('NonceTooLarge' in error) { return { type: 'nonceTooLarge', transactionNonce: error.NonceTooLarge.tx_nonce, upperBound: error.NonceTooLarge.upper_bound, }; } if ('InvalidReceiverId' in error) { return { type: 'invalidReceiverId', receiverId: error.InvalidReceiverId.receiver_id, }; } if ('InvalidSignature' in error) { return { type: 'invalidSignature', }; } if ('NotEnoughBalance' in error) { return { type: 'notEnoughBalance', signerId: error.NotEnoughBalance.signer_id, balance: error.NotEnoughBalance.balance, cost: error.NotEnoughBalance.cost, }; } if ('LackBalanceForState' in error) { return { type: 'lackBalanceForState', signerId: error.LackBalanceForState.signer_id, amount: error.LackBalanceForState.amount, }; } if ('CostOverflow' in error) { return { type: 'costOverflow', }; } if ('InvalidChain' in error) { return { type: 'invalidChain', }; } if ('Expired' in error) { return { type: 'expired', }; } if ('ActionsValidation' in error) { return { type: 'actionsValidation', }; } if ('TransactionSizeExceeded' in error) { return { type: 'transactionSizeExceeded', size: error.TransactionSizeExceeded.size, limit: error.TransactionSizeExceeded.limit, }; } return UNKNOWN_ERROR; } function mapRpcReceiptError(error) { let UNKNOWN_ERROR = { type: 'unknown' }; if ('ActionError' in error) { return { type: 'action', error: mapRpcReceiptActionError(error.ActionError), }; } if ('InvalidTxError' in error) { return { type: 'transaction', error: mapRpcReceiptInvalidTxError(error.InvalidTxError), }; } return UNKNOWN_ERROR; } function mapRpcReceiptStatus(status) { if ('SuccessValue' in status) { return { type: 'successValue', value: status.SuccessValue }; } if ('SuccessReceiptId' in status) { return { type: 'successReceiptId', receiptId: status.SuccessReceiptId }; } if ('Failure' in status) { return { type: 'failure', error: mapRpcReceiptError(status.Failure) }; } return { type: 'unknown' }; } function mapRpcActionToAction1(rpcAction) { if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) { return { kind: 'delegateAction', args: { actions: rpcAction.Delegate.delegate_action.actions.map( (subaction, index) => ({ ...mapNonDelegateRpcActionToAction(subaction), delegateIndex: index, }), ), receiverId: rpcAction.Delegate.delegate_action.receiver_id, senderId: rpcAction.Delegate.delegate_action.sender_id, }, }; } return mapNonDelegateRpcActionToAction(rpcAction); } function parseOutcomeOld(outcome) { return { blockHash: outcome.block_hash, tokensBurnt: outcome.outcome.tokens_burnt, gasBurnt: outcome.outcome.gas_burnt, status: mapRpcReceiptStatus(outcome.outcome.status), logs: outcome.outcome.logs, receiptIds: outcome.outcome.receipt_ids, }; } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function decodeArgs(args) { if (!args || typeof args === 'undefined') return {}; const encodedString = Buffer.from(args).toString('base64'); return JSON.parse(Buffer.from(encodedString, 'base64').toString()); } function txnMethod( actions, t, ) { const count = actions?.length || 0; if (!count) return t ? t('txns:unknownType') : 'Unknown'; if (count > 1) return t ? t('txns:batchTxns') : 'Batch Transaction'; const action = actions[0]; if (action.action === 'FUNCTION_CALL') { return action.method; } return action.action; } function gasPrice(yacto) { const near = Big(yoctoToNear(yacto, false)).mul(Big(10).pow(12)).toString(); return `${localFormat(near)} Ⓝ / Tgas`; } function tokenAmount(amount, decimal, format) { if (amount === undefined || amount === null) return 'N/A'; const near = Big(amount).div(Big(10).pow(decimal)); const formattedValue = format ? near.toFixed(8).replace(/\.?0+$/, '') : near.toFixed(Big(decimal, 10)).replace(/\.?0+$/, ''); return formattedValue; } function tokenPercentage( supply, amount, decimal, ) { const nearAmount = Big(amount).div(Big(10).pow(decimal)); const nearSupply = Big(supply); return nearAmount.div(nearSupply).mul(Big(100)).toFixed(2); } function price(amount, decimal, price) { const nearAmount = Big(amount).div(Big(10).pow(decimal)); return dollarFormat(nearAmount.mul(Big(price || 0)).toString()); } function mapRpcActionToAction(action) { if (action === 'CreateAccount') { return { action_kind: 'CreateAccount', args: {}, }; } if (typeof action === 'object') { const kind = Object.keys(action)[0]; return { action_kind: kind, args: action[kind], }; } return null; } function valueFromObj(obj) { const keys = Object.keys(obj); for (let i = 0; i < keys.length; i++) { const key = keys[i]; const value = obj[key]; if (typeof value === 'string') { return value; } if (typeof value === 'object') { const nestedValue = valueFromObj(value ); if (nestedValue) { return nestedValue; } } } return undefined; } function txnLogs(txn) { let txLogs = []; const outcomes = txn?.receipts_outcome || []; for (let i = 0; i < outcomes.length; i++) { const outcome = outcomes[i]; let logs = outcome?.outcome?.logs || []; if (logs.length > 0) { const mappedLogs = logs.map((log) => ({ contract: outcome?.outcome?.executor_id || '', logs: log, })); txLogs = [...txLogs, ...mappedLogs]; } } return txLogs; } function txnActions(txn) { const txActions = []; const receipts = txn?.receipts || []; for (let i = 0; i < receipts.length; i++) { const receipt = receipts[i]; const from = receipt?.predecessor_id; const to = receipt?.receiver_id; if (Array.isArray(receipt?.receipt)) { const actions = receipt.receipt; for (let j = 0; j < actions.length; j++) { const action = actions[j]; txActions.push({ from, to, ...action }); } } else { const actions = receipt?.receipt?.Action?.actions || []; for (let j = 0; j < actions.length; j++) { const action = mapRpcActionToAction(actions[j]); txActions.push({ from, to, ...action }); } } } return txActions.filter( (action) => action.action_kind !== 'FunctionCall' && action.from !== 'system', ); } function txnErrorMessage(txn) { const kind = txn?.status?.Failure?.ActionError?.kind; if (typeof kind === 'string') return kind; if (typeof kind === 'object') { return valueFromObj(kind); } return null; } function formatLine(line, offset, format) { let result = `${offset.toString(16).padStart(8, '0')} `; const hexValues = line.match(/[0-9a-fA-F]{2}/g) || []; hexValues.forEach((byte, index) => { if (index > 0 && index % 4 === 0) { result += ' '; } result += byte.toUpperCase().padEnd(2, ' ') + ' '; }); if (format === 'twos') { result = result.replace(/(.{4})/g, '$1 '); } else if (format === 'default') { result += ` ${String.fromCharCode( ...hexValues.map((b) => parseInt(b, 16)), )}`; } return result.trimEnd(); } function collectNestedReceiptWithOutcomeOld( idOrHash, parsedMap, ) { const parsedElement = parsedMap.get(idOrHash); if (!parsedElement) { return { id: idOrHash }; } const { receiptIds, ...restOutcome } = parsedElement.outcome; return { ...parsedElement, outcome: { ...restOutcome, nestedReceipts: receiptIds.map((id) => collectNestedReceiptWithOutcomeOld(id, parsedMap), ), }, }; } function parseReceipt( receipt, outcome, transaction, ) { if (!receipt) { return { id: outcome.id, predecessorId: transaction.signer_id, receiverId: transaction.receiver_id, actions: transaction.actions.map(mapRpcActionToAction1), }; } return { id: receipt.receipt_id, predecessorId: receipt.predecessor_id, receiverId: receipt.receiver_id, actions: 'Action' in receipt.receipt ? receipt.receipt.Action.actions.map(mapRpcActionToAction1) : [], }; } function mapNonDelegateRpcActionToAction( rpcAction, ) { if (rpcAction === 'CreateAccount') { return { kind: 'createAccount', args: {}, }; } if ('DeployContract' in rpcAction) { return { kind: 'deployContract', args: rpcAction.DeployContract, }; } if ('FunctionCall' in rpcAction) { return { kind: 'functionCall', args: { methodName: rpcAction.FunctionCall.method_name, args: rpcAction.FunctionCall.args, deposit: rpcAction.FunctionCall.deposit, gas: rpcAction.FunctionCall.gas, }, }; } if ('Transfer' in rpcAction) { return { kind: 'transfer', args: rpcAction.Transfer, }; } if ('Stake' in rpcAction) { return { kind: 'stake', args: { publicKey: rpcAction.Stake.public_key, stake: rpcAction.Stake.stake, }, }; } if ('AddKey' in rpcAction) { return { kind: 'addKey', args: { publicKey: rpcAction.AddKey.public_key, accessKey: { nonce: rpcAction.AddKey.access_key.nonce, permission: rpcAction.AddKey.access_key.permission === 'FullAccess' ? { type: 'fullAccess', } : { type: 'functionCall', contractId: rpcAction.AddKey.access_key.permission.FunctionCall .receiver_id, methodNames: rpcAction.AddKey.access_key.permission.FunctionCall .method_names, }, }, }, }; } if ('DeleteKey' in rpcAction) { return { kind: 'deleteKey', args: { publicKey: rpcAction.DeleteKey.public_key, }, }; } return { kind: 'deleteAccount', args: { beneficiaryId: rpcAction.DeleteAccount.beneficiary_id, }, }; } function mapRpcInvalidAccessKeyError(error) { const UNKNOWN_ERROR = { type: 'unknown' }; if (error === 'DepositWithFunctionCall') { return { type: 'depositWithFunctionCall', }; } if (error === 'RequiresFullAccess') { return { type: 'requiresFullAccess', }; } if ('AccessKeyNotFound' in error) { const { account_id, public_key } = error.AccessKeyNotFound; return { type: 'accessKeyNotFound', accountId: account_id, publicKey: public_key, }; } if ('ReceiverMismatch' in error) { const { ak_receiver, tx_receiver } = error.ReceiverMismatch; return { type: 'receiverMismatch', akReceiver: ak_receiver, transactionReceiver: tx_receiver, }; } if ('MethodNameMismatch' in error) { const { method_name } = error.MethodNameMismatch; return { type: 'methodNameMismatch', methodName: method_name, }; } if ('NotEnoughAllowance' in error) { const { account_id, allowance, cost, public_key } = error.NotEnoughAllowance; return { type: 'notEnoughAllowance', accountId: account_id, allowance: allowance, cost: cost, publicKey: public_key, }; } return UNKNOWN_ERROR; } function mapRpcCompilationError(error) { const UNKNOWN_ERROR = { type: 'unknown' }; if ('CodeDoesNotExist' in error) { return { type: 'codeDoesNotExist', accountId: error.CodeDoesNotExist.account_id, }; } if ('PrepareError' in error) { return { type: 'prepareError', }; } if ('WasmerCompileError' in error) { return { type: 'wasmerCompileError', msg: error.WasmerCompileError.msg, }; } if ('UnsupportedCompiler' in error) { return { type: 'unsupportedCompiler', msg: error.UnsupportedCompiler.msg, }; } return UNKNOWN_ERROR; } function mapRpcFunctionCallError(error) { const UNKNOWN_ERROR = { type: 'unknown' }; if ('CompilationError' in error) { return { type: 'compilationError', error: mapRpcCompilationError(error.CompilationError), }; } if ('LinkError' in error) { return { type: 'linkError', msg: error.LinkError.msg, }; } if ('MethodResolveError' in error) { return { type: 'methodResolveError', }; } if ('WasmTrap' in error) { return { type: 'wasmTrap', }; } if ('WasmUnknownError' in error) { return { type: 'wasmUnknownError', }; } if ('HostError' in error) { return { type: 'hostError', }; } if ('_EVMError' in error) { return { type: 'evmError', }; } if ('ExecutionError' in error) { return { type: 'executionError', error: error.ExecutionError, }; } return UNKNOWN_ERROR; } function mapRpcNewReceiptValidationError(error) { const UNKNOWN_ERROR = { type: 'unknown' }; if ('InvalidPredecessorId' in error) { return { type: 'invalidPredecessorId', accountId: error.InvalidPredecessorId.account_id, }; } if ('InvalidReceiverId' in error) { return { type: 'invalidReceiverId', accountId: error.InvalidReceiverId.account_id, }; } if ('InvalidSignerId' in error) { return { type: 'invalidSignerId', accountId: error.InvalidSignerId.account_id, }; } if ('InvalidDataReceiverId' in error) { return { type: 'invalidDataReceiverId', accountId: error.InvalidDataReceiverId.account_id, }; } if ('ReturnedValueLengthExceeded' in error) { return { type: 'returnedValueLengthExceeded', length: error.ReturnedValueLengthExceeded.length, limit: error.ReturnedValueLengthExceeded.limit, }; } if ('NumberInputDataDependenciesExceeded' in error) { return { type: 'numberInputDataDependenciesExceeded', numberOfInputDataDependencies: error.NumberInputDataDependenciesExceeded .number_of_input_data_dependencies, limit: error.NumberInputDataDependenciesExceeded.limit, }; } if ('ActionsValidation' in error) { return { type: 'actionsValidation', }; } return UNKNOWN_ERROR; } function mapRpcReceiptActionError(error) { const UNKNOWN_ERROR = { type: 'unknown' }; const { kind } = error; if (kind === 'DelegateActionExpired') { return { type: 'delegateActionExpired', }; } if (kind === 'DelegateActionInvalidSignature') { return { type: 'delegateActionInvalidSignature', }; } if ('DelegateActionSenderDoesNotMatchTxReceiver' in kind) { return { type: 'delegateActionSenderDoesNotMatchTxReceiver', receiverId: kind.DelegateActionSenderDoesNotMatchTxReceiver.receiver_id, senderId: kind.DelegateActionSenderDoesNotMatchTxReceiver.sender_id, }; } if ('DelegateActionAccessKeyError' in kind) { return { type: 'delegateActionAccessKeyError', error: mapRpcInvalidAccessKeyError(kind.DelegateActionAccessKeyError), }; } if ('DelegateActionInvalidNonce' in kind) { return { type: 'delegateActionInvalidNonce', akNonce: kind.DelegateActionInvalidNonce.ak_nonce, delegateNonce: kind.DelegateActionInvalidNonce.delegate_nonce, }; } if ('DelegateActionNonceTooLarge' in kind) { return { type: 'delegateActionNonceTooLarge', delegateNonce: kind.DelegateActionNonceTooLarge.delegate_nonce, upperBound: kind.DelegateActionNonceTooLarge.upper_bound, }; } if ('AccountAlreadyExists' in kind) { return { type: 'accountAlreadyExists', accountId: kind.AccountAlreadyExists.account_id, }; } if ('AccountDoesNotExist' in kind) { return { type: 'accountDoesNotExist', accountId: kind.AccountDoesNotExist.account_id, }; } if ('CreateAccountOnlyByRegistrar' in kind) { return { type: 'createAccountOnlyByRegistrar', accountId: kind.CreateAccountOnlyByRegistrar.account_id, registrarAccountId: kind.CreateAccountOnlyByRegistrar.registrar_account_id, predecessorId: kind.CreateAccountOnlyByRegistrar.predecessor_id, }; } if ('CreateAccountNotAllowed' in kind) { return { type: 'createAccountNotAllowed', accountId: kind.CreateAccountNotAllowed.account_id, predecessorId: kind.CreateAccountNotAllowed.predecessor_id, }; } if ('ActorNoPermission' in kind) { return { type: 'actorNoPermission', accountId: kind.ActorNoPermission.account_id, actorId: kind.ActorNoPermission.actor_id, }; } if ('DeleteKeyDoesNotExist' in kind) { return { type: 'deleteKeyDoesNotExist', accountId: kind.DeleteKeyDoesNotExist.account_id, publicKey: kind.DeleteKeyDoesNotExist.public_key, }; } if ('AddKeyAlreadyExists' in kind) { return { type: 'addKeyAlreadyExists', accountId: kind.AddKeyAlreadyExists.account_id, publicKey: kind.AddKeyAlreadyExists.public_key, }; } if ('DeleteAccountStaking' in kind) { return { type: 'deleteAccountStaking', accountId: kind.DeleteAccountStaking.account_id, }; } if ('LackBalanceForState' in kind) { return { type: 'lackBalanceForState', accountId: kind.LackBalanceForState.account_id, amount: kind.LackBalanceForState.amount, }; } if ('TriesToUnstake' in kind) { return { type: 'triesToUnstake', accountId: kind.TriesToUnstake.account_id, }; } if ('TriesToStake' in kind) { return { type: 'triesToStake', accountId: kind.TriesToStake.account_id, stake: kind.TriesToStake.stake, locked: kind.TriesToStake.locked, balance: kind.TriesToStake.balance, }; } if ('InsufficientStake' in kind) { return { type: 'insufficientStake', accountId: kind.InsufficientStake.account_id, stake: kind.InsufficientStake.stake, minimumStake: kind.InsufficientStake.minimum_stake, }; } if ('FunctionCallError' in kind) { return { type: 'functionCallError', error: mapRpcFunctionCallError(kind.FunctionCallError), }; } if ('NewReceiptValidationError' in kind) { return { type: 'newReceiptValidationError', error: mapRpcNewReceiptValidationError(kind.NewReceiptValidationError), }; } if ('OnlyImplicitAccountCreationAllowed' in kind) { return { type: 'onlyImplicitAccountCreationAllowed', accountId: kind.OnlyImplicitAccountCreationAllowed.account_id, }; } if ('DeleteAccountWithLargeState' in kind) { return { type: 'deleteAccountWithLargeState', accountId: kind.DeleteAccountWithLargeState.account_id, }; } return UNKNOWN_ERROR; } function mapRpcReceiptInvalidTxError(error) { const UNKNOWN_ERROR = { type: 'unknown' }; if ('InvalidAccessKeyError' in error) { return { type: 'invalidAccessKeyError', error: mapRpcInvalidAccessKeyError(error.InvalidAccessKeyError), }; } if ('InvalidSignerId' in error) { return { type: 'invalidSignerId', signerId: error.InvalidSignerId.signer_id, }; } if ('SignerDoesNotExist' in error) { return { type: 'signerDoesNotExist', signerId: error.SignerDoesNotExist.signer_id, }; } if ('InvalidNonce' in error) { return { type: 'invalidNonce', transactionNonce: error.InvalidNonce.tx_nonce, akNonce: error.InvalidNonce.ak_nonce, }; } if ('NonceTooLarge' in error) { return { type: 'nonceTooLarge', transactionNonce: error.NonceTooLarge.tx_nonce, upperBound: error.NonceTooLarge.upper_bound, }; } if ('InvalidReceiverId' in error) { return { type: 'invalidReceiverId', receiverId: error.InvalidReceiverId.receiver_id, }; } if ('InvalidSignature' in error) { return { type: 'invalidSignature', }; } if ('NotEnoughBalance' in error) { return { type: 'notEnoughBalance', signerId: error.NotEnoughBalance.signer_id, balance: error.NotEnoughBalance.balance, cost: error.NotEnoughBalance.cost, }; } if ('LackBalanceForState' in error) { return { type: 'lackBalanceForState', signerId: error.LackBalanceForState.signer_id, amount: error.LackBalanceForState.amount, }; } if ('CostOverflow' in error) { return { type: 'costOverflow', }; } if ('InvalidChain' in error) { return { type: 'invalidChain', }; } if ('Expired' in error) { return { type: 'expired', }; } if ('ActionsValidation' in error) { return { type: 'actionsValidation', }; } if ('TransactionSizeExceeded' in error) { return { type: 'transactionSizeExceeded', size: error.TransactionSizeExceeded.size, limit: error.TransactionSizeExceeded.limit, }; } return UNKNOWN_ERROR; } function mapRpcReceiptError(error) { let UNKNOWN_ERROR = { type: 'unknown' }; if ('ActionError' in error) { return { type: 'action', error: mapRpcReceiptActionError(error.ActionError), }; } if ('InvalidTxError' in error) { return { type: 'transaction', error: mapRpcReceiptInvalidTxError(error.InvalidTxError), }; } return UNKNOWN_ERROR; } function mapRpcReceiptStatus(status) { if ('SuccessValue' in status) { return { type: 'successValue', value: status.SuccessValue }; } if ('SuccessReceiptId' in status) { return { type: 'successReceiptId', receiptId: status.SuccessReceiptId }; } if ('Failure' in status) { return { type: 'failure', error: mapRpcReceiptError(status.Failure) }; } return { type: 'unknown' }; } function mapRpcActionToAction1(rpcAction) { if (typeof rpcAction === 'object' && 'Delegate' in rpcAction) { return { kind: 'delegateAction', args: { actions: rpcAction.Delegate.delegate_action.actions.map( (subaction, index) => ({ ...mapNonDelegateRpcActionToAction(subaction), delegateIndex: index, }), ), receiverId: rpcAction.Delegate.delegate_action.receiver_id, senderId: rpcAction.Delegate.delegate_action.sender_id, }, }; } return mapNonDelegateRpcActionToAction(rpcAction); } function parseOutcomeOld(outcome) { return { blockHash: outcome.block_hash, tokensBurnt: outcome.outcome.tokens_burnt, gasBurnt: outcome.outcome.gas_burnt, status: mapRpcReceiptStatus(outcome.outcome.status), logs: outcome.outcome.logs, receiptIds: outcome.outcome.receipt_ids, }; } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function yoctoToNear(yocto, format) { const YOCTO_PER_NEAR = Big(10).pow(24).toString(); const near = Big(yocto).div(YOCTO_PER_NEAR).toString(); return format ? localFormat(near) : near; } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } function dollarFormat(number) { const bigNumber = new Big(number); // Format to two decimal places without thousands separator const formattedNumber = bigNumber.toFixed(2); // Add comma as a thousands separator const parts = formattedNumber.split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const dollarFormattedNumber = `${parts.join('.')}`; return dollarFormattedNumber; } function localFormat(number) { const bigNumber = Big(number); const formattedNumber = bigNumber .toFixed(5) .replace(/(\d)(?=(\d{3})+\.)/g, '$1,'); // Add commas before the decimal point return formattedNumber.replace(/\.?0*$/, ''); // Remove trailing zeros and the dot } /* END_INCLUDE: "includes/near.jsx" */ /* INCLUDE COMPONENT: "includes/Common/Skeleton.jsx" */ /** * @interface Props * @param {string} [className] - The CSS class name(s) for styling purposes. */ const Skeleton = (props) => { return ( <div className={`bg-gray-200 rounded shadow-sm animate-pulse ${props.className}`} ></div> ); };/* END_INCLUDE COMPONENT: "includes/Common/Skeleton.jsx" */ const tabs = [ 'Transactions', 'Token Txns', 'NFT Token Txns', 'Access Keys', 'Contract', 'Comments', ]; function MainComponent({ network, t, id }) { const [loading, setLoading] = useState(false); const [statsData, setStatsData] = useState({} ); const [pageTab, setPageTab] = useState('Transactions'); const [filters, setFilters] = useState({}); const [accountData, setAccountData] = useState( {} , ); const [deploymentData, setDeploymentData] = useState( {} , ); const [tokenData, setTokenData] = useState({} ); const [inventoryData, setInventoryData] = useState( {} , ); const [contract, setContract] = useState({} ); const [ft, setFT] = useState({} ); const [code, setCode] = useState({} ); const [key, setKey] = useState({} ); const config = getConfig(network); const onTab = (index) => { setPageTab(tabs[index]); onFilterClear(''); }; useEffect(() => { function fetchStatsData() { asyncFetch(`${config?.backendUrl}stats`, { method: 'GET', headers: { 'Content-Type': 'application/json', }, }) .then( (data ) => { const statsResp = data?.body?.stats?.[0]; setStatsData({ near_price: statsResp.near_price }); }, ) .catch(() => {}); } function fetchAccountData() { asyncFetch(`${config?.backendUrl}account/${id}`, { method: 'GET', headers: { 'Content-Type': 'application/json', }, }) .then( (data ) => { const accountResp = data?.body?.account?.[0]; setAccountData({ account_id: accountResp.account_id, amount: accountResp.amount, code_hash: accountResp.code_hash, created: accountResp.created, deleted: accountResp.deleted, locked: accountResp.locked, storage_usage: accountResp.storage_usage, }); }, ) .catch(() => {}); } function fetchContractData() { asyncFetch(`${config?.backendUrl}account/${id}/contract/deployments`, { method: 'GET', headers: { 'Content-Type': 'application/json', }, }) .then( (data ) => { const depResp = data?.body?.deployments?.[0]; setDeploymentData({ block_timestamp: depResp.block_timestamp, receipt_predecessor_account_id: depResp.receipt_predecessor_account_id, transaction_hash: depResp.transaction_hash, }); }, ) .catch(() => {}); } function fetchTokenData() { asyncFetch(`${config?.backendUrl}fts/${id}`, { method: 'GET', headers: { 'Content-Type': 'application/json', }, }) .then( (data ) => { const tokenResp = data?.body?.contracts?.[0]; setTokenData({ name: tokenResp.name, icon: tokenResp.icon, symbol: tokenResp.symbol, price: tokenResp.price, website: tokenResp.website, }); }, ) .catch(() => {}); } function fetchInventoryData() { asyncFetch(`${config?.backendUrl}account/${id}/inventory`, { method: 'GET', headers: { 'Content-Type': 'application/json', }, }) .then( (data ) => { const response = data?.body?.inventory; setInventoryData({ fts: response.fts, nfts: response.nfts, }); }, ) .catch(() => {}); } fetchStatsData(); fetchAccountData(); fetchContractData(); fetchTokenData(); fetchInventoryData(); }, [config?.backendUrl, id]); useEffect(() => { function ftBalanceOf(contracts, account_id) { return asyncFetch(`${config?.rpcUrl}`, { method: 'POST', body: JSON.stringify({ jsonrpc: '2.0', id: 'dontcare', method: 'query', params: { request_type: 'call_function', finality: 'final', account_id: contracts, method_name: 'ft_balance_of', args_base64: encodeArgs({ account_id }), }, }), headers: { 'Content-Type': 'application/json', }, }) .then( (res ) => { return res; }, ) .then( (data ) => { const resp = data?.body?.result; return decodeArgs(resp.result); }, ) .catch(() => {}); } function loadBalances() { const fts = inventoryData.fts; if (!fts?.length) { if (fts?.length === 0) setLoading(false); return; } let total = Big(0); const tokens = []; const pricedTokens = []; Promise.all( fts.map((ft) => { return ftBalanceOf(ft.contract, id).then((rslt) => { return { ...ft, amount: rslt }; }); }), ).then((results) => { results.forEach((rslt) => { const ftrslt = rslt; const amount = rslt?.amount ? rslt?.amount : ''; let sum = Big(0); let rpcAmount = Big(0); if (amount) { rpcAmount = ftrslt.ft_metas?.decimals ? Big(amount).div(Big(10).pow(ftrslt.ft_metas?.decimals)) : 0; } if (ftrslt.ft_metas?.price) { sum = rpcAmount.mul(Big(ftrslt.ft_metas?.price)); total = total.add(sum); return pricedTokens.push({ ...ftrslt, amountUsd: sum.toString(), rpcAmount: rpcAmount.toString(), }); } return tokens.push({ ...ftrslt, amountUsd: sum.toString(), rpcAmount: rpcAmount.toString(), }); }); tokens.sort((a, b) => { const first = Big(a.rpcAmount); const second = Big(b.rpcAmount); if (first.lt(second)) return 1; if (first.gt(second)) return -1; return 0; }); pricedTokens.sort((a, b) => { const first = Big(a.amountUsd); const second = Big(b.amountUsd); if (first.lt(second)) return 1; if (first.gt(second)) return -1; return 0; }); setFT({ amount: total.toString(), tokens: [...pricedTokens, ...tokens], }); setLoading(false); }); } loadBalances(); }, [inventoryData?.fts, id, config?.rpcUrl]); useEffect(() => { function contractCode(address) { asyncFetch(`${config?.rpcUrl}`, { method: 'POST', body: JSON.stringify({ jsonrpc: '2.0', id: 'dontcare', method: 'query', params: { request_type: 'view_code', finality: 'final', account_id: address, prefix_base64: '', }, }), headers: { 'Content-Type': 'application/json', }, }) .then( (res ) => { const resp = res?.body?.result; setCode({ block_hash: resp.block_hash, block_height: resp.block_height, code_base64: resp.code_base64, hash: resp.hash, }); }, ) .catch(() => {}); } function viewAccessKeys(address) { asyncFetch(`${config?.rpcUrl}`, { method: 'POST', body: JSON.stringify({ jsonrpc: '2.0', id: 'dontcare', method: 'query', params: { request_type: 'view_access_key_list', finality: 'final', account_id: address, }, }), headers: { 'Content-Type': 'application/json', }, }) .then( (res ) => { const resp = res?.body?.result; setKey({ block_hash: resp.block_hash, block_height: resp.block_height, keys: resp.keys, hash: resp.hash, }); }, ) .catch(() => {}); } function loadSchema() { if (!id) return; Promise.all([contractCode(id), viewAccessKeys(id)]); } loadSchema(); }, [id, config?.rpcUrl]); if (code?.code_base64) { const locked = (key.keys || []).every( (key ) => key.access_key.permission !== 'FullAccess', ); setContract({ ...code, locked }); } const handleFilter = (name, value) => { const updatedFilters = { ...filters, [name]: value }; setFilters(updatedFilters); }; const onFilterClear = (name) => { let updatedFilters = { ...filters }; if (updatedFilters.hasOwnProperty(name)) { delete updatedFilters[name]; setFilters(updatedFilters); } else { updatedFilters = {}; setFilters(updatedFilters); } }; return ( <> <div className="flex items-center justify-between flex-wrap pt-4 "> {!id ? ( <div className="w-80 max-w-xs px-3 py-5"> <Skeleton className="h-7" /> </div> ) : ( <h1 className="py-4 flex items-center justify-between break-all space-x-2 text-xl text-gray-700 leading-8 px-2"> Near Account: @ {' '} {id && ( <span className="font-semibold text-green-500 ">{' ' + id}</span> )} { <Widget src={`${config.ownerId}/widget/bos-components.components.Shared.Buttons`} props={{ id: id, config: config, }} /> } </h1> )} </div> <div className="grid grid-cols-1 lg:grid-cols-2 gap-4"> <div className="w-full"> <div className="h-full bg-white soft-shadow rounded-xl"> <div className="flex justify-between border-b p-3 text-nearblue-600"> <h2 className="leading-6 text-sm font-semibold"> {t ? t('address:overview') : 'Overview'} </h2> {tokenData?.name && ( <div className="flex items-center text-xs bg-gray-100 rounded-md px-2 py-1"> <div className="truncate max-w-[110px]">{tokenData.name}</div> {tokenData.website && ( <a href={tokenData.website} className="ml-1" target="_blank" rel="noopener noreferrer nofollow" > <FaExternalLinkAlt /> </a> )} </div> )} </div> <div className="px-3 divide-y text-sm text-nearblue-600"> <div className="flex flex-wrap py-4"> <div className="w-full md:w-1/4 mb-2 md:mb-0"> {t ? t('address:balance') : 'Balance'}: </div> {loading ? ( <Skeleton className="h-4 w-32" /> ) : ( <div className="w-full md:w-3/4 break-words"> {accountData?.amount ? yoctoToNear(accountData?.amount, true) : ''}{' '} Ⓝ </div> )} </div> {network === 'mainnet' && statsData?.near_price && ( <div className="flex flex-wrap py-4 text-sm text-nearblue-600"> <div className="w-full md:w-1/4 mb-2 md:mb-0"> {t ? t('address:value') : 'Value:'} </div> {loading ? ( <Skeleton className="h-4 w-32" /> ) : ( <div className="w-full md:w-3/4 break-words"> {accountData.amount ? '$' + fiatValue( yoctoToNear(accountData.amount, false), statsData.near_price, ) : ''}{' '} <span className="text-xs"> (@ $ {statsData.near_price ? dollarFormat(statsData.near_price) : ''}{' '} / Ⓝ) </span> </div> )} </div> )} <div className="flex flex-wrap py-4 text-sm text-nearblue-600"> <div className="w-full md:w-1/4 mb-2 md:mb-0"> {t ? t('address:tokens') : 'Tokens:'} </div> <div className="w-full md:w-3/4 break-words -my-1 z-10"> <TokenHoldings data={inventoryData} loading={loading} ft={ft} id={id} appUrl={config.appUrl} /> </div> </div> </div> </div> </div> <div className="w-full"> <div className="h-full bg-white soft-shadow rounded-xl overflow-hidden"> <h2 className="leading-6 border-b p-3 text-nearblue-600 text-sm font-semibold"> {t ? t('address:moreInfo') : 'Account information'} </h2> <div className="px-3 divide-y text-sm text-nearblue-600"> <div className="flex justify-between"> <div className="flex xl:flex-nowrap flex-wrap items-center justify-between py-4 w-full"> <div className="w-full mb-2 md:mb-0"> Staked {t ? t('address:balance') : 'Balance'}: </div> {loading ? ( <div className="w-full break-words"> <Skeleton className="h-4 w-32" /> </div> ) : ( <div className="w-full break-words xl:mt-0 mt-2"> {accountData?.locked ? yoctoToNear(accountData?.locked, true) + ' Ⓝ' : ''} </div> )} </div> <div className="flex ml-4 xl:flex-nowrap flex-wrap items-center justify-between py-4 w-full"> <div className="w-full mb-2 md:mb-0">Storage Used:</div> {loading ? ( <div className="w-full break-words"> <Skeleton className="h-4 w-28" /> </div> ) : ( <div className="w-full break-words xl:mt-0 mt-2"> {accountData?.storage_usage ? weight(accountData?.storage_usage) : ''} </div> )} </div> </div> <div className="flex justify-between"> <div className="flex xl:flex-nowrap flex-wrap items-center justify-between py-4 w-full"> {loading ? ( <div className="w-full mb-2 md:mb-0"> <Skeleton className="h-4 w-28" /> </div> ) : ( <div className="w-full mb-2 md:mb-0"> {accountData?.deleted?.transaction_hash ? 'Deleted At:' : 'Created At:'} </div> )} {loading ? ( <div className="w-full break-words"> <Skeleton className="h-4 w-40" /> </div> ) : ( <div className="w-full break-words xl:mt-0 mt-2"> {accountData?.deleted?.transaction_hash ? convertToUTC( nanoToMilli(accountData.deleted.block_timestamp), false, ) : accountData?.created?.transaction_hash ? convertToUTC( nanoToMilli(accountData.created.block_timestamp), false, ) : accountData?.code_hash ? 'Genesis' : 'N/A'} </div> )} </div> {contract?.hash ? ( <div className="flex ml-4 xl:flex-nowrap flex-wrap items-center justify-between py-4 w-full"> <div className="w-full mb-2 md:mb-0">Contract Locked:</div> <div className="w-full break-words xl:mt-0 mt-2"> {contract?.locked ? 'Yes' : 'No'} </div> </div> ) : ( <div className="flex ml-4 xl:flex-nowrap flex-wrap items-center justify-between py-4 w-full" /> )} </div> {deploymentData?.receipt_predecessor_account_id && ( <div className="flex flex-wrap items-center justify-between py-4"> <div className="w-full md:w-1/4 mb-2 md:mb-0"> Contract Creator: </div> <div className="w-full md:w-3/4 break-words"> <a href={`/address/${deploymentData.receipt_predecessor_account_id}`} className="hover:no-underline" > <a className="text-green-500 hover:no-underline"> {shortenAddress( deploymentData.receipt_predecessor_account_id, )} </a> </a> {' at txn '} <a href={`/txns/${deploymentData.transaction_hash}`} className="hover:no-underline" > <a className="text-green-500 hover:no-underline"> {shortenAddress(deploymentData.transaction_hash)} </a> </a> </div> </div> )} {tokenData?.name && ( <div className="flex flex-wrap items-center justify-between py-4"> <div className="w-full md:w-1/4 mb-2 md:mb-0"> Token Tracker: </div> <div className="w-full md:w-3/4 break-words"> <div className="flex items-center"> <TokenImage src={tokenData?.icon} alt={tokenData?.name} appUrl={config.appUrl} className="w-4 h-4 mr-2" /> <a href={`/token/${id}`} className="hover:no-underline"> <a className="flex text-green-500 hover:no-underline"> <span className="inline-block truncate max-w-[110px] mr-1"> {tokenData.name} </span> ( <span className="inline-block truncate max-w-[80px]"> {tokenData.symbol} </span> ) </a> </a> {tokenData.price && ( <div className="text-nearblue-600 ml-1"> (@ ${localFormat(tokenData.price)}) </div> )} </div> </div> </div> )} </div> </div> </div> </div> <div className="py-6"></div> <div className="block lg:flex lg:space-x-2 mb-10"> <div className="w-full "> <Tabs.Root defaultValue={pageTab}> <Tabs.List> {tabs && tabs.map((tab, index) => ( <Tabs.Trigger key={index} onClick={() => { onTab(index); }} className={`text-nearblue-600 text-sm font-medium overflow-hidden inline-block cursor-pointer p-2 mb-3 mr-2 focus:outline-none ${ pageTab === tab ? 'rounded-lg bg-green-600 text-white' : 'hover:bg-neargray-800 bg-neargray-700 rounded-lg hover:text-nearblue-600' }`} value={tab} > {tab === 'Transactions' ? ( <h2>{t ? t('address:txns') : tab}</h2> ) : tab === 'Token Txns' ? ( <h2>{t ? t('address:tokenTxns') : tab}</h2> ) : tab === 'Contract' ? ( <div className="flex h-full"> <h2>{tab}</h2> <div className="absolute text-white bg-neargreen text-[8px] h-4 inline-flex items-center rounded-md ml-11 -mt-3 px-1 "> NEW </div> </div> ) : tab === 'Comments' ? ( <h2>{t ? t('address:comments') : tab}</h2> ) : ( <h2>{tab}</h2> )} </Tabs.Trigger> ))} </Tabs.List> <div> <Tabs.Content value={tabs[0]}> { <Widget src={`${config.ownerId}/widget/bos-components.components.Address.Transactions`} props={{ network: network, t: t, id: id, filters: filters, handleFilter: handleFilter, onFilterClear: onFilterClear, }} /> } </Tabs.Content> <Tabs.Content value={tabs[1]}> { <Widget src={`${config.ownerId}/widget/bos-components.components.Address.TokenTransactions`} props={{ network: network, id: id, t: t, filters: filters, handleFilter: handleFilter, onFilterClear: onFilterClear, }} /> } </Tabs.Content> <Tabs.Content value={tabs[2]}> { <Widget src={`${config.ownerId}/widget/bos-components.components.Address.NFTTransactions`} props={{ network: network, id: id, t: t, filters: filters, handleFilter: handleFilter, onFilterClear: onFilterClear, }} /> } </Tabs.Content> <Tabs.Content value={tabs[3]}> { <Widget src={`${config.ownerId}/widget/bos-components.components.Address.AccessKeys`} props={{ network: network, id: id, t: t, }} /> } </Tabs.Content> <Tabs.Content value={tabs[4]}> <div className="px-4 sm:px-6 py-3"></div> </Tabs.Content> <Tabs.Content value={tabs[5]}> <div className="px-4 sm:px-6 py-3"></div> </Tabs.Content> </div> </Tabs.Root> </div> </div> </> ); } return MainComponent(props, context);