lib/coined.js
function Coined(options) {
  var self = this
    , dbType
    , dbDir
    , dbPath;

  if (!(this instanceof Coined)) {
    return new Coined(options);
  }

  EventEmitter.call(this);

  options = options || {};
  options.db = options.db || {};

  dbType = options.db.type || 'tiny';
  dbDir = dbType === 'level'
    ? '.coined.level'
    : '.coined';
  dbPath = dbType === 'level'
    ? path.resolve(process.env.HOME, dbDir)
    : path.resolve(process.env.HOME, dbDir, 'db');

  options.db.type = options.db.type || dbType;
  options.db.path = options.db.path || dbPath;

  if (options.db.clear) {
    cleanup(options.db.path);
  }

  if (options.db.type === 'level') {
    mkdirp(options.db.path);
    this.db = require('levelup')(options.db.path, {
      db: require('leveldown'),
      valueEncoding: 'json'
    });
  } else if (options.db.type === 'tiny') {
    mkdirp(path.resolve(options.db.path, '..'));
    this.db = require('tiny').json({
      file: options.db.path,
      saveIndex: false,
      initialCache: false
    });
  } else {
    throw new Error('Invalid DB type.');
  }

  this.options = options;

  this.socketIndex = 0;

  this.crypto = options.crypto;
  this.compressed = options.compressed != null
    ? options.compressed
    : true;

  this.walletPath = options.walletPath || options.wallet
    || process.env.HOME + '/.coined/wallet.json';

  this.addr = null;
  this.dust = 5460;
  this.fee = 10000;

  mkdirp(path.dirname(this.walletPath));

  this.account = null;
  this.accounts = [];
  this.aaccounts = {};
  this.laccounts = {};
  this.recipients = {};

  if (options.noPreload) {
    this._clearPreload();
  }

  this.pool = options.pool || bcoin.pool({
    size: options.size,
    createConnection: function() {
      if (self.socketIndex >= seeds.length) {
        self.socketIndex = 0;
      }

      if (seeds.length > 3000) {
        seeds = seeds.slice(0, 1500);
        self.socketIndex = 0;
      }

      var addr = seeds[self.socketIndex++]
        , parts = addr.split(':')
        , host = parts[0]
        , port = +parts[1] || network.port
        , socket;

      socket = net.connect(port, host);

      socket.on('connect', function() {
        var peers = [].concat(
          self.pool.peers.pending,
          self.pool.peers.block,
          self.pool.peers.load
        ).filter(Boolean);

        for (var i = 0; i < peers.length; i++) {
          var peer = peers[i];

          if (peer.socket !== socket) {
            continue;
          }

          if (peer.version) {
            return self.emit('peer', peer, socket);
          }

          return peer.parser.on('packet', function callee(payload) {
            if (payload.cmd !== 'version') return;
            peer.removeListener('packet', callee);
            return setImmediate(function() {
              self.emit('peer', peer, socket);
            });
          });
        }

        self._log('Connected to %s:%d', host, port);
      });

      return socket;
    },
    storage: this.db,
    startHeight: options.startHeight,
    fullNode: options.fullNode
    // relay: options.relay
  });

  this.blockHeight = 0;
  this.on('peer', function(peer) {
    if (!peer.version || !peer.socket) {
      return;
    }
    if (peer.version.height > self.blockHeight) {
      self.blockHeight = peer.version.height;
    }
    self._log('Connected to %s:%d (%s v%s) height=%d relay=%d',
      peer.socket.remoteAddress,
      peer.socket.remotePort,
      peer.version.agent,
      peer.version.v,
      peer.version.height,
      peer.version.relay);
  });

  if (options.noPreload) {
    network.preload = network._preload;
  }

  this.pool.on('error', function(err) {
    self._error(err);
  });

  this.salt = 'coined:';

  this.pending = {};

  this.loadWallet(null, this.passphrase);

  if (!this.account) {
    this.createAccount(options);
  }

  // Keep track of version, handle upgrades.
  this.version = Coined.version;
  this.previousVersion = '0.0.0';
  this.db.get('meta/version', function(err, data) {
    if (data) {
      self.previousVersion = data.version;
    }
    return self.db.put('meta/version', { version: self.version }, function(err) {
      if (err) return self._error(err);
      self._log('Version written: %s, previous: %s',
        self.version, self.previousVersion);
    });
  });

  // Listeners to remove on .destroy();
  this.pool._poolOnTX = null;
  this.pool._poolOnReject = null;
  this.pool._poolOnceFull = null;
  this.closed = false;

  this.init();
}
function Coined(options) {
  var self = this
    , dbType
    , dbDir
    , dbPath;

  if (!(this instanceof Coined)) {
    return new Coined(options);
  }

  EventEmitter.call(this);

  options = options || {};
  options.db = options.db || {};

  dbType = options.db.type || 'tiny';
  dbDir = dbType === 'level'
    ? '.coined.level'
    : '.coined';
  dbPath = dbType === 'level'
    ? path.resolve(process.env.HOME, dbDir)
    : path.resolve(process.env.HOME, dbDir, 'db');

  options.db.type = options.db.type || dbType;
  options.db.path = options.db.path || dbPath;

  if (options.db.clear) {
    cleanup(options.db.path);
  }

  if (options.db.type === 'level') {
    mkdirp(options.db.path);
    this.db = require('levelup')(options.db.path, {
      db: require('leveldown'),
      valueEncoding: 'json'
    });
  } else if (options.db.type === 'tiny') {
    mkdirp(path.resolve(options.db.path, '..'));
    this.db = require('tiny').json({
      file: options.db.path,
      saveIndex: false,
      initialCache: false
    });
  } else {
    throw new Error('Invalid DB type.');
  }

  this.options = options;

  this.socketIndex = 0;

  this.crypto = options.crypto;
  this.compressed = options.compressed != null
    ? options.compressed
    : true;

  this.walletPath = options.walletPath || options.wallet
    || process.env.HOME + '/.coined/wallet.json';

  this.addr = null;
  this.dust = 5460;
  this.fee = 10000;

  mkdirp(path.dirname(this.walletPath));

  this.account = null;
  this.accounts = [];
  this.aaccounts = {};
  this.laccounts = {};
  this.recipients = {};

  if (options.noPreload) {
    this._clearPreload();
  }

  this.pool = options.pool || bcoin.pool({
    size: options.size,
    createConnection: function() {
      if (self.socketIndex >= seeds.length) {
        self.socketIndex = 0;
      }

      if (seeds.length > 3000) {
        seeds = seeds.slice(0, 1500);
        self.socketIndex = 0;
      }

      var addr = seeds[self.socketIndex++]
        , parts = addr.split(':')
        , host = parts[0]
        , port = +parts[1] || network.port
        , socket;

      socket = net.connect(port, host);

      socket.on('connect', function() {
        var peers = [].concat(
          self.pool.peers.pending,
          self.pool.peers.block,
          self.pool.peers.load
        ).filter(Boolean);

        for (var i = 0; i < peers.length; i++) {
          var peer = peers[i];

          if (peer.socket !== socket) {
            continue;
          }

          if (peer.version) {
            return self.emit('peer', peer, socket);
          }

          return peer.parser.on('packet', function callee(payload) {
            if (payload.cmd !== 'version') return;
            peer.removeListener('packet', callee);
            return setImmediate(function() {
              self.emit('peer', peer, socket);
            });
          });
        }

        self._log('Connected to %s:%d', host, port);
      });

      return socket;
    },
    storage: this.db,
    startHeight: options.startHeight,
    fullNode: options.fullNode
    // relay: options.relay
  });

  this.blockHeight = 0;
  this.on('peer', function(peer) {
    if (!peer.version || !peer.socket) {
      return;
    }
    if (peer.version.height > self.blockHeight) {
      self.blockHeight = peer.version.height;
    }
    self._log('Connected to %s:%d (%s v%s) height=%d relay=%d',
      peer.socket.remoteAddress,
      peer.socket.remotePort,
      peer.version.agent,
      peer.version.v,
      peer.version.height,
      peer.version.relay);
  });

  if (options.noPreload) {
    network.preload = network._preload;
  }

  this.pool.on('error', function(err) {
    self._error(err);
  });

  this.salt = 'coined:';

  this.pending = {};

  this.loadWallet(null, this.passphrase);

  if (!this.account) {
    this.createAccount(options);
  }

  // Keep track of version, handle upgrades.
  this.version = Coined.version;
  this.previousVersion = '0.0.0';
  this.db.get('meta/version', function(err, data) {
    if (data) {
      self.previousVersion = data.version;
    }
    return self.db.put('meta/version', { version: self.version }, function(err) {
      if (err) return self._error(err);
      self._log('Version written: %s, previous: %s',
        self.version, self.previousVersion);
    });
  });

  // Listeners to remove on .destroy();
  this.pool._poolOnTX = null;
  this.pool._poolOnReject = null;
  this.pool._poolOnceFull = null;
  this.closed = false;

  this.init();
}
function Coined ( options ) { var self = this , dbType , dbDir , dbPath ; if ( ! ( this instanceof Coined ) ) { return new Coined ( options ) ; } EventEmitter . call ( this ) ; options = options || { } ; options . db = options . db || { } ; dbType = options . db . type || 'tiny' ; dbDir = dbType === 'level' ? '.coined.level' : '.coined' ; dbPath = dbType === 'level' ? path . resolve ( process . env . HOME , dbDir ) : path . resolve ( process . env . HOME , dbDir , 'db' ) ; options . db . type = options . db . type || dbType ; options . db . path = options . db . path || dbPath ; if ( options . db . clear ) { cleanup ( options . db . path ) ; } if ( options . db . type === 'level' ) { mkdirp ( options . db . path ) ; this . db = require ( 'levelup' ) ( options . db . path , { db : require ( 'leveldown' ) , valueEncoding : 'json' } ) ; } else if ( options . db . type === 'tiny' ) { mkdirp ( path . resolve ( options . db . path , '..' ) ) ; this . db = require ( 'tiny' ) . json ( { file : options . db . path , saveIndex : false , initialCache : false } ) ; } else { throw new Error ( 'Invalid DB type.' ) ; } this . options = options ; this . socketIndex = 0 ; this . crypto = options . crypto ; this . compressed = options . compressed != null ? options . compressed : true ; this . walletPath = options . walletPath || options . wallet || process . env . HOME + '/.coined/wallet.json' ; this . addr = null ; this . dust = 5460 ; this . fee = 10000 ; mkdirp ( path . dirname ( this . walletPath ) ) ; this . account = null ; this . accounts = [ ] ; this . aaccounts = { } ; this . laccounts = { } ; this . recipients = { } ; if ( options . noPreload ) { this . _clearPreload ( ) ; } this . pool = options . pool || bcoin . pool ( { size : options . size , createConnection : function ( ) { if ( self . socketIndex >= seeds . length ) { self . socketIndex = 0 ; } if ( seeds . length > 3000 ) { seeds = seeds . slice ( 0 , 1500 ) ; self . socketIndex = 0 ; } var addr = seeds [ self . socketIndex ++ ] , parts = addr . split ( ':' ) , host = parts [ 0 ] , port = + parts [ 1 ] || network . port , socket ; socket = net . connect ( port , host ) ; socket . on ( 'connect' , function ( ) { var peers = [ ] . concat ( self . pool . peers . pending , self . pool . peers . block , self . pool . peers . load ) . filter ( Boolean ) ; for ( var i = 0 ; i < peers . length ; i ++ ) { var peer = peers [ i ] ; if ( peer . socket !== socket ) { continue ; } if ( peer . version ) { return self . emit ( 'peer' , peer , socket ) ; } return peer . parser . on ( 'packet' , function callee ( payload ) { if ( payload . cmd !== 'version' ) return ; peer . removeListener ( 'packet' , callee ) ; return setImmediate ( function ( ) { self . emit ( 'peer' , peer , socket ) ; } ) ; } ) ; } self . _log ( 'Connected to %s:%d' , host , port ) ; } ) ; return socket ; } , storage : this . db , startHeight : options . startHeight , fullNode : options . fullNode // relay: options.relay } ) ; this . blockHeight = 0 ; this . on ( 'peer' , function ( peer ) { if ( ! peer . version || ! peer . socket ) { return ; } if ( peer . version . height > self . blockHeight ) { self . blockHeight = peer . version . height ; } self . _log ( 'Connected to %s:%d (%s v%s) height=%d relay=%d' , peer . socket . remoteAddress , peer . socket . remotePort , peer . version . agent , peer . version . v , peer . version . height , peer . version . relay ) ; } ) ; if ( options . noPreload ) { network . preload = network . _preload ; } this . pool . on ( 'error' , function ( err ) { self . _error ( err ) ; } ) ; this . salt = 'coined:' ; this . pending = { } ; this . loadWallet ( null , this . passphrase ) ; if ( ! this . account ) { this . createAccount ( options ) ; } // Keep track of version, handle upgrades. this . version = Coined . version ; this . previousVersion = '0.0.0' ; this . db . get ( 'meta/version' , function ( err , data ) { if ( data ) { self . previousVersion = data . version ; } return self . db . put ( 'meta/version' , { version : self . version } , function ( err ) { if ( err ) return self . _error ( err ) ; self . _log ( 'Version written: %s, previous: %s' , self . version , self . previousVersion ) ; } ) ; } ) ; // Listeners to remove on .destroy(); this . pool . _poolOnTX = null ; this . pool . _poolOnReject = null ; this . pool . _poolOnceFull = null ; this . closed = false ; this . init ( ) ; }
Coined
Coined