Skip to content

Add payload hash to signer JWT claims #356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 137 commits into
base: sigp-audit-fixes
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
137 commits
Select commit Hold shift + click to select a range
c68125d
bump version
ltitanb Apr 2, 2025
d9979a2
Successful cross-compilation, but runtime has memory allocation issues
jclapis May 5, 2025
97ef653
Working with OpenSSL static-linked
jclapis May 6, 2025
91eefe2
Got dynamic linking working, added a feature flag to toggle dynamic v…
jclapis May 6, 2025
de09415
Fixed the vendored build arg
jclapis May 6, 2025
3aee63d
Reintroduced the cargo chef setup
jclapis May 6, 2025
c07c717
Ported the cross-compilation stuff into PBS
jclapis May 6, 2025
699b7ec
Split the dockerfiles into separate builder / image definitions
jclapis May 7, 2025
7165f12
Added a build guide
jclapis May 7, 2025
9438dae
Refactored the Github release action to use the Docker builder
jclapis May 13, 2025
12c020a
Fixed the Docker image binary filenames
jclapis May 13, 2025
53cafc0
Cleaned up the Darwin artifact step
jclapis May 13, 2025
58c6117
Made the CI workflow and justfile use the same toolchain as the source
jclapis May 14, 2025
45e581b
Revert "Made the CI workflow and justfile use the same toolchain as t…
jclapis May 14, 2025
24a10c5
Testing removal of OpenSSL vendored option
jclapis May 14, 2025
e36da54
Updating just in the CI workflow
jclapis May 14, 2025
843b110
Merge branch 'main' into cross-compile
jclapis May 28, 2025
e7c6d19
Refactored the signer to support host and port config settings
jclapis May 21, 2025
6117219
Updated docs
jclapis May 21, 2025
c0f591d
Fixing Clippy in CI workflow
jclapis May 21, 2025
adbd34a
Removed obviated CI setup
jclapis May 28, 2025
e3488b3
Minor dedup of RwLock guard acquisition
jclapis May 20, 2025
c3d7ec4
Added rate limiting for signer clients with repeated JWT auth failures
jclapis May 22, 2025
9ddad64
Added Signer config validation
jclapis May 22, 2025
c62185e
Started unit test setup for the Signer
jclapis May 22, 2025
dc73c62
Finished a basic signer module unit test
jclapis May 28, 2025
6c3d967
Added a JWT failure unit test
jclapis May 28, 2025
6464638
Added a rate limit test and cleaned up a bit
jclapis May 28, 2025
0313f18
Added unique ports to unit tests for parallel execution
jclapis May 28, 2025
346eea4
Cleaned up the build Dockerfile and removed an extra dependency layer
jclapis May 28, 2025
7b20d2f
Ported the build script over to the justfile
jclapis May 29, 2025
cf3f0b1
Merge branch 'main' into cross-compile
jclapis May 29, 2025
ca9f4a1
Added a justfile recipe for installing protoc
jclapis May 29, 2025
3eed526
Merge branch 'cross-compile' into add-ip-bind-to-signer
jclapis May 29, 2025
aa6ad96
Merge branch 'add-ip-bind-to-signer' into rate-limit-jwt
jclapis May 29, 2025
fc872ac
Merge branch 'main' into add-ip-bind-to-signer
jclapis Jun 3, 2025
ca0c6e8
Merge branch 'add-ip-bind-to-signer' into rate-limit-jwt
jclapis Jun 3, 2025
40d34aa
Merge branch 'main' into add-ip-bind-to-signer
jclapis Jun 9, 2025
d537288
Update crates/cli/src/docker_init.rs
jclapis Jun 9, 2025
7afb763
Added example signer config params
jclapis Jun 9, 2025
09ac821
Cleaned up signer config loading from feedback
jclapis Jun 9, 2025
cf39d86
Merge remote-tracking branch 'origin/add-ip-bind-to-signer' into add-…
jclapis Jun 9, 2025
2431937
Merge branch 'add-ip-bind-to-signer' into rate-limit-jwt
jclapis Jun 9, 2025
2e1198b
Merge branch 'main' into rate-limit-jwt
jclapis Jun 9, 2025
ccaf97d
Added JWT auth fields to the example config
jclapis Jun 10, 2025
145ebe8
Started building the JWT config file
jclapis Jun 12, 2025
bb0e023
Added tests
jclapis Jun 12, 2025
71a7605
Started migration from JWTS_ENV to the config file
jclapis Jun 12, 2025
615774e
Signing requests now uses the module's signing ID
jclapis Jun 16, 2025
af6076d
Finished added signing ID support and a quick test
jclapis Jun 17, 2025
cc13a6f
Fixed some example config parameters
jclapis Jun 18, 2025
488547a
Added a test to ensure modules can't create the same sigs
jclapis Jun 18, 2025
ef3d8f2
Merge branch 'rate-limit-jwt' into prevent-cross-module-sigs
jclapis Jun 18, 2025
6fd4327
Made the jwt_config_file optional
jclapis Jun 18, 2025
d9ef82f
Started working on docs
jclapis Jun 24, 2025
83db727
Redid implementation with the original JWTS env var
jclapis Jun 26, 2025
8d08c11
Started the signer doc
jclapis Jun 26, 2025
64b49f2
Overhauled the signing_id setup to be directly in the signed struct
jclapis Jul 1, 2025
8b65b1e
Made proposer commitments nested Merkle trees to allow Dirk support
jclapis Jul 1, 2025
9967033
Added the signer request guide
jclapis Jul 1, 2025
adb1cb8
Added quotes to some HTML
jclapis Jul 1, 2025
1c3a07d
Added some simple JWT secret info
jclapis Jul 2, 2025
daf3147
Adding a closing tag
jclapis Jul 2, 2025
fa36a34
Merge branch 'main' into prevent-cross-module-sigs
jclapis Jul 8, 2025
0fd8480
Started refactoring the signer API
jclapis Jul 8, 2025
d5641df
Added prop commit signature verification helpers for modules to use
jclapis Jul 9, 2025
5da31bf
Fixed some params in da_commit
jclapis Jul 10, 2025
bfd72c5
Merge branch 'main' into prevent-cross-module-sigs
jclapis Jul 14, 2025
1a0efec
Cleaned load_module_signing_configs a bit
jclapis Jul 14, 2025
ee282da
Fixed some docs language
jclapis Jul 14, 2025
133447d
Refactored into compute_prop_commit_signing_root
jclapis Jul 15, 2025
9f72aff
Merge branch 'main' into prevent-cross-module-sigs
jclapis Jul 28, 2025
509dba8
Signing IDs are no longer optional in the config
jclapis Jul 28, 2025
2c507d7
Refactored some of the signer consts for consistency
jclapis Jul 28, 2025
d1ad9c9
Merge branch 'refactor-signer-consts' into prevent-cross-module-sigs
jclapis Jul 28, 2025
58f2ad7
Merge branch 'prevent-cross-module-sigs' into signer-json-api
jclapis Jul 28, 2025
ff716a0
Updated the Signer API docs
jclapis Jul 29, 2025
c6565ed
Merged sigp-audit-fixes
jclapis Jul 29, 2025
472fcf7
sync rwlock fix (#349)
ltitanb Jul 29, 2025
50b7ce8
Minor fixes
jclapis Jul 29, 2025
281b03c
Merge branch 'update-cbst2-02' into signer-json-api
jclapis Jul 29, 2025
ec300dc
Signing requests return JSON now
jclapis Jul 29, 2025
7939b24
Updated the signer OpenAPI spec
jclapis Jul 29, 2025
d993a8a
Updated da_commit
jclapis Jul 29, 2025
bd91972
Merge branch 'sigp-audit-fixes' into update-cbst2-02
jclapis Jul 30, 2025
688d82d
Cleaned up an unwrap()
jclapis Jul 30, 2025
d4a7eb2
Merge branch 'update-cbst2-02' into signer-json-api
jclapis Jul 30, 2025
de61066
Merge sigp-audit-fixes (#348)
jclapis Jul 30, 2025
db08d77
Merge branch 'sigp-audit-fixes' into prevent-cross-module-sigs
jclapis Jul 30, 2025
ce29c3a
Move from [u8; 32] to B256 everywhere (#347)
jclapis Jul 30, 2025
b837e44
Merge branch 'sigp-audit-fixes' into prevent-cross-module-sigs
jclapis Jul 31, 2025
e0fa6cb
Merge branch 'prevent-cross-module-sigs' into signer-json-api
jclapis Jul 31, 2025
874e07d
Cleaned up some hashmap usage
jclapis Aug 4, 2025
3ad11a8
Removed compute_tree_hash_root()
jclapis Aug 4, 2025
a75605e
Some minor cleanup
jclapis Aug 4, 2025
d091a90
Fixed some docs
jclapis Aug 4, 2025
4a832ca
Added nonces to signing requests and chain ID to signing info
jclapis Aug 6, 2025
e63fc3f
Relaxed the signing struct types
jclapis Aug 7, 2025
75d040e
Finished updating docs
jclapis Aug 7, 2025
8e01755
Reset chain ID to u64 for this branch
jclapis Aug 7, 2025
51e572a
Fixed the rest of the tests
jclapis Aug 7, 2025
7649971
Merge branch 'prevent-cross-module-sigs' into signer-json-api
jclapis Aug 7, 2025
0d78b0f
Merge branch 'signer-json-api' into add-payload-hash-to-jwt
jclapis Aug 7, 2025
b449049
Added nonce and chain_id to signature response
jclapis Aug 7, 2025
26e8b50
Started updating the JWT
jclapis Aug 7, 2025
58d87cd
Removed a comment
jclapis Aug 7, 2025
22128c6
Merge branch 'augment-sign-requests' into add-payload-hash-to-jwt
jclapis Aug 7, 2025
21a3856
Removed a comment
jclapis Aug 7, 2025
33d9110
Merge branch 'augment-sign-requests' into add-payload-hash-to-jwt
jclapis Aug 11, 2025
28b10f7
Added payload hashes to JWT claims
jclapis Aug 12, 2025
66c0695
Updated the signer API doc with the JWT claims
jclapis Aug 12, 2025
900f0f8
Added payload hash checking to the JWT admin routes
jclapis Aug 12, 2025
4720b93
Added admin routes to the OpenAPI spec
jclapis Aug 12, 2025
7293e5c
change chain IDs to 256-bit numbers (#353)
jclapis Aug 12, 2025
0313cc2
Merge branch 'sigp-audit-fixes' into prevent-cross-module-sigs
jclapis Aug 12, 2025
2e746ce
Merge branch 'prevent-cross-module-sigs' into signer-json-api
jclapis Aug 12, 2025
a44beeb
Merge branch 'signer-json-api' into augment-sign-requests
jclapis Aug 12, 2025
bc5c0b6
Merge branch 'augment-sign-requests' into add-payload-hash-to-jwt
jclapis Aug 12, 2025
2041fdc
Removed non-signer routes from the signer API spec
jclapis Aug 13, 2025
f25f6fe
Cleaned up the client a bit
jclapis Aug 13, 2025
358b3cb
Merge branch 'sigp-audit-fixes' into prevent-cross-module-sigs
jclapis Aug 13, 2025
bee0de5
Merge branch 'prevent-cross-module-sigs' into signer-json-api
jclapis Aug 13, 2025
3345ef0
Merge branch 'signer-json-api' into augment-sign-requests
jclapis Aug 13, 2025
69a515a
Merge branch 'augment-sign-requests' into add-payload-hash-to-jwt
jclapis Aug 13, 2025
53888a1
Removed extraneous Display() impls
jclapis Aug 18, 2025
228cbec
Cleaned up the signature request handlers
jclapis Aug 19, 2025
a306f23
Consolidated similar bodies for signing handlers
jclapis Aug 19, 2025
dc90028
Merge branch 'sigp-audit-fixes' into signer-json-api
jclapis Aug 19, 2025
46ec92b
Merge branch 'signer-json-api' into augment-sign-requests
jclapis Aug 19, 2025
dfbdcc4
Fixed a proxy signing bug
jclapis Aug 19, 2025
ec37c65
Merge branch 'signer-json-api' into augment-sign-requests
jclapis Aug 19, 2025
dd63e7c
Fixed the default nonce
jclapis Aug 19, 2025
ad3a7fe
Merge branch 'augment-sign-requests' into add-payload-hash-to-jwt
jclapis Aug 19, 2025
fdc1b95
Removed an old use
jclapis Aug 19, 2025
5fcd187
Merge branch 'augment-sign-requests' into add-payload-hash-to-jwt
jclapis Aug 19, 2025
f0fe2b4
Update crates/signer/src/service.rs
jclapis Aug 19, 2025
79285f8
Update crates/signer/src/service.rs
jclapis Aug 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ cb-signer = { path = "crates/signer" }
cipher = "0.4"
clap = { version = "4.5.4", features = ["derive", "env"] }
color-eyre = "0.6.3"
const_format = "0.2.34"
ctr = "0.9.2"
derive_more = { version = "2.0.1", features = ["deref", "display", "from", "into"] }
docker-compose-types = "0.16.0"
Expand Down
445 changes: 384 additions & 61 deletions api/signer-api.yml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions crates/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ bimap.workspace = true
blst.workspace = true
bytes.workspace = true
cipher.workspace = true
const_format.workspace = true
ctr.workspace = true
derive_more.workspace = true
docker-image.workspace = true
Expand Down
60 changes: 41 additions & 19 deletions crates/common/src/commit/client.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
use std::time::{Duration, Instant};

use alloy::{primitives::Address, rpc::types::beacon::BlsSignature};
use alloy::primitives::Address;
use eyre::WrapErr;
use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION};
use serde::Deserialize;
use serde::{Deserialize, Serialize};
use url::Url;

use super::{
constants::{GENERATE_PROXY_KEY_PATH, GET_PUBKEYS_PATH, REQUEST_SIGNATURE_PATH},
constants::{GENERATE_PROXY_KEY_PATH, GET_PUBKEYS_PATH},
error::SignerClientError,
request::{
EncryptionScheme, GenerateProxyRequest, GetPubkeysResponse, ProxyId, SignConsensusRequest,
SignProxyRequest, SignRequest, SignedProxyDelegation,
SignProxyRequest, SignedProxyDelegation,
},
};
use crate::{
commit::{
constants::{
REQUEST_SIGNATURE_BLS_PATH, REQUEST_SIGNATURE_PROXY_BLS_PATH,
REQUEST_SIGNATURE_PROXY_ECDSA_PATH,
},
response::{BlsSignResponse, EcdsaSignResponse},
},
constants::SIGNER_JWT_EXPIRATION,
signer::{BlsPublicKey, EcdsaSignature},
signer::BlsPublicKey,
types::{Jwt, ModuleId},
utils::create_jwt,
DEFAULT_REQUEST_TIMEOUT,
Expand All @@ -36,7 +43,7 @@ pub struct SignerClient {
impl SignerClient {
/// Create a new SignerClient
pub fn new(signer_server_url: Url, jwt_secret: Jwt, module_id: ModuleId) -> eyre::Result<Self> {
let jwt = create_jwt(&module_id, &jwt_secret)?;
let jwt = create_jwt(&module_id, &jwt_secret, None)?;

let mut auth_value =
HeaderValue::from_str(&format!("Bearer {}", jwt)).wrap_err("invalid jwt")?;
Expand All @@ -61,7 +68,7 @@ impl SignerClient {

fn refresh_jwt(&mut self) -> Result<(), SignerClientError> {
if self.last_jwt_refresh.elapsed() > Duration::from_secs(SIGNER_JWT_EXPIRATION) {
let jwt = create_jwt(&self.module_id, &self.jwt_secret)?;
let jwt = create_jwt(&self.module_id, &self.jwt_secret, None)?;

let mut auth_value =
HeaderValue::from_str(&format!("Bearer {}", jwt)).wrap_err("invalid jwt")?;
Expand All @@ -79,6 +86,16 @@ impl SignerClient {
Ok(())
}

fn create_jwt_for_payload<T: Serialize>(
&mut self,
payload: &T,
) -> Result<Jwt, SignerClientError> {
let payload_vec = serde_json::to_vec(payload)?;
create_jwt(&self.module_id, &self.jwt_secret, Some(&payload_vec))
.wrap_err("failed to create JWT for payload")
.map_err(SignerClientError::JWTError)
}

/// Request a list of validator pubkeys for which signatures can be
/// requested.
// TODO: add more docs on how proxy keys work
Expand All @@ -99,14 +116,19 @@ impl SignerClient {
}

/// Send a signature request
async fn request_signature<T>(&mut self, request: &SignRequest) -> Result<T, SignerClientError>
async fn request_signature<Q, T>(
&mut self,
route: &str,
request: &Q,
) -> Result<T, SignerClientError>
where
Q: Serialize,
T: for<'de> Deserialize<'de>,
{
self.refresh_jwt()?;
let jwt = self.create_jwt_for_payload(request)?;

let url = self.url.join(REQUEST_SIGNATURE_PATH)?;
let res = self.client.post(url).json(&request).send().await?;
let url = self.url.join(route)?;
let res = self.client.post(url).json(&request).bearer_auth(jwt).send().await?;

let status = res.status();
let response_bytes = res.bytes().await?;
Expand All @@ -126,22 +148,22 @@ impl SignerClient {
pub async fn request_consensus_signature(
&mut self,
request: SignConsensusRequest,
) -> Result<BlsSignature, SignerClientError> {
self.request_signature(&request.into()).await
) -> Result<BlsSignResponse, SignerClientError> {
self.request_signature(REQUEST_SIGNATURE_BLS_PATH, &request).await
}

pub async fn request_proxy_signature_ecdsa(
&mut self,
request: SignProxyRequest<Address>,
) -> Result<EcdsaSignature, SignerClientError> {
self.request_signature(&request.into()).await
) -> Result<EcdsaSignResponse, SignerClientError> {
self.request_signature(REQUEST_SIGNATURE_PROXY_ECDSA_PATH, &request).await
}

pub async fn request_proxy_signature_bls(
&mut self,
request: SignProxyRequest<BlsPublicKey>,
) -> Result<BlsSignature, SignerClientError> {
self.request_signature(&request.into()).await
) -> Result<BlsSignResponse, SignerClientError> {
self.request_signature(REQUEST_SIGNATURE_PROXY_BLS_PATH, &request).await
}

async fn generate_proxy_key<T>(
Expand All @@ -151,10 +173,10 @@ impl SignerClient {
where
T: ProxyId + for<'de> Deserialize<'de>,
{
self.refresh_jwt()?;
let jwt = self.create_jwt_for_payload(request)?;

let url = self.url.join(GENERATE_PROXY_KEY_PATH)?;
let res = self.client.post(url).json(&request).send().await?;
let res = self.client.post(url).json(&request).bearer_auth(jwt).send().await?;

let status = res.status();
let response_bytes = res.bytes().await?;
Expand Down
9 changes: 8 additions & 1 deletion crates/common/src/commit/constants.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
use const_format::concatcp;

pub const GET_PUBKEYS_PATH: &str = "/signer/v1/get_pubkeys";
pub const REQUEST_SIGNATURE_PATH: &str = "/signer/v1/request_signature";
pub const REQUEST_SIGNATURE_BASE_PATH: &str = "/signer/v1/request_signature";
pub const REQUEST_SIGNATURE_BLS_PATH: &str = concatcp!(REQUEST_SIGNATURE_BASE_PATH, "/bls");
pub const REQUEST_SIGNATURE_PROXY_BLS_PATH: &str =
concatcp!(REQUEST_SIGNATURE_BASE_PATH, "/proxy-bls");
pub const REQUEST_SIGNATURE_PROXY_ECDSA_PATH: &str =
concatcp!(REQUEST_SIGNATURE_BASE_PATH, "/proxy-ecdsa");
pub const GENERATE_PROXY_KEY_PATH: &str = "/signer/v1/generate_proxy_key";
pub const STATUS_PATH: &str = "/status";
pub const RELOAD_PATH: &str = "/reload";
Expand Down
1 change: 1 addition & 0 deletions crates/common/src/commit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pub mod client;
pub mod constants;
pub mod error;
pub mod request;
pub mod response;
123 changes: 52 additions & 71 deletions crates/common/src/commit/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use alloy::{
primitives::{aliases::B32, Address, B256},
rpc::types::beacon::BlsSignature,
};
use derive_more::derive::From;
use serde::{Deserialize, Deserializer, Serialize};
use tree_hash::TreeHash;
use tree_hash_derive::TreeHash;
Expand Down Expand Up @@ -74,53 +73,20 @@ impl<T: ProxyId> fmt::Display for SignedProxyDelegation<T> {
}
}

// TODO(David): This struct shouldn't be visible to module authors
#[derive(Debug, Clone, Serialize, Deserialize, From)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum SignRequest {
Consensus(SignConsensusRequest),
ProxyBls(SignProxyRequest<BlsPublicKey>),
ProxyEcdsa(SignProxyRequest<Address>),
}

impl Display for SignRequest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SignRequest::Consensus(req) => write!(
f,
"Consensus(pubkey: {}, object_root: {})",
req.pubkey,
hex::encode_prefixed(req.object_root)
),
SignRequest::ProxyBls(req) => write!(
f,
"BLS(proxy: {}, object_root: {})",
req.proxy,
hex::encode_prefixed(req.object_root)
),
SignRequest::ProxyEcdsa(req) => write!(
f,
"ECDSA(proxy: {}, object_root: {})",
req.proxy,
hex::encode_prefixed(req.object_root)
),
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SignConsensusRequest {
pub pubkey: BlsPublicKey,
pub object_root: B256,
pub nonce: u64,
}

impl SignConsensusRequest {
pub fn new(pubkey: BlsPublicKey, object_root: B256) -> Self {
Self { pubkey, object_root }
pub fn new(pubkey: BlsPublicKey, object_root: B256, nonce: u64) -> Self {
Self { pubkey, object_root, nonce }
}

pub fn builder(pubkey: BlsPublicKey) -> Self {
Self::new(pubkey, B256::ZERO)
Self::new(pubkey, B256::ZERO, u64::MAX - 1)
}

pub fn with_root<R: Into<B256>>(self, object_root: R) -> Self {
Expand All @@ -130,21 +96,38 @@ impl SignConsensusRequest {
pub fn with_msg(self, msg: &impl TreeHash) -> Self {
self.with_root(msg.tree_hash_root().0)
}

pub fn with_nonce(self, nonce: u64) -> Self {
Self { nonce, ..self }
}
}

impl Display for SignConsensusRequest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Consensus(pubkey: {}, object_root: {}, nonce: {})",
self.pubkey,
hex::encode_prefixed(self.object_root),
self.nonce
)
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SignProxyRequest<T: ProxyId> {
pub proxy: T,
pub object_root: B256,
pub nonce: u64,
}

impl<T: ProxyId> SignProxyRequest<T> {
pub fn new(proxy: T, object_root: B256) -> Self {
Self { proxy, object_root }
pub fn new(proxy: T, object_root: B256, nonce: u64) -> Self {
Self { proxy, object_root, nonce }
}

pub fn builder(proxy: T) -> Self {
Self::new(proxy, B256::ZERO)
Self::new(proxy, B256::ZERO, 0)
}

pub fn with_root<R: Into<B256>>(self, object_root: R) -> Self {
Expand All @@ -154,6 +137,34 @@ impl<T: ProxyId> SignProxyRequest<T> {
pub fn with_msg(self, msg: &impl TreeHash) -> Self {
self.with_root(msg.tree_hash_root().0)
}

pub fn with_nonce(self, nonce: u64) -> Self {
Self { nonce, ..self }
}
}

impl Display for SignProxyRequest<BlsPublicKey> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"BLS(proxy: {}, object_root: {}, nonce: {})",
self.proxy,
hex::encode_prefixed(self.object_root),
self.nonce
)
}
}

impl Display for SignProxyRequest<Address> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"ECDSA(proxy: {}, object_root: {}, nonce: {})",
self.proxy,
hex::encode_prefixed(self.object_root),
self.nonce
)
}
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
Expand Down Expand Up @@ -249,36 +260,6 @@ mod tests {
use super::*;
use crate::signer::EcdsaSignature;

#[test]
fn test_decode_request_signature() {
let data = r#"{
"type": "consensus",
"pubkey": "0xa3366b54f28e4bf1461926a3c70cdb0ec432b5c92554ecaae3742d33fb33873990cbed1761c68020e6d3c14d30a22050",
"object_root": "0x5c89913beafa0472168e0ec05e349b4ceb9985d25ab9fa8de53a60208c85b3a5"
}"#;

let request: SignRequest = serde_json::from_str(data).unwrap();
assert!(matches!(request, SignRequest::Consensus(..)));

let data = r#"{
"type": "proxy_bls",
"proxy": "0xa3366b54f28e4bf1461926a3c70cdb0ec432b5c92554ecaae3742d33fb33873990cbed1761c68020e6d3c14d30a22050",
"object_root": "0x5c89913beafa0472168e0ec05e349b4ceb9985d25ab9fa8de53a60208c85b3a5"
}"#;

let request: SignRequest = serde_json::from_str(data).unwrap();
assert!(matches!(request, SignRequest::ProxyBls(..)));

let data = r#"{
"type": "proxy_ecdsa",
"proxy": "0x4ca9939a8311a7cab3dde201b70157285fa81a9d",
"object_root": "0x5c89913beafa0472168e0ec05e349b4ceb9985d25ab9fa8de53a60208c85b3a5"
}"#;

let request: SignRequest = serde_json::from_str(data).unwrap();
assert!(matches!(request, SignRequest::ProxyEcdsa(..)));
}

#[test]
fn test_decode_response_signature() {
let data = r#""0xa3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989a3ffa9241f78279f1af04644cb8c79c2d8f02bcf0e28e2f186f6dcccac0a869c2be441fda50f0dea895cfce2e53f0989""#;
Expand Down
Loading