MESC is a standard for how crypto tools configure their RPC endpoints. By following this specification, a user creates a single RPC configuration that can be shared by all crypto tools on their system.
MESC has two main design goals:
- make it easy to share RPC configuration data across tools, languages, and environments
- make it easy to manage the configuration of a large number of RPC endpoints
MESC is formally defined in SPECIFICATION.md.
Additional information can be found in the MESC Documentation.
Contents
Reference Implementations
Reference implementations are provided for each of the following:
- cli
- go [WIP]
- python
- rust
- typescript [WIP]
These implementations provide a consistent language-agnostic interface while still obeying the best practices of each language.
Quickstart
The quickest way to use MESC is:
- create a
mesc.jsonconfig file - set the
MESC_PATHenvironment variable to the path of this file
These steps can be performed automatically using the interactive mesc CLI tool:
- Install:
cargo install mesc_cli - Perform interactive setup:
mesc setup
Installing the mesc cli on some linux distributions may require installing ssl libraries (e.g. sudo apt-get install pkg-config libssl-dev on ubunutu)
Tutorial
Below is a brief tutorial on MESC. For more detail, see the MESC Specification and Documentation.
Topics:
Tracked Information
MESC tracks the following information:
- a list of RPC endpoints, including their
name,chain_id, andurl - the default RPC endpoint to use
- the default RPC endpoint to use for each network
MESC can also track other information like metadata and tool-specific defaults. Configuration data is stored in a JSON file. To create this file, follow the Quickstart instructions above.
Common Interface
All reference MESC implementations use the same common interface.
Here is a comparison between the python interface and the rust interface:
python
1import mesc
2
3# check whether mesc is enabled
4enabled: bool = mesc.is_mesc_enabled()
5
6# get the default endpoint
7endpoint: Endpoint | None = mesc.get_default_endpoint()
8
9# get the default endpoint of a network
10endpoint: Endpoint | None = mesc.get_endpoint_by_network(5)
11
12# get the default endpoint for a particular tool
13endpoint: Endpoint | None = mesc.get_default_endpoint(profile='xyz_tool')
14
15# get the default endpoint of a network for a particular tool
16endpoint: Endpoint | None = mesc.get_endpoint_by_network(5, profile='xyz_tool')
17
18# get an endpoint by name
19endpoint: Endpoint | None = mesc.get_endpoint_by_name('local_goerli')
20
21# parse a user-provided string into a matching endpoint
22# (first try 1. endpoint name, then 2. chain id, then 3. network name)
23endpoint: Endpoint | None = mesc.get_endpoint_by_query(user_str, profile='xyz_tool')
24
25# find all endpoints matching given criteria
26endpoints: list[Endpoint] = mesc.find_endpoints(chain_id=5)rust
1use mesc::{MescError, Endpoint};
2use std::collections::HashMap;
3
4type OptionalResult = Result<Option<Endpoint>, MescError>;
5type MultiResult = Result<Vec<Endpoint>, MescError>;
6type MetadataResult = Result<HashMap<String, serde_json::Value>, MescError>;
7
8// check whether mesc is enabled
9let enabled: bool = mesc::is_mesc_enabled();
10
11// get the default endpoint
12let endpoint: OptionalResult = mesc::get_default_endpoint(None);
13
14// get the default endpoint of a network
15let endpoint: OptionalResult = mesc::get_endpoint_by_network("5", None);
16
17// get the default network for a particular tool
18let chain_id: OptionalResult = mesc::get_default_endpoint(Some("xyz_tool"));
19
20// get the default endpoint of a network for a particular tool
21let endpoint: OptionalResult = mesc::get_endpoint_by_network("5", Some("xyz_tool"));
22
23// get an endpoint by name
24let endpoint: OptionalResult = mesc::get_endpoint_by_name("local_goerli");
25
26// parse a user-provided string into a matching endpoint
27// (first try 1. endpoint name, then 2. chain id, then 3. network name)
28let user_str = "local_goerli";
29let endpoint: OptionalResult = mesc::get_endpoint_by_query(user_str, Some("xyz_tool"));
30
31// find all endpoints matching given criteria
32let query = mesc::MultiEndpointQuery::new().chain_id("5").unwrap();
33let endpoints: MultiResult = mesc::find_endpoints(query);Typical Usage
Imagine a crypto cli tool xyz. This tool has an argument -r <RPC_URL> that specifies which RPC endpoint to use.
If xyz uses MESC, then -r can become a much more versatile argument. Instead of just accepting a plain URL, -r can accept 1. an endpoint name, 2. chain id, or 3. a network name. Each of the following might resolve to the same RPC url:
xyz -r localhost:8545(url)xyz -r local_goerli(endpoint name)xyz -r 5(chain id)xyz -r goerli(network name)
This url resolution can implemented within xyz using:
1# python code used by xyz tool
2endpoint = mesc.get_endpoint_by_query(user_input, profile='xyz')
3url = endpoint['url']1// rust code used by xyz tool
2let endpoint = mesc::get_endpoint_by_query(user_input, Some("xyz"))?;
3let url = endpoint.url;