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

add token admin behavior #13

Merged
merged 5 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ docs/
# Dotenv file
.env
*.lock
.idea/

analysis/counter/*
1 change: 1 addition & 0 deletions src/behaviors/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use serde::{Deserialize, Serialize};

pub mod deployer;
mod token_admin;

pub use deployer::Deployer;
143 changes: 143 additions & 0 deletions src/behaviors/token_admin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
use std::collections::HashMap;
use std::sync::Arc;

use anyhow::{Result};
use arbiter_core::{middleware::ArbiterMiddleware};
use arbiter_engine::{
machine::{Behavior, EventStream},
messager::Messager
};
use arbiter_engine::machine::ControlFlow;
use arbiter_engine::messager::{Message, To};
use ethers::types::H160;

use super::*;
use crate::bindings::token::ArbiterToken;

#[derive(Debug, Serialize, Deserialize)]
pub struct TokenAdmin{
#[serde(skip)]
pub tokens: Option<HashMap<String, ArbiterToken<ArbiterMiddleware>>>,
pub token_data: HashMap<String, TokenData>,
#[serde(skip)]
pub messager: Option<Messager>
}

#[derive(Debug, Serialize, Deserialize)]
pub struct TokenData {
pub name: String,
pub symbol: String,
pub decimals: u8,
pub address: Option<H160>
}

/// Used as an action to ask what tokens are available.
#[derive(Debug, Deserialize, Serialize)]
pub enum TokenAdminQuery {
/// Get the address of the token.
AddressOf(String),
/// Mint tokens.
MintRequest(MintRequest)
}

/// Used as an action to mint tokens.
#[derive(Debug, Deserialize, Serialize)]
pub struct MintRequest {
/// The token to mint.
pub token: String,
/// The address to mint to.
pub mint_to: H160,
/// The amount to mint.
pub mint_amount: u64
}

#[async_trait::async_trait]
impl Behavior<Message> for TokenAdmin {
async fn startup(
&mut self,
client: Arc<ArbiterMiddleware>,
messager: Messager,
) -> Result<Option<EventStream<Message>>> {
let mut deployed_tokens = HashMap::new();
let mut token_addresses = HashMap::new(); // For messaging purposes

for (token_id, data) in self.token_data.iter_mut() {
// Handle the deployment result
let deploy_result = ArbiterToken::deploy(
client.clone(),
(
data.name.clone(),
data.symbol.clone(),
data.decimals,
),
)?.send().await?;

// Send the deployment transaction and await its confirmation
let token = deploy_result;

// Assuming `address` is an async method to get the deployed contract's address
let token_address = token.address();
data.address = Some(token_address);

deployed_tokens.insert(token_id.clone(), token);
token_addresses.insert(token_id.clone(), token_address); // Collect addresses for messaging
}

self.tokens = Some(deployed_tokens);

// Serialize and send token information to all agents
let message_content = serde_json::to_string(&token_addresses)?;

messager
.send(To::All, serde_json::to_string(&message_content)?)
0xJepsen marked this conversation as resolved.
Show resolved Hide resolved
.await;

// Return None as no event stream is required for startup
Ok(None)
}

async fn process(
&mut self,
event: Message
) -> Result<ControlFlow> {
// First, deserialize the incoming message to a TokenAdminQuery
let query: TokenAdminQuery = match serde_json::from_str(&event.data) {
Ok(query) => query,
Err(_) => {
// Log or handle the error as appropriate for your application
eprintln!("Failed to deserialize the event data into a TokenAdminQuery");
return Ok(ControlFlow::Continue);
}
};

// Process the query
match query {
TokenAdminQuery::AddressOf(token_name) => {
if let Some(token_data) = self.token_data.get(&token_name) {
let response = serde_json::to_string(&token_data.address)
.map_err(|_| anyhow::anyhow!("Failed to serialize token address"))?;
if let Some(messager) = &self.messager {
messager.send(To::Agent(event.from.clone()), response).await?;
} else {
eprintln!("Messager is not available.");
return Err(anyhow::anyhow!("Messager is not available."));
}
} else {
eprintln!("Token not found: {}", token_name);
}
Ok(ControlFlow::Continue)
},
TokenAdminQuery::MintRequest(mint_request) => {
if let Some(token) = self.tokens.as_ref().and_then(|tokens| tokens.get(&mint_request.token)) {
match token.mint(mint_request.mint_to, mint_request.mint_amount.into()).send().await {
Ok(_) => println!("Minting successful for token: {}", mint_request.token),
Err(e) => eprintln!("Failed to mint token: {}. Error: {:?}", mint_request.token, e),
}
} else {
eprintln!("Token not found for minting: {}", mint_request.token);
}
Ok(ControlFlow::Continue)
}
}
}
}
Loading