<commit_before>const Ember = require('ember-source/dist/ember.debug');
const { dasherize } = Ember.String;
const { pluralize } = require('inflection');
const { isEqual, get } = require('lodash');
const log = require('@cardstack/logger')('cardstack/ethereum/indexer');
const { declareInjections } = require('@cardstack/di');
const { fieldTypeFor } = require('./abi-utils');
const { apply_patch } = require('jsonpatch');

const defaultBranch = 'master';

module.exports = declareInjections({
  searchers: 'hub:searchers',
  controllingBranch: 'hub:controlling-branch',
  ethereumClient: `plugin-services:${require.resolve('./client')}`,
  eventIndexer: `plugin-services:${require.resolve('./event-indexer')}`,
  transactionIndexer: `plugin-services:${require.resolve('./transaction-indexer')}`
},

  class EthereumIndexer {

    static create(...args) {
      let [{ ethereumClient, jsonRpcUrl }] = args;
      ethereumClient.connect(jsonRpcUrl);
      return new this(...args);
    }

    constructor({ ethereumClient, dataSource, jsonRpcUrl, controllingBranch, contract, addressIndexing, patch, searchers, eventIndexer, transactionIndexer }) {
      this.dataSourceId = dataSource.id;
      this.contract = contract;
      this.addressIndexing = addressIndexing;
      this.searchers = searchers;
      this.eventIndexer = eventIndexer;
      this.transactionIndexer = transactionIndexer;
      this.controllingBranch = controllingBranch;
      this.patch = patch || Object.create(null);
      this._jsonRpcUrl = jsonRpcUrl;
      this.ethereumClient = ethereumClient;
    }

    async branches() {
      return [this.controllingBranch.name];
    }

    async beginUpdate() {
      if (this.contract) {
        await this.eventIndexer.start({
          ethereumClient: this.ethereumClient,
          name: this.dataSourceId,
          contract: this.contract
        });
      }

      if (this.addressIndexing) {
        await this.transactionIndexer.start(this.addressIndexing, this.ethereumClient);
      }

      return new Updater({
        dataSourceId: this.dataSourceId,
        contract: this.contract,
        addressIndexing: this.addressIndexing,
        eventIndexer: this.eventIndexer,
        transactionIndexer: this.transactionIndexer,
        patch: this.patch,
        searchers: this.searchers
      });
    }
  });

class Updater {

  constructor({ dataSourceId, contract, addressIndexing, searchers, transactionIndexer, eventIndexer, patch }) {
    this.dataSourceId = dataSourceId;
    this.contract = contract;
    this.addressIndexing = addressIndexing;
    this.searchers = searchers;
    this.eventIndexer = eventIndexer;
    this.transactionIndexer = transactionIndexer;
    this.patch = patch;
  }

  async schema() {
    if (this._schema) { return this._schema; }

    let defaultFields = [{
      type: "fields",
      id: "ethereum-address",
      attributes: {
        "field-type": "@cardstack/core-types::case-insensitive"
      }
    }, {
      type: "fields",
      id: "balance-wei",
      attributes: {
        "field-type": "@cardstack/core-types::string"
      }
    }, {
      type: "fields",
      id: "block-number",
      attributes: {
        "field-type": "@cardstack/core-types::integer"
      }
    }, {
      type: "fields",
      id: "event-name",
      attributes: {
        "field-type": "@cardstack/core-types::string"
      }
    }, {
      type: "fields",
      id: "mapping-boolean-value",
      attributes: {
        "field-type": "@cardstack/core-types::boolean"
      }
    }, {
      type: "fields",
      id: "mapping-string-value",
      attributes: {
        "field-type": "@cardstack/core-types::string"
      }
    }, {
      type: "fields",
      id: "mapping-address-value",
      attributes: {
        "field-type": "@cardstack/core-types::case-insensitive"
      }
    }, {
      type: "fields",
      id: "mapping-number-value",
      attributes: {
        "field-type": "@cardstack/core-types::string" // ethereum numbers are too large for JS, use a string to internally represent ethereum numbers
      }
    }, {
      type: "fields",
      id: "transaction-participants",
      attributes: {
        "field-type": "@cardstack/core-types::string-array"
      }
    }, {
      type: "fields",
      id: "block-data",
      attributes: {
        "field-type": "@cardstack/core-types::object"
      }
    }, {
      type: "fields",
      id: "transaction-hash",
      attributes: {
        "field-type": "@cardstack/core-types::integer"
      }
    }, {
      type: "fields",
      id: "block-hash",
      attributes: {
        "field-type": "@cardstack/core-types::string"
      }
    }, {
      type: "fields",
      id: "transaction-nonce",
      attributes: {<commit_msg>fix copy pasta<commit_after>const Ember = require('ember-source/dist/ember.debug');
const { dasherize } = Ember.String;
const { pluralize } = require('inflection');
const { isEqual, get } = require('lodash');
const log = require('@cardstack/logger')('cardstack/ethereum/indexer');
const { declareInjections } = require('@cardstack/di');
const { fieldTypeFor } = require('./abi-utils');
const { apply_patch } = require('jsonpatch');

const defaultBranch = 'master';

module.exports = declareInjections({
  searchers: 'hub:searchers',
  controllingBranch: 'hub:controlling-branch',
  ethereumClient: `plugin-services:${require.resolve('./client')}`,
  eventIndexer: `plugin-services:${require.resolve('./event-indexer')}`,
  transactionIndexer: `plugin-services:${require.resolve('./transaction-indexer')}`
},

  class EthereumIndexer {

    static create(...args) {
      let [{ ethereumClient, jsonRpcUrl }] = args;
      ethereumClient.connect(jsonRpcUrl);
      return new this(...args);
    }

    constructor({ ethereumClient, dataSource, jsonRpcUrl, controllingBranch, contract, addressIndexing, patch, searchers, eventIndexer, transactionIndexer }) {
      this.dataSourceId = dataSource.id;
      this.contract = contract;
      this.addressIndexing = addressIndexing;
      this.searchers = searchers;
      this.eventIndexer = eventIndexer;
      this.transactionIndexer = transactionIndexer;
      this.controllingBranch = controllingBranch;
      this.patch = patch || Object.create(null);
      this._jsonRpcUrl = jsonRpcUrl;
      this.ethereumClient = ethereumClient;
    }

    async branches() {
      return [this.controllingBranch.name];
    }

    async beginUpdate() {
      if (this.contract) {
        await this.eventIndexer.start({
          ethereumClient: this.ethereumClient,
          name: this.dataSourceId,
          contract: this.contract
        });
      }

      if (this.addressIndexing) {
        await this.transactionIndexer.start(this.addressIndexing, this.ethereumClient);
      }

      return new Updater({
        dataSourceId: this.dataSourceId,
        contract: this.contract,
        addressIndexing: this.addressIndexing,
        eventIndexer: this.eventIndexer,
        transactionIndexer: this.transactionIndexer,
        patch: this.patch,
        searchers: this.searchers
      });
    }
  });

class Updater {

  constructor({ dataSourceId, contract, addressIndexing, searchers, transactionIndexer, eventIndexer, patch }) {
    this.dataSourceId = dataSourceId;
    this.contract = contract;
    this.addressIndexing = addressIndexing;
    this.searchers = searchers;
    this.eventIndexer = eventIndexer;
    this.transactionIndexer = transactionIndexer;
    this.patch = patch;
  }

  async schema() {
    if (this._schema) { return this._schema; }

    let defaultFields = [{
      type: "fields",
      id: "ethereum-address",
      attributes: {
        "field-type": "@cardstack/core-types::case-insensitive"
      }
    }, {
      type: "fields",
      id: "balance-wei",
      attributes: {
        "field-type": "@cardstack/core-types::string"
      }
    }, {
      type: "fields",
      id: "block-number",
      attributes: {
        "field-type": "@cardstack/core-types::integer"
      }
    }, {
      type: "fields",
      id: "event-name",
      attributes: {
        "field-type": "@cardstack/core-types::string"
      }
    }, {
      type: "fields",
      id: "mapping-boolean-value",
      attributes: {
        "field-type": "@cardstack/core-types::boolean"
      }
    }, {
      type: "fields",
      id: "mapping-string-value",
      attributes: {
        "field-type": "@cardstack/core-types::string"
      }
    }, {
      type: "fields",
      id: "mapping-address-value",
      attributes: {
        "field-type": "@cardstack/core-types::case-insensitive"
      }
    }, {
      type: "fields",
      id: "mapping-number-value",
      attributes: {
        "field-type": "@cardstack/core-types::string" // ethereum numbers are too large for JS, use a string to internally represent ethereum numbers
      }
    }, {
      type: "fields",
      id: "transaction-participants",
      attributes: {
        "field-type": "@cardstack/core-types::string-array"
      }
    }, {
      type: "fields",
      id: "block-data",
      attributes: {
        "field-type": "@cardstack/core-types::object"
      }
    }, {
      type: "fields",
      id: "transaction-hash",
      attributes: {
        "field-type": "@cardstack/core-types::string"
      }
    }, {
      type: "fields",
      id: "block-hash",
      attributes: {
        "field-type": "@cardstack/core-types::string"
      }
    }, {
      type: "fields",
      id: "transaction-nonce",
      attributes: {
{'fraction_non_alphanumeric': 0.14285714285714285, 'fraction_numerical': 0.0, 'mean_word_length': 2.6695013529184384, 'pattern_counts': {'":': 24, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7234220', 'n_tokens_mistral': 2866, 'n_tokens_neox': 2880, 'n_words': 518}