Skip to content

Commit a237fad

Browse files
committed
access-list getter
1 parent 8281514 commit a237fad

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

src/hypermap.rs

+50
Original file line numberDiff line numberDiff line change
@@ -619,4 +619,54 @@ impl Hypermap {
619619
.collect::<Vec<_>>(),
620620
)
621621
}
622+
623+
/// Gets the list of delegate addresses stored via the standard Hypermap access control pattern.
624+
/// This involves reading the `~access-list` note for the given `entry_path` to find the
625+
/// namehash of the permissions note, then reading that permissions note to get the
626+
/// ABI-encoded `Vec<Address>` of delegates.
627+
///
628+
/// # Arguments
629+
/// * `entry_path` - The base hypermap path (e.g., "myname.hypr") for which to find delegates.
630+
///
631+
/// # Returns
632+
/// A `Result<Vec<Address>, EthError>` containing the list of delegate addresses if found
633+
/// and decoded successfully, or an error otherwise.
634+
pub fn get_access_list_delegates(&self, entry_path: &str) -> Result<Vec<Address>, EthError> {
635+
// 1. Construct the path to the ~access-list note
636+
let access_list_path = format!("~access-list.{}", entry_path);
637+
638+
// 2. Get the ~access-list note data (expecting a B256 namehash)
639+
let (_tba, _owner, access_list_data_opt) = self.get(&access_list_path)?;
640+
641+
let access_list_data = access_list_data_opt.ok_or_else(|| {
642+
// Note not found or has no data - considered a malformed/unexpected response
643+
EthError::RpcMalformedResponse
644+
})?;
645+
646+
// 3. Decode the data as the permissions note hash (B256)
647+
// We expect the raw bytes stored in the note to be exactly 32 bytes.
648+
if access_list_data.len() != 32 {
649+
// Invalid data length - malformed response
650+
return Err(EthError::RpcMalformedResponse);
651+
}
652+
let perms_note_hash = B256::from_slice(access_list_data.as_ref());
653+
let perms_note_hash_str = format!("0x{}", hex::encode(perms_note_hash));
654+
655+
// 4. Get the permissions note using the hash
656+
let (_perms_tba, _perms_owner, perms_data_opt) =
657+
self.get_hash(&perms_note_hash_str)?;
658+
659+
let perms_data = perms_data_opt.ok_or_else(|| {
660+
// Permissions note not found or has no data - malformed/unexpected response
661+
EthError::RpcMalformedResponse
662+
})?;
663+
664+
// 5. Decode the permissions data as Vec<Address>
665+
let delegates = Vec::<Address>::abi_decode(&perms_data, true).map_err(|_e| {
666+
// Failed to decode Vec<Address> - malformed response
667+
EthError::RpcMalformedResponse
668+
})?;
669+
670+
Ok(delegates)
671+
}
622672
}

src/wallet.rs

+49
Original file line numberDiff line numberDiff line change
@@ -2152,3 +2152,52 @@ pub fn get_token_details(
21522152
formatted_balance,
21532153
})
21542154
}
2155+
2156+
//
2157+
// CALLDATA CREATION HELPERS
2158+
//
2159+
2160+
/// Creates the ABI-encoded calldata for an ERC20 `transfer` call.
2161+
///
2162+
/// # Arguments
2163+
/// * `recipient` - The address to transfer tokens to.
2164+
/// * `amount` - The amount of tokens to transfer (in the token's smallest unit, e.g., wei for ETH-like).
2165+
///
2166+
/// # Returns
2167+
/// A `Vec<u8>` containing the ABI-encoded calldata.
2168+
pub fn create_erc20_transfer_calldata(
2169+
recipient: EthAddress,
2170+
amount: U256,
2171+
) -> Vec<u8> {
2172+
let call = IERC20::transferCall { to: recipient, value: amount };
2173+
call.abi_encode()
2174+
}
2175+
2176+
/// Creates the ABI-encoded calldata for a Hypermap `note` call.
2177+
/// Performs validation on the note key format.
2178+
///
2179+
/// # Arguments
2180+
/// * `note_key` - The note key (e.g., "~my-note"). Must start with '~'.
2181+
/// * `data` - The byte data to store in the note.
2182+
///
2183+
/// # Returns
2184+
/// A `Result<Vec<u8>, WalletError>` containing the ABI-encoded calldata on success,
2185+
/// or a `WalletError::NameResolutionError` if the note key format is invalid.
2186+
pub fn create_hypermap_note_calldata(
2187+
note_key: &str,
2188+
data: Vec<u8>,
2189+
) -> Result<Vec<u8>, WalletError> {
2190+
// Validate the note key format
2191+
if !hypermap::valid_note(note_key) {
2192+
return Err(WalletError::NameResolutionError(format!(
2193+
"Invalid note key format: '{}'. Must start with '~' and follow naming rules.",
2194+
note_key
2195+
)));
2196+
}
2197+
2198+
let call = hypermap::contract::noteCall {
2199+
note: Bytes::from(note_key.as_bytes().to_vec()),
2200+
data: Bytes::from(data),
2201+
};
2202+
Ok(call.abi_encode())
2203+
}

0 commit comments

Comments
 (0)