From 56927de614caaf0d0bc1d696e0a75bfa43e68e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Bernard?= Date: Wed, 28 Jun 2023 23:05:12 +0200 Subject: [PATCH] feat(lib): introduced ENS gateway library --- .github/workflows/release.yml | 2 +- Cargo.lock | 42 +++++++++++++++++------------------ Cargo.toml | 12 ++++++++-- Dockerfile | 10 ++++----- README.md | 5 ++++- src/errors.rs | 9 +++++++- src/lib.rs | 18 +++++++++++++++ src/main.rs | 16 ++----------- src/utils.rs | 4 ++++ 9 files changed, 73 insertions(+), 45 deletions(-) create mode 100644 src/lib.rs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c1157e8..09a9ae6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -89,7 +89,7 @@ jobs: - name: "Upload Binaries" uses: "taiki-e/upload-rust-binary-action@v1" with: - bin: "offchain-resolver-gateway" + bin: "ens-gateway" target: ${{ matrix.target }} archive: $bin-${{ matrix.target }} ref: refs/tags/v${{ needs.get-tag.outputs.pkg-version }} diff --git a/Cargo.lock b/Cargo.lock index 0ceeaa1..e788d5b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -842,6 +842,27 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ens-offchain-resolver-gateway" +version = "0.1.2" +dependencies = [ + "async-trait", + "ccip-read-server", + "chrono", + "clap", + "color-eyre", + "ethers", + "ethers-ccip-read", + "eyre", + "openssl", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "tracing-subscriber", +] + [[package]] name = "errno" version = "0.3.1" @@ -2094,27 +2115,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "offchain-resolver-gateway" -version = "0.1.1" -dependencies = [ - "async-trait", - "ccip-read-server", - "chrono", - "clap", - "color-eyre", - "ethers", - "ethers-ccip-read", - "eyre", - "openssl", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", - "tracing-subscriber", -] - [[package]] name = "once_cell" version = "1.18.0" diff --git a/Cargo.toml b/Cargo.toml index bfae093..027113f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,16 @@ [package] -name = "offchain-resolver-gateway" -version = "0.1.1" +name = "ens-offchain-resolver-gateway" +version = "0.1.2" edition = "2021" +[lib] +name = "ens_gateway_server" +path = "src/lib.rs" + +[[bin]] +name = "ens-gateway" +path = "src/main.rs" + [dependencies] ccip-read-server = "0.1.0" diff --git a/Dockerfile b/Dockerfile index 57d0286..a62db79 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,9 +5,9 @@ WORKDIR /opt/ RUN apk add curl protoc musl-dev gzip git # offchain-resolver-gateway -RUN curl -sLO https://github.com/jeje/ens-offchain-resolver-gateway-rs/releases/latest/download/offchain-resolver-gateway-x86_64-unknown-linux-musl.tar.gz \ - && tar -xvf offchain-resolver-gateway-x86_64-unknown-linux-musl.tar.gz \ - && chmod +x offchain-resolver-gateway +RUN curl -sLO https://github.com/jeje/ens-offchain-resolver-gateway-rs/releases/latest/download/ens-gateway-x86_64-unknown-linux-musl.tar.gz \ + && tar -xvf ens-gateway-x86_64-unknown-linux-musl.tar.gz \ + && chmod +x ens-gateway ######################################################### @@ -15,7 +15,7 @@ FROM alpine:3.16.2 RUN apk add tmux -COPY --from=builder /opt/offchain-resolver-gateway /opt/offchain-resolver-gateway +COPY --from=builder /opt/ens-gateway /opt/ens-gateway RUN chown -R root:root /opt/ @@ -24,4 +24,4 @@ ENV TTL 300 ENV LISTEN_IP 0.0.0.0 ENV LISTEN_PORT 8080 -ENTRYPOINT [ "/opt/offchain-resolver-gateway" ] \ No newline at end of file +ENTRYPOINT [ "/opt/ens-gateway" ] \ No newline at end of file diff --git a/README.md b/README.md index ba405a5..01c05cb 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,15 @@ Precompiled ENS gateways are available in [releases page](https://github.com/jej A Docker image is also available: https://hub.docker.com/r/jeje/ens-offchain-resolver-gateway-rs +Lastly a library is provided to ease implementation of custom gateways without duplicating much code. +A good sample is the [default implementation provided](src/main.rs). + ### CLI Usage ``` ENS Offchain Gateway server answering requests from CCIP-READ protocol (aka ERC-3668) -Usage: offchain-resolver-gateway [OPTIONS] --privatekey <--json > +Usage: ens-gateway [OPTIONS] --privatekey <--json > Options: -k, --privatekey private key of the wallet allowed to sign offchain ENS record results [env: PRIVATE_KEY] diff --git a/src/errors.rs b/src/errors.rs index 6866ede..f8ec846 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,17 +1,24 @@ use thiserror::Error; +/// ENS gateway errors #[derive(Error, Debug)] pub enum GatewayErrors { - #[error("invalid dns name")] + /// Invalid ENS name error + #[error("invalid ENS name")] InvalidName, + /// ABI error #[error("ABI error {0}")] Abi(#[from] ethers::contract::AbiError), + /// ABI Parsing error #[error("ABI parse error {0}")] AbiParse(#[from] ethers::abi::ParseError), + /// CCIP-Read server error #[error("CCIP Read error {0}")] CCIPReadMiddleware(#[from] ccip_read_server::CCIPReadMiddlewareError), + /// Unknown ENS record type error #[error("unknown record type")] UnknownRecordType, + /// Invalid signature error #[error("signature error")] Signature(#[from] ethers::types::SignatureError), } diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..199d9d5 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,18 @@ +//! ENS offchain resolver gateway framework + +/// Various offchain database storage options +pub mod db; +/// Errors +pub mod errors; +/// Gateway framework +pub mod gateway; +/// Utils +pub mod utils; + +use ethers::prelude::abigen; + +abigen!( + Resolver, + "./res/Resolver.json", + event_derives(serde::Deserialize, serde::Serialize) +); diff --git a/src/main.rs b/src/main.rs index d1aeb49..d24b057 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,7 @@ -use crate::db::{Database, JsonDatabase}; -use crate::gateway::Gateway; use clap::{arg, command, value_parser, ArgGroup}; use color_eyre::Report; -use ethers::prelude::abigen; +use ens_gateway_server::db::{Database, JsonDatabase}; +use ens_gateway_server::gateway::Gateway; use ethers::signers::{LocalWallet, Signer}; use eyre::Result; use std::env; @@ -13,17 +12,6 @@ use tracing::info; use tracing_subscriber::prelude::*; use tracing_subscriber::EnvFilter; -mod db; -mod errors; -mod gateway; -mod utils; - -abigen!( - Resolver, - "./res/Resolver.json", - event_derives(serde::Deserialize, serde::Serialize) -); - #[tokio::main] async fn main() -> Result<(), Report> { let matches = command!() diff --git a/src/utils.rs b/src/utils.rs index 381c594..3a1280b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,6 +2,7 @@ use crate::errors::GatewayErrors; use ethers::abi::{AbiEncode, Token}; use ethers::types::Signature; +/// Decode DNS name from call data, parsing ENS labels pub fn decode_dns_name(dns_name: &Token) -> Result { if let Some(dns_name) = dns_name.clone().into_bytes() { let mut labels = vec![]; @@ -20,6 +21,9 @@ pub fn decode_dns_name(dns_name: &Token) -> Result { } } +/// Compute `yParityAndS` from a signature +/// +/// EIP-2098: pub fn compact_y_parity_and_s(sig: &Signature) -> Result, GatewayErrors> { let mut y_parity_and_s = sig.s.encode(); if sig.recovery_id()?.is_y_odd() {