@transia/secret-numbers
Version:
Generate XRPL Accounts with a number-based secret: 8 chunks of 6 digits
76 lines • 2.99 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseSecretString = exports.checkChecksum = exports.calculateChecksum = exports.secretToEntropy = exports.entropyToSecret = exports.randomSecret = exports.randomEntropy = void 0;
const utils_1 = require("@transia/isomorphic/utils");
function randomEntropy() {
return (0, utils_1.randomBytes)(16);
}
exports.randomEntropy = randomEntropy;
function calculateChecksum(position, value) {
return (value * (position * 2 + 1)) % 9;
}
exports.calculateChecksum = calculateChecksum;
function checkChecksum(position, value, checksum) {
let normalizedChecksum;
let normalizedValue;
if (typeof value === 'string') {
if (value.length !== 6) {
throw new Error('value must have a length of 6');
}
normalizedChecksum = parseInt(value.slice(5), 10);
normalizedValue = parseInt(value.slice(0, 5), 10);
}
else {
if (typeof checksum !== 'number') {
throw new Error('checksum must be a number when value is a number');
}
normalizedChecksum = checksum;
normalizedValue = value;
}
return (normalizedValue * (position * 2 + 1)) % 9 === normalizedChecksum;
}
exports.checkChecksum = checkChecksum;
function entropyToSecret(entropy) {
const len = new Array(Math.ceil(entropy.length / 2));
const chunks = Array.from(len, (_a, chunk) => {
const buffChunk = entropy.slice(chunk * 2, (chunk + 1) * 2);
const no = parseInt((0, utils_1.bytesToHex)(buffChunk), 16);
const fill = '0'.repeat(5 - String(no).length);
return fill + String(no) + String(calculateChecksum(chunk, no));
});
if (chunks.length !== 8) {
throw new Error('Chucks must have 8 digits');
}
return chunks;
}
exports.entropyToSecret = entropyToSecret;
function randomSecret() {
return entropyToSecret(randomEntropy());
}
exports.randomSecret = randomSecret;
function secretToEntropy(secret) {
return (0, utils_1.concat)(secret.map((chunk, i) => {
const no = Number(chunk.slice(0, 5));
const checksum = Number(chunk.slice(5));
if (chunk.length !== 6) {
throw new Error('Invalid secret: number invalid');
}
if (!checkChecksum(i, no, checksum)) {
throw new Error('Invalid secret part: checksum invalid');
}
const hex = `0000${no.toString(16)}`.slice(-4);
return (0, utils_1.hexToBytes)(hex);
}));
}
exports.secretToEntropy = secretToEntropy;
function parseSecretString(secret) {
const normalizedSecret = secret.replace(/[^0-9]/gu, '');
if (normalizedSecret.length !== 48) {
throw new Error('Invalid secret string (should contain 8 blocks of 6 digits');
}
return Array.from(new Array(8), (_a, index) => {
return normalizedSecret.slice(index * 6, (index + 1) * 6);
});
}
exports.parseSecretString = parseSecretString;
//# sourceMappingURL=index.js.map