use async_trait::async_trait;
use aztec_core::abi::{AbiValue, FunctionSelector, FunctionType};
use aztec_core::constants::protocol_contract_address;
use aztec_core::tx::{ExecutionPayload, FunctionCall};
use aztec_core::types::{AztecAddress, Fr};
use aztec_core::Error;
use crate::fee_payment_method::FeePaymentMethod;
use crate::types::L2AmountClaim;
pub struct FeeJuicePaymentMethodWithClaim {
sender: AztecAddress,
claim: L2AmountClaim,
}
impl FeeJuicePaymentMethodWithClaim {
pub fn new(sender: AztecAddress, claim: L2AmountClaim) -> Self {
Self { sender, claim }
}
}
#[async_trait]
impl FeePaymentMethod for FeeJuicePaymentMethodWithClaim {
async fn get_asset(&self) -> Result<AztecAddress, Error> {
Ok(protocol_contract_address::fee_juice())
}
async fn get_fee_payer(&self) -> Result<AztecAddress, Error> {
Ok(self.sender)
}
async fn get_fee_execution_payload(&self) -> Result<ExecutionPayload, Error> {
let call = FunctionCall {
to: protocol_contract_address::fee_juice(),
selector: FunctionSelector::from_signature(
"claim_and_end_setup((Field),u128,Field,Field)",
),
args: vec![
AbiValue::Field(self.sender.0),
AbiValue::Integer(self.claim.claim_amount as i128),
AbiValue::Field(self.claim.claim_secret),
AbiValue::Field(Fr::from(self.claim.message_leaf_index)),
],
function_type: FunctionType::Private,
is_static: false,
hide_msg_sender: false,
};
Ok(ExecutionPayload {
calls: vec![call],
auth_witnesses: vec![],
capsules: vec![],
extra_hashed_args: vec![],
fee_payer: Some(self.sender),
})
}
}
#[cfg(test)]
#[allow(clippy::expect_used)]
mod tests {
use super::*;
fn test_claim() -> L2AmountClaim {
L2AmountClaim {
claim_amount: 1000,
claim_secret: Fr::from(99u64),
message_leaf_index: 7,
}
}
#[tokio::test]
async fn payload_targets_fee_juice_contract() {
let sender = AztecAddress(Fr::from(1u64));
let method = FeeJuicePaymentMethodWithClaim::new(sender, test_claim());
let payload = method.get_fee_execution_payload().await.expect("payload");
assert_eq!(payload.calls.len(), 1);
let call = &payload.calls[0];
assert_eq!(call.to, protocol_contract_address::fee_juice());
assert_eq!(
call.selector,
FunctionSelector::from_signature("claim_and_end_setup((Field),u128,Field,Field)")
);
assert_eq!(call.function_type, FunctionType::Private);
assert!(!call.is_static);
}
#[tokio::test]
async fn arguments_are_correctly_ordered() {
let sender = AztecAddress(Fr::from(1u64));
let claim = test_claim();
let method = FeeJuicePaymentMethodWithClaim::new(sender, claim.clone());
let payload = method.get_fee_execution_payload().await.expect("payload");
let args = &payload.calls[0].args;
assert_eq!(args.len(), 4);
assert_eq!(args[0], AbiValue::Field(sender.0));
assert_eq!(args[1], AbiValue::Integer(claim.claim_amount as i128));
assert_eq!(args[2], AbiValue::Field(claim.claim_secret));
assert_eq!(args[3], AbiValue::Field(Fr::from(claim.message_leaf_index)));
}
#[tokio::test]
async fn fee_payer_is_sender() {
let sender = AztecAddress(Fr::from(1u64));
let method = FeeJuicePaymentMethodWithClaim::new(sender, test_claim());
assert_eq!(method.get_fee_payer().await.expect("fee payer"), sender);
let payload = method.get_fee_execution_payload().await.expect("payload");
assert_eq!(payload.fee_payer, Some(sender));
}
#[tokio::test]
async fn asset_is_fee_juice() {
let sender = AztecAddress(Fr::from(1u64));
let method = FeeJuicePaymentMethodWithClaim::new(sender, test_claim());
assert_eq!(
method.get_asset().await.expect("asset"),
protocol_contract_address::fee_juice()
);
}
}