Skip to content
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

Bp/kimap errors #134

Merged
merged 4 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 20 additions & 0 deletions src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ pub use alloy::rpc::types::{
pub use alloy_primitives::{Address, BlockHash, BlockNumber, Bytes, TxHash, U128, U256, U64, U8};
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::error::Error;
use std::fmt;

/// Subscription kind. Pulled directly from alloy (https://github.com/alloy-rs/alloy).
/// Why? Because alloy is not yet 1.0 and the types in this interface must be stable.
Expand Down Expand Up @@ -130,6 +132,24 @@ pub enum EthError {
RpcMalformedResponse,
}

impl fmt::Display for EthError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EthError::RpcError(e) => write!(f, "RPC error: {:?}", e),
EthError::MalformedRequest => write!(f, "Malformed request"),
EthError::NoRpcForChain => write!(f, "No RPC provider for chain"),
EthError::SubscriptionClosed(id) => write!(f, "Subscription {} closed", id),
EthError::InvalidMethod(m) => write!(f, "Invalid method: {}", m),
EthError::InvalidParams => write!(f, "Invalid parameters"),
EthError::PermissionDenied => write!(f, "Permission denied"),
EthError::RpcTimeout => write!(f, "RPC request timed out"),
EthError::RpcMalformedResponse => write!(f, "RPC returned malformed response"),
}
}
}

impl Error for EthError {}

/// The action type used for configuring eth:distro:sys. Only processes which have the "root"
/// [`crate::Capability`] from eth:distro:sys can successfully send this action.
#[derive(Clone, Debug, Serialize, Deserialize)]
Expand Down
55 changes: 51 additions & 4 deletions src/kimap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ use alloy::rpc::types::request::{TransactionInput, TransactionRequest};
use alloy::{hex, primitives::keccak256};
use alloy_primitives::{Address, Bytes, FixedBytes, B256};
use alloy_sol_types::{SolCall, SolEvent, SolValue};
use contract::tokenCall;
use serde::{Deserialize, Serialize};
use std::error::Error;
use std::fmt;
use std::str::FromStr;

/// kimap deployment address on optimism
Expand Down Expand Up @@ -210,12 +213,19 @@ pub mod contract {

function supportsInterface(bytes4 interfaceId) external view returns (bool);

/// Retrieves the address of the ERC-6551 implementation of the
/// zeroth entry. This is set once at initialization.
/// Gets the token identifier that owns this token-bound account (TBA).
/// This is a core function of the ERC-6551 standard that returns the
/// identifying information about the NFT that owns this account.
/// The return values are constant and cannot change over time.
///
/// Returns:
/// - implementation: The address of the ERC-6551 implementation.
function get6551Implementation() external view returns (address);
/// - chainId: The EIP-155 chain ID where the owning NFT exists
/// - tokenContract: The contract address of the owning NFT
/// - tokenId: The token ID of the owning NFT
function token()
external
view
returns (uint256 chainId, address tokenContract, uint256 tokenId);
}
}

Expand Down Expand Up @@ -259,6 +269,21 @@ pub enum DecodeLogError {
UnresolvedParent(String),
}

impl fmt::Display for DecodeLogError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DecodeLogError::UnexpectedTopic(topic) => write!(f, "Unexpected topic: {:?}", topic),
DecodeLogError::InvalidName(name) => write!(f, "Invalid name: {}", name),
DecodeLogError::DecodeError(err) => write!(f, "Decode error: {}", err),
DecodeLogError::UnresolvedParent(parent) => {
write!(f, "Could not resolve parent: {}", parent)
}
}
}
}

impl Error for DecodeLogError {}

/// Canonical function to determine if a kimap entry is valid. This should
/// be used whenever reading a new kimap entry from a mints query, because
/// while most frontends will enforce these rules, it is possible to post
Expand Down Expand Up @@ -514,6 +539,28 @@ impl Kimap {
Ok((res.tba, res.owner, note_data))
}

/// Gets a namehash from an existing TBA address.
///
/// # Parameters
/// - `tba`: The TBA to get the namehash of.
/// # Returns
/// A `Result<String, EthError>` representing the namehash of the TBA.
pub fn get_namehash_from_tba(&self, tba: Address) -> Result<String, EthError> {
let token_call = tokenCall {}.abi_encode();

let tx_req = TransactionRequest::default()
.input(TransactionInput::new(token_call.into()))
.to(tba);

let res_bytes = self.provider.call(tx_req, None)?;

let res = tokenCall::abi_decode_returns(&res_bytes, false)
.map_err(|_| EthError::RpcMalformedResponse)?;

let namehash: FixedBytes<32> = res.tokenId.into();
Ok(format!("0x{}", hex::encode(namehash)))
}

/// Create a filter for all mint events.
pub fn mint_filter(&self) -> crate::eth::Filter {
crate::eth::Filter::new()
Expand Down
4 changes: 2 additions & 2 deletions src/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ pub enum IndexerRequests {
#[derive(Clone, Debug, Serialize, Deserialize, Hash, Eq, PartialEq)]
pub struct NamehashToNameRequest {
pub hash: String,
pub block: Option<u64>,
pub block: u64,
}

/// Response from `kns-indexer:kns-indexer:sys`.
Expand Down Expand Up @@ -226,7 +226,7 @@ where
.body(
serde_json::to_vec(&IndexerRequests::NamehashToName(NamehashToNameRequest {
hash: namehash.into(),
block,
block: block.unwrap_or(0),
}))
.unwrap(),
)
Expand Down
Loading