Skip to main content

hypercall_api/directives/
encoding.rs

1use crate::directives::models::ParsedAction;
2use crate::error::ApiError;
3use alloy::primitives::Address;
4use hypercall_types::directives::ActionKey;
5
6pub fn encode_action_bytes(version: u8, id: u32, inner_abi: &[u8]) -> Result<Vec<u8>, ApiError> {
7    if id > 0x00ff_ffff {
8        return Err(ApiError::internal_error(format!(
9            "action id {} exceeds uint24 range",
10            id
11        )));
12    }
13
14    let mut encoded = Vec::with_capacity(4 + inner_abi.len());
15    encoded.push(version);
16    let id_bytes = id.to_be_bytes();
17    encoded.extend_from_slice(&id_bytes[1..]);
18    encoded.extend_from_slice(inner_abi);
19    Ok(encoded)
20}
21
22pub fn encode_directive(account: Address, nonce: u64, action_bytes: &[u8]) -> Vec<u8> {
23    let mut directive = Vec::with_capacity(28 + action_bytes.len());
24    directive.extend_from_slice(account.as_slice());
25    directive.extend_from_slice(&nonce.to_be_bytes());
26    directive.extend_from_slice(action_bytes);
27    directive
28}
29
30pub fn encode_directive_for_action(
31    action_key: ActionKey,
32    account: Address,
33    nonce: u64,
34    action: &ParsedAction,
35) -> Result<Vec<u8>, ApiError> {
36    let inner_abi = action.encode_inner_abi();
37
38    let spec = action_key.spec();
39    let action_bytes = encode_action_bytes(spec.version, spec.id, &inner_abi)?;
40    Ok(encode_directive(account, nonce, &action_bytes))
41}