use defuse::contract::Role; use defuse_test_utils::asserts::ResultAssertsExt; use near_sdk::{AccountId, NearToken, PublicKey}; use near_workspaces::{Account, types::SecretKey}; use rstest::rstest; use serde_json::json; use crate::{ tests::defuse::{env::Env, intents::ExecuteIntentsExt}, utils::acl::AclExt, }; #[tokio::test] #[rstest] async fn relayer_keys() { use near_workspaces::Contract; let env = Env::builder().deployer_as_super_admin().build().await; let (user, other_user) = futures::join!(env.create_user(), env.create_user()); env.acl_grant_role(env.defuse.id(), Role::RelayerKeysManager, user.id()) .await .unwrap(); let worker = env.sandbox().worker().clone(); // We generate a new key, because all keys generated by Near Workspaces are the same let new_relayer_secret_key = SecretKey::from_random(near_workspaces::types::KeyType::ED25519); let new_relayer_public_key = new_relayer_secret_key.public_key(); let new_relayer_public_key_near_sdk = new_relayer_public_key.to_string().parse().unwrap(); // Attempt to use the key that we still didn't add, to execute an intent, which fails Contract::from_secret_key( env.defuse.id().clone(), new_relayer_secret_key.clone(), &worker, ) .execute_intents(env.defuse.id(), []) // Empty because it's just to ensure that authorization works/doesn't work .await .assert_err_contains("Failed to query access key"); // A random, unauthorized user attempts to add a key (no role `Role::RelayerKeysManager`) and fails other_user .add_relayer_key(env.defuse.id(), &new_relayer_public_key_near_sdk) .await .assert_err_contains("Requires one of these roles:"); // A `Role::RelayerKeysManager` attempts to add the key, successfully user.add_relayer_key(env.defuse.id(), &new_relayer_public_key_near_sdk) .await .unwrap(); // Attempt to add a key that already exists user.add_relayer_key(env.defuse.id(), &new_relayer_public_key_near_sdk) .await .assert_err_contains("key already exists"); // Create a Function-call Key, then use it to execute an (empty) intent Contract::from_secret_key( env.defuse.id().clone(), new_relayer_secret_key.clone(), &worker, ) .execute_intents(env.defuse.id(), []) // Empty because it's just to ensure that authorization works/doesn't work .await .unwrap(); // Attempt to delete the key by an unauthorized user other_user .delete_relayer_key(env.defuse.id(), &new_relayer_public_key_near_sdk) .await .assert_err_contains("Requires one of these roles:"); // Delete the relayer key by the authorized entity user.delete_relayer_key(env.defuse.id(), &new_relayer_public_key_near_sdk) .await .unwrap(); // Delete the same key again, which won't work user.delete_relayer_key(env.defuse.id(), &new_relayer_public_key_near_sdk) .await .assert_err_contains("key not found"); let access_keys = env.defuse.view_access_keys().await.unwrap(); dbg!(&access_keys); assert!(!access_keys.is_empty()); } pub trait RelayerKeysExt { async fn add_relayer_key( &self, defuse_contract_id: &AccountId, public_key: &PublicKey, ) -> anyhow::Result<()>; async fn delete_relayer_key( &self, defuse_contract_id: &AccountId, public_key: &PublicKey, ) -> anyhow::Result<()>; } impl RelayerKeysExt for Account { async fn add_relayer_key( &self, defuse_contract_id: &AccountId, public_key: &PublicKey, ) -> anyhow::Result<()> { self.call(defuse_contract_id, "add_relayer_key") .deposit(NearToken::from_yoctonear(1)) .args_json(json!({ "public_key": public_key, })) .max_gas() .transact() .await? .into_result()?; Ok(()) } async fn delete_relayer_key( &self, defuse_contract_id: &AccountId, public_key: &PublicKey, ) -> anyhow::Result<()> { self.call(defuse_contract_id, "delete_relayer_key") .deposit(NearToken::from_yoctonear(1)) .args_json(json!({ "public_key": public_key, })) .max_gas() .transact() .await? .into_result()?; Ok(()) } }