UNPKG

@ar.io/sdk

Version:

[![codecov](https://codecov.io/gh/ar-io/ar-io-sdk/graph/badge.svg?token=7dXKcT7dJy)](https://codecov.io/gh/ar-io/ar-io-sdk)

109 lines (108 loc) 4.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.convertHyperBeamStateToAoANTState = exports.isHyperBeamANTState = exports.sortANTRecords = void 0; /** * Sorts ANT records by priority and then lexicographically. * * Note: javascript guarantees that the order of objects in an object is persistent. Still, adding index to each record is useful for enforcing against undername limits. * * Reference: https://github.com/ar-io/ar-io-node/blob/e0a9ec56559cad1b3e35d668563871afb8649913/docs/madr/003-arns-undername-limits.md * * @param antRecords - The ANT records to sort. */ const sortANTRecords = (antRecords) => { const sortedEntries = Object.entries(antRecords).sort(([a, aRecord], [b, bRecord]) => { // '@' is the root name and should be resolved first if (a === '@') { return -1; } if (b === '@') { return 1; } // if a record has a priority, it should be resolved before any other record without a priority if ('priority' in aRecord && !('priority' in bRecord)) { return -1; } if (!('priority' in aRecord) && 'priority' in bRecord) { return 1; } // if both records have a priority, sort by priority and fallback to lexicographic sorting if (aRecord.priority !== undefined && bRecord.priority !== undefined) { if (aRecord.priority === bRecord.priority) { // use deterministic comparison instead of localeCompare to avoid locale-specific sorting return a < b ? -1 : a > b ? 1 : 0; } return aRecord.priority - bRecord.priority; } // all other records are sorted lexicographically, using deterministic comparison instead of localeCompare to avoid locale-specific sorting return a < b ? -1 : a > b ? 1 : 0; }); // now that they are sorted, add the index to each record - this is their position in the sorted list and is used to enforce undername limits return Object.fromEntries(sortedEntries.map(([a, aRecord], index) => [a, { ...aRecord, index }])); }; exports.sortANTRecords = sortANTRecords; /** * @deprecated - this is no longer necessary because HyperBeam now uses the AoANTState type */ const isHyperBeamANTState = (state) => { return ('name' in state && 'ticker' in state && 'description' in state && 'keywords' in state && 'denomination' in state && 'owner' in state && 'controllers' in state && 'records' in state && 'balances' in state && 'logo' in state && 'totalsupply' in state && 'initialized' in state); }; exports.isHyperBeamANTState = isHyperBeamANTState; /** * Convert HyperBeam serialized ANT state to backwards compatible format. * * @deprecated - this is no longer necessary because HyperBeam now uses the AOANTState type * @param state - The HyperBeam serialized ANT state. */ const convertHyperBeamStateToAoANTState = (initialState) => { function lowerCaseKeys(obj) { return Object.fromEntries(Object.entries(obj).map(([key, value]) => { if (key.toLowerCase().includes('balances')) { return [key.toLowerCase(), value]; } if (typeof value === 'object' && !Array.isArray(value) && value !== null) { return [key.toLowerCase(), lowerCaseKeys(value)]; } return [key.toLowerCase(), value]; })); } // we need to ensure keys are lower cased because hyperbeam json serializes keys to lowercase inconsistently const state = lowerCaseKeys(initialState); return { Name: state.name, Ticker: state.ticker, Description: state.description, Keywords: state.keywords, Denomination: parseInt(state.denomination), Owner: state.owner, Controllers: state.controllers, Records: Object.entries(state.records).reduce((acc, [key, record]) => { acc[key] = { transactionId: record.transactionid, ttlSeconds: record.ttlseconds, ...(record.priority !== undefined ? { priority: record.priority } : {}), }; return acc; }, {}), Balances: state.balances, Logo: state.logo, TotalSupply: state.totalsupply || 1, Initialized: state.initialized, }; }; exports.convertHyperBeamStateToAoANTState = convertHyperBeamStateToAoANTState;