@@ -20,7 +20,7 @@ use reqwest::Url;
2020use serde:: Deserialize ;
2121use sqlx:: { postgres:: PgListener , PgPool } ;
2222use thegraph_core:: {
23- alloy:: { primitives:: Address , sol_types:: Eip712Domain } ,
23+ alloy:: { hex :: ToHexExt , primitives:: Address , sol_types:: Eip712Domain } ,
2424 AllocationId as AllocationIdCore , CollectionId ,
2525} ;
2626use tokio:: { select, sync:: watch:: Receiver } ;
@@ -165,29 +165,64 @@ pub enum AllocationId {
165165}
166166
167167impl AllocationId {
168- /// Get a hex string representation for database queries
168+ /// Canonical hex (no 0x); 40 chars for Legacy, 64 for Horizon
169169 pub fn to_hex ( & self ) -> String {
170170 match self {
171- AllocationId :: Legacy ( allocation_id) => allocation_id. to_string ( ) ,
172- AllocationId :: Horizon ( collection_id) => collection_id. to_string ( ) ,
171+ AllocationId :: Legacy ( allocation_id) => ( * * allocation_id) . encode_hex ( ) ,
172+ AllocationId :: Horizon ( collection_id) => collection_id. encode_hex ( ) ,
173173 }
174174 }
175175
176- /// Get the underlying Address for Legacy allocations
176+ /// Get the underlying Address for Legacy allocations.
177+ ///
178+ /// Deprecated: Prefer `address()` which returns a normalized Address for both Legacy and Horizon.
179+ #[ deprecated(
180+ note = "Use `address()` for both Legacy and Horizon; this returns None for Horizon"
181+ ) ]
177182 pub fn as_address ( & self ) -> Option < Address > {
178183 match self {
179184 AllocationId :: Legacy ( allocation_id) => Some ( * * allocation_id) ,
180185 AllocationId :: Horizon ( _) => None ,
181186 }
182187 }
183188
189+ /// Legacy-only accessor returning an optional address.
190+ ///
191+ /// Returns:
192+ /// - Some(address) for Legacy allocations
193+ /// - None for Horizon allocations
194+ pub fn legacy_address ( & self ) -> Option < Address > {
195+ match self {
196+ AllocationId :: Legacy ( allocation_id) => Some ( * * allocation_id) ,
197+ AllocationId :: Horizon ( _) => None ,
198+ }
199+ }
200+
184201 /// Get an Address representation for both allocation types
185202 pub fn address ( & self ) -> Address {
186203 match self {
187204 AllocationId :: Legacy ( allocation_id) => * * allocation_id,
188205 AllocationId :: Horizon ( collection_id) => collection_id. as_address ( ) ,
189206 }
190207 }
208+
209+ /// Normalized 20-byte address as lowercase hex (no 0x prefix).
210+ ///
211+ /// Behavior:
212+ /// - Legacy (V1): returns the allocation address as hex.
213+ /// - Horizon (V2): derives the 20-byte address from the 32-byte `CollectionId`
214+ /// using `collection_id.as_address()` (last 20 bytes) and encodes as hex.
215+ ///
216+ /// Use for:
217+ /// - Actor names and routing (consistent identity across versions)
218+ /// - Metrics labels (uniform 20-byte form)
219+ /// - Network subgraph queries (which expect allocation addresses)
220+ ///
221+ /// Do NOT use for Horizon database queries where `collection_id` is stored
222+ /// as 32-byte hex; use `to_hex()` / `CollectionId::encode_hex()` instead.
223+ pub fn address_hex ( & self ) -> String {
224+ self . address ( ) . encode_hex ( )
225+ }
191226}
192227
193228impl Display for AllocationId {
0 commit comments