Skip to main content

clear_signing/types/
context.rs

1//! Deployment context types: contract deployments and EIP-712 domain bindings.
2
3use serde::{Deserialize, Serialize};
4
5/// Top-level context discriminator — either contract (calldata) or eip712.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7#[serde(untagged)]
8pub enum DescriptorContext {
9    Contract(ContractContext),
10    Eip712(Eip712Context),
11}
12
13/// Context for contract calldata clear signing.
14/// v2: no `abi` field — ABI is derived from function signatures in format keys.
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct ContractContext {
17    #[serde(rename = "$id")]
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub id: Option<String>,
20
21    pub contract: ContractInfo,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct ContractInfo {
26    #[serde(default)]
27    pub deployments: Vec<Deployment>,
28
29    /// Factory deployment info for factory-deployed contracts.
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub factory: Option<FactoryInfo>,
32}
33
34/// Factory deployment information.
35#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct FactoryInfo {
37    /// Event signature emitted on deployment (e.g., "ContractCreated(address)").
38    #[serde(rename = "deployEvent")]
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub deploy_event: Option<String>,
41
42    /// Factory contract deployments.
43    #[serde(default)]
44    pub deployments: Vec<Deployment>,
45}
46
47/// Context for EIP-712 typed data clear signing.
48/// v2: no `schemas` field — deprecated.
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct Eip712Context {
51    #[serde(rename = "$id")]
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub id: Option<String>,
54
55    pub eip712: Eip712Info,
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct Eip712Info {
60    #[serde(default)]
61    pub deployments: Vec<Deployment>,
62
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub domain: Option<Eip712Domain>,
65
66    /// Domain separator hash validated during typed-data formatting.
67    #[serde(rename = "domainSeparator")]
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub domain_separator: Option<String>,
70}
71
72#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct Eip712Domain {
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub name: Option<String>,
76
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub version: Option<String>,
79
80    #[serde(rename = "chainId")]
81    #[serde(skip_serializing_if = "Option::is_none")]
82    pub chain_id: Option<u64>,
83
84    #[serde(rename = "verifyingContract")]
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub verifying_contract: Option<String>,
87
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub salt: Option<String>,
90}
91
92/// A single chain + address deployment entry.
93#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct Deployment {
95    #[serde(rename = "chainId")]
96    pub chain_id: u64,
97
98    pub address: String,
99}
100
101impl DescriptorContext {
102    pub fn deployments(&self) -> &[Deployment] {
103        match self {
104            DescriptorContext::Contract(c) => &c.contract.deployments,
105            DescriptorContext::Eip712(e) => &e.eip712.deployments,
106        }
107    }
108}