Source: covenants/locked-browser.js

'use strict';

const assert = require('bsert');
const sha3 = require('bcrypto/lib/sha3');
const data = require('./lockup.json');

/*
 * Constants
 */

const ZERO_HASH = sha3.zero.toString('hex');

/**
 * Locked up
 */

class LockedUp {
  constructor(data) {
    const meta = data[ZERO_HASH];

    this.data = data;
    this.size = meta[0];
  }

  has(hash) {
    assert(Buffer.isBuffer(hash) && hash.length === 32);

    const hex = hash.toString('hex');
    const item = this.data[hex];

    if (!item)
      return false;

    return Array.isArray(item);
  }

  get(hash) {
    assert(Buffer.isBuffer(hash) && hash.length === 32);

    const hex = hash.toString('hex');
    const item = this.data[hex];

    if (!item || !Array.isArray(item))
      return null;

    const target = item[0];
    const flags = item[1];
    const index = target.indexOf('.');

    assert(index !== -1);

    const root = (flags & 1) !== 0;
    const custom = (flags & 2) !== 0;
    const name = target.substring(0, index);

    return {
      name,
      hash,
      target,
      root,
      custom
    };
  }

  hasByName(name) {
    assert(typeof name === 'string');

    if (name.length === 0 || name.length > 63)
      return false;

    return this.has(hashName(name));
  }

  getByName(name) {
    assert(typeof name === 'string');

    if (name.length === 0 || name.length > 63)
      return null;

    return this.get(hashName(name));
  }

  *entries() {
    const keys = Object.keys(this.data);

    for (const key of keys) {
      const hash = Buffer.from(key, 'hex');

      yield [hash, this.get(hash)];
    }
  }

  *keys() {
    const keys = Object.keys(this.data);

    for (const key of keys)
      yield Buffer.from(key, 'hex');
  }

  *values() {
    for (const [, item] of this.entries())
      yield item;
  }

  [Symbol.iterator]() {
    return this.entries();
  }
}

function hashName(name) {
  const raw = Buffer.from(name.toLowerCase(), 'ascii');
  return sha3.digest(raw);
}

exports.LockedUp = LockedUp;
exports.locked = new LockedUp(data);