solagent/tools/
deploy_token.rs

1// Copyright 2025 zTgx
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::actions::deploy_token;
16use crate::SolanaAgentKit;
17use rig::{
18    completion::ToolDefinition,
19    tool::{Tool, ToolEmbedding},
20};
21use serde::{Deserialize, Serialize};
22use std::sync::Arc;
23
24#[derive(Deserialize)]
25pub struct DeployTokenArgs {
26    pub name: String,
27    pub uri: String,
28    pub symbol: String,
29    pub decimals: u8,
30    pub initial_supply: Option<u64>,
31}
32
33#[derive(Deserialize, Serialize)]
34pub struct DeployTokenOutput {
35    pub mint_address: String,
36    pub tx_signature: String,
37}
38
39#[derive(Debug, thiserror::Error)]
40#[error("DeployToken error")]
41pub struct DeployTokenError;
42
43pub struct DeployToken {
44    agent: Arc<SolanaAgentKit>,
45}
46
47impl DeployToken {
48    pub fn new(agent: Arc<SolanaAgentKit>) -> Self {
49        DeployToken { agent }
50    }
51}
52
53impl Tool for DeployToken {
54    const NAME: &'static str = "deploy_token";
55
56    type Error = DeployTokenError;
57    type Args = DeployTokenArgs;
58    type Output = DeployTokenOutput;
59
60    async fn definition(&self, _prompt: String) -> ToolDefinition {
61        ToolDefinition {
62            name: "deploy_token".to_string(),
63            description: r#"
64            Deploy a new SPL token on the Solana blockchain with specified parameters:
65
66            examples: [
67                [
68                {
69                    input: {
70                        name: "My Token",
71                        uri: "https://example.com/token.json",
72                        symbol: "MTK",
73                        decimals: 9,
74                        initialSupply: 1000000,
75                    },
76                    output: {
77                        mint: "7nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkN",
78                        status: "success",
79                        message: "Token deployed successfully",
80                    },
81                    explanation: "Deploy a token with initial supply and metadata",
82                },
83                ],
84                [
85                {
86                    input: {
87                        name: "Basic Token",
88                        uri: "https://example.com/basic.json",
89                        symbol: "BASIC",
90                    },
91                    output: {
92                        mint: "8nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkM",
93                        status: "success",
94                        message: "Token deployed successfully",
95                    },
96                    explanation: "Deploy a basic token with minimal parameters",
97                },
98                ],
99            ],
100            
101            "#
102            .to_string(),
103            parameters: serde_json::Value::Null,
104        }
105    }
106
107    async fn call(&self, args: Self::Args) -> Result<Self::Output, Self::Error> {
108        let res = deploy_token(&self.agent, args.name, args.uri, args.symbol, args.decimals, args.initial_supply)
109            .await
110            .expect("deploy_token");
111
112        Ok(DeployTokenOutput { mint_address: res.mint, tx_signature: res.signature })
113    }
114}
115
116#[derive(Debug, thiserror::Error)]
117#[error("Init error")]
118pub struct InitError;
119
120impl ToolEmbedding for DeployToken {
121    type InitError = InitError;
122    type Context = ();
123    type State = Arc<SolanaAgentKit>;
124
125    fn init(_state: Self::State, _context: Self::Context) -> Result<Self, Self::InitError> {
126        Ok(DeployToken { agent: _state })
127    }
128
129    fn embedding_docs(&self) -> Vec<String> {
130        vec!["Deploy a new SPL token on the Solana blockchain with specified parameters.".into()]
131    }
132
133    fn context(&self) -> Self::Context {}
134}