npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@vidy-dev/ethereum-connect

v1.0.22

Published

Easy connection to the backend ethereum node load balancer

Downloads

9

Readme

ethereum-connect

Quick connection to ethereum nodes, including RPC configuration and internal service detection.

connecting

To create a connection with default settings, use:

const ethereumConnect = require('@vidy-dev/ethereum-connect')
const connection = await ethereumConnect()

Connection configuration is inferred from environmental context and, optionally, a config/{environment}.js config file readable with the config module. Alternatively, configurations can be overridden by providing an options argument, like:

const ethereumConnect = require('@vidy-dev/ethereum-connect')
const connection = await ethereumConnect({logging: true, rpc: {port: 1337}})

caching

Usage of ethereumConnect as an object constructor will create a fresh connection every time it is called; it is the user's responsibility to manage the transfer of this connection object between uses.

Alternatively, the module provides connection caching based on input arguments:

const ethereumConnect = require('@vidy-dev/ethereum-connect')
const connection1 = await ethereumConnect.getConnection({logging: true})
...
const connection2 = await ethereumConnect.getConnection({logging: true})

In this example, both connection1 and connection2 refer to the same object. If the input configuration is meaningfully changed, a new connection would be returned instead. This allows different files or function invocations to use the same connection (saving time and remote calls) so long as they share configuration arguments. ethereumConnect.reset() clears this cache.

config / options

The environment configuration file is checked for these keys:

{
  "ethereum": {
    "contracts": [],
    "logging": false,
    "rpc": {
      "address": "www.google.com",
      "port": 8545
    }
  }
}

when provided as function arguments, the same format may be used, or the subobject named ethereum.

ethereum node

ethereumConnect automates the complexity of discovering the Vidy backend ethereum service domain name, connecting to the load balancer, testing the connection, etc. To this end, functions that create connections (the constructor ethereumConnect() and caching ethereumConnect.getConnection() function) will raise exceptions if an active Ethereum node cannot be found.

The ethereum node location can be specified as the rpc.address and rpc.port options. If the address is omitted, the normal discovery process will be used; if the port is omitted, 8545 is the default.

ethereum node address discovery

ethereumConnect is intended for three use cases:

  1. The service is running on the Google Cloud backend, in a project using our ethereum-node load balancing service.
  2. The service is running on a developer's local workstation, with an active port-tunnelling connection to the ethereum middleman (see the ethereum-tools repo).
  3. The service is running on an instance with an active ethereum node.

To handle the first case, Google's metadata domain names are queried for the current project and zone; from these, the associated ethereum-node fully-qualified-domain-name can be determined. This address is sent a simple RPC request (net_version) to confirm that it is active and accepting RPC connections. If the connection fails, ethereumConnect reverts to the default region us-central1 and tries again. If both fail, a connection to localhost is connected.

The first of these three connection attempts to succeed is the one used for the connection. If none succeed, the connection attempt fails and an exception will be thrown.

contracts

Solidity smart contracts, as build output .json files, can be discovered and loaded by the connection. Contracts loaded by it will be wrapped in the truffle-contract interface and preconfigured with a default account for transaction signing. See the truffle-contract implementation or other examples for usage of the contracts themselves, once loaded.

Contract discovery allows users to specify contracts without their fully scoped module paths. For example, if the VidyCoin contract is included in your project (with npm install @vidy-dev/ethereum-vidycoin) you can reference it directly with await connection.getContract('@vidy-dev/ethereum-vidycoin/build/contracts/VidyCoin.json') -- but it could also be located with simpler queries, such as await connection.getContract('ethereum-vidycoin/VidyCoin.json') or even await connection.getContract('VidyCoin'). It is an error (an exception will be thrown) to request a contract that cannot be found, or a query string that is ambiguous (discovers multiple contracts).

As a security measure, contracts located in your project's node_modules paths will only be discoverable if they exist in the @vidy-dev scope (this prevents 3rd party libraries from attacking by providing conflicting contract definitions). However, if you need custom contracts that are not provided by modules in that scope, their directories can be specified with the ethereum.contracts config option.

connections

Connections created by ethereumConnect provide these functions:

await connection.getConfig(): provides the fully populated configuration object, combining environment configuration, construction options, node discovery, and default values.

await connection.getWeb3(): provides the ethereum web3 instance used for the connection, preconfigured with a default account for transaction signing. Useful for any web3 operation: checking block numbers, sync status, account balances, etc.

await connection.getContractFinder(): provides the internal helper used to locate Solidity contracts when getContract() or createContract is used.

await connection.getContract(contract): discovers, loads, and configures a truffle-contract instance for the specified contract, which is a string or file path uniquely identifying a discoverable contract .json file. To save time, the output is cached; multiple calls with the same input query will retrieve exactly the same contract instance (you should not rely on this caching for any reason other than efficiency; e.g. you should not build code on the assumption that the same instance is provided every time).

await connection.createContract(contract): identical to getContract, except no caching is done; a fresh truffle-contract instance is provided with each call.

example

Below is a short usage example, taken from the KYC reference implementation. The specific functions supported by the contract itself are contract-dependent.

'use strict';

const web3 = require('../lib/web3');
const ethereumConnect = require('@vidy-dev/ethereum-connect')

exports.isOnWhitelist = async function(req, res) {
  try {
    // get a connection (cached; only the first call is expensive)
    const connection = await ethereumConnect.getConnection();
    // get a contract interface for the public whitelist (cached)
    const PublicICOWhitelist = await connection.getContract('PublicIcoWhitelist');
    // get an interface for the instance deployed on this ethereum network
    const publicIcoWhitelist = await PublicICOWhitelist.deployed();
    // query whether the given address is on the whitelist
    const result = await publicIcoWhitelist.whitelist.call(req.params.address);
    if (!result) {
      res.status(404).send({address: `address ${req.params.address} is not on the whitelist`, success: false});
    } else {
      res.json({success:result});
    }
  } catch (err) {
    console.log(err);
    res.status(500).send({success:false, message: err.message})
  }
};

exports.addToWhitelist = async function(req, res) {
  try {
    // get a connection (cached; only the first call is expensive)
    const connection = await ethereumConnect.getConnection();
    // get a contract interface for the public whitelist (cached)
    const PublicICOWhitelist = await connection.getContract('PublicIcoWhitelist');
    // get an interface for the instance deployed on this ethereum network
    const publicIcoWhitelist = await PublicICOWhitelist.deployed();
    // make the change on the Ethereum blockchain through the contract interface
    await publicIcoWhitelist.addAddressToWhitelist(req.params.address);
    res.json({"success":true});
  } catch (err) {
    console.log(err);
    res.status(500).send({success:false, message: err.message})
  }
};