@@ -5,7 +5,10 @@ use alloy::rpc::types::request::{TransactionInput, TransactionRequest};
5
5
use alloy:: { hex, primitives:: keccak256} ;
6
6
use alloy_primitives:: { Address , Bytes , FixedBytes , B256 } ;
7
7
use alloy_sol_types:: { SolCall , SolEvent , SolValue } ;
8
+ use contract:: tokenCall;
8
9
use serde:: { Deserialize , Serialize } ;
10
+ use std:: error:: Error ;
11
+ use std:: fmt;
9
12
use std:: str:: FromStr ;
10
13
11
14
/// kimap deployment address on optimism
@@ -210,12 +213,19 @@ pub mod contract {
210
213
211
214
function supportsInterface( bytes4 interfaceId) external view returns ( bool ) ;
212
215
213
- /// Retrieves the address of the ERC-6551 implementation of the
214
- /// zeroth entry. This is set once at initialization.
216
+ /// Gets the token identifier that owns this token-bound account (TBA).
217
+ /// This is a core function of the ERC-6551 standard that returns the
218
+ /// identifying information about the NFT that owns this account.
219
+ /// The return values are constant and cannot change over time.
215
220
///
216
221
/// Returns:
217
- /// - implementation: The address of the ERC-6551 implementation.
218
- function get6551Implementation( ) external view returns ( address) ;
222
+ /// - chainId: The EIP-155 chain ID where the owning NFT exists
223
+ /// - tokenContract: The contract address of the owning NFT
224
+ /// - tokenId: The token ID of the owning NFT
225
+ function token( )
226
+ external
227
+ view
228
+ returns ( uint256 chainId, address tokenContract, uint256 tokenId) ;
219
229
}
220
230
}
221
231
@@ -259,6 +269,21 @@ pub enum DecodeLogError {
259
269
UnresolvedParent ( String ) ,
260
270
}
261
271
272
+ impl fmt:: Display for DecodeLogError {
273
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
274
+ match self {
275
+ DecodeLogError :: UnexpectedTopic ( topic) => write ! ( f, "Unexpected topic: {:?}" , topic) ,
276
+ DecodeLogError :: InvalidName ( name) => write ! ( f, "Invalid name: {}" , name) ,
277
+ DecodeLogError :: DecodeError ( err) => write ! ( f, "Decode error: {}" , err) ,
278
+ DecodeLogError :: UnresolvedParent ( parent) => {
279
+ write ! ( f, "Could not resolve parent: {}" , parent)
280
+ }
281
+ }
282
+ }
283
+ }
284
+
285
+ impl Error for DecodeLogError { }
286
+
262
287
/// Canonical function to determine if a kimap entry is valid. This should
263
288
/// be used whenever reading a new kimap entry from a mints query, because
264
289
/// while most frontends will enforce these rules, it is possible to post
@@ -514,6 +539,28 @@ impl Kimap {
514
539
Ok ( ( res. tba , res. owner , note_data) )
515
540
}
516
541
542
+ /// Gets a namehash from an existing TBA address.
543
+ ///
544
+ /// # Parameters
545
+ /// - `tba`: The TBA to get the namehash of.
546
+ /// # Returns
547
+ /// A `Result<String, EthError>` representing the namehash of the TBA.
548
+ pub fn get_namehash_from_tba ( & self , tba : Address ) -> Result < String , EthError > {
549
+ let token_call = tokenCall { } . abi_encode ( ) ;
550
+
551
+ let tx_req = TransactionRequest :: default ( )
552
+ . input ( TransactionInput :: new ( token_call. into ( ) ) )
553
+ . to ( tba) ;
554
+
555
+ let res_bytes = self . provider . call ( tx_req, None ) ?;
556
+
557
+ let res = tokenCall:: abi_decode_returns ( & res_bytes, false )
558
+ . map_err ( |_| EthError :: RpcMalformedResponse ) ?;
559
+
560
+ let namehash: FixedBytes < 32 > = res. tokenId . into ( ) ;
561
+ Ok ( format ! ( "0x{}" , hex:: encode( namehash) ) )
562
+ }
563
+
517
564
/// Create a filter for all mint events.
518
565
pub fn mint_filter ( & self ) -> crate :: eth:: Filter {
519
566
crate :: eth:: Filter :: new ( )
0 commit comments