Source: client.js

const Web3 = require('web3');
const pLimit = require('p-limit');
const rlay = require('@rlay/web3-rlay');
const EntityMetaFactory = require('./entity/meta-factory');
const RlayEntities = require('./rlay');
const RlayOntology = require('@rlay/ontology');

class Config {
  constructor() {
    this.address = '0xc02345a911471fd46c47c4d3c2e5c85f5ae93d13';
    this.backend = 'myneo4j';
    this.RpcUrl = process.env.RPC_URL || 'http://localhost:8546';
    this.storeLimit = 50;
    this.readLimit = 50;
    Object.seal(this);
  }
}

/**
 * The `Client`, ORM, and main interface for users
 */
class Client {

  /**
   * Create a new Client instance
   *
   * @param {Config} config - The configuration for the client
   */
  constructor (config = {}) {
    this.config = new Config();
    this.initConfig(config);

    this.web3 = new Web3(this.config.RpcUrl);
    rlay.extendWeb3WithRlay(this.web3);
    this.web3.eth.defaultAccount = this.config.address;

    this.rlay = rlay;
    this.rlayOntology = RlayOntology;
    this.schema = {};
    this.storeLimit = pLimit(this.config.storeLimit);
    this.readLimit = pLimit(this.config.readLimit);
    this.entityMetaFactory = new EntityMetaFactory(this);

    // set client for RlayEntities
    Object.keys(RlayEntities).forEach(entity => {
      RlayEntities[entity].client = this;
    });
    Object.assign(this, RlayEntities);
    this.Individual = this.Rlay_Individual;
  }

  async createEntity (entity) {
    return this.storeLimit(async () => {
      return this.rlay.store(this.web3, entity, { backend: this.config.backend });
    })
  }

  async findEntityByCID (cid) {
    return this.readLimit(async () => {
      return this.web3.rlay.experimentalGetEntity(cid, { backend: this.config.backend });
    });
  }

  async findEntityByCypher (query) {
    return this.readLimit(async () => {
      return this.web3.rlay.experimentalNeo4jQuery(query, { backend: 'myneo4j' });
    });
  }

  getEntityCid (payload) {
    return this.rlayOntology.getEntityCid(payload);
  }

  initConfig (config) {
    Object.assign(this.config, config);
  }

  initSchema (schemaCIDs, schema) {
    this.schema = Object.assign(this.schema, schemaCIDs);
    // transform this.schema['abc'] = "0x00xx" to
    //           this.schema['abc'] = { cid: "0x00xx" }
    Object.keys(this.schema).forEach(key => {
      const cid = this.schema[key];
      this.schema[key] = { cid };
    });
    // add additional schema info from @param: `schema`
    schema.forEach(assertion => {
      if (this.schema[assertion.key]) {
        this.schema[assertion.key] = Object.assign(
          this.schema[assertion.key],
          assertion.assertion
        );
        // convert to proper Rlay Entity
        this.schema[assertion.key] = this.entityMetaFactory.fromType(
          this.schema[assertion.key].type,
          this.schema[assertion.key]
        );
      }
    });
  }

  initClient () {
    Object.keys(this.schema).forEach(key => {
      const schemaEntity = this.schema[key];
      try {
        this[key] = this.entityMetaFactory.fromSchema(schemaEntity);
      } catch (_) { }
    });
  }
}

module.exports = { Client, Config };