solagent/tools/
deploy_collection.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_collection, parameters_json_schema, primitives::NFTMetadata, SolanaAgentKit};
16use rig::{
17    completion::ToolDefinition,
18    tool::{Tool, ToolEmbedding},
19};
20use serde::{Deserialize, Serialize};
21use serde_json::json;
22use std::sync::Arc;
23
24#[derive(Deserialize)]
25pub struct DeployCollectionArgs {
26    metadata: NFTMetadata,
27}
28
29#[derive(Deserialize, Serialize)]
30pub struct DeployCollectionOutput {
31    pub mint_address: String,
32    pub tx_signature: String,
33}
34
35#[derive(Debug, thiserror::Error)]
36#[error("DeployCollection error")]
37pub struct DeployCollectionError;
38
39pub struct DeployCollection {
40    agent: Arc<SolanaAgentKit>,
41}
42
43impl DeployCollection {
44    pub fn new(agent: Arc<SolanaAgentKit>) -> Self {
45        DeployCollection { agent }
46    }
47}
48
49impl Tool for DeployCollection {
50    const NAME: &'static str = "deploy_collection";
51
52    type Error = DeployCollectionError;
53    type Args = DeployCollectionArgs;
54    type Output = DeployCollectionOutput;
55
56    async fn definition(&self, _prompt: String) -> ToolDefinition {
57        ToolDefinition {
58            name: "deploy_collection".to_string(),
59            description: r#"
60            Deploy a new NFT collection on Solana blockchain.:
61            examples: [
62                [
63                {
64                    input: {
65                        metadata: {
66                            name: "My NFT",
67                            uri: "https://example.com/nft.json",
68                            basis_points: 500,
69                        }
70                    },
71                    output: {
72                        status: "success",
73                        message: "Collection deployed successfully",
74                        collectionAddress: "7nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkN",
75                        name: "My Collection",
76                    },
77                    explanation: "Deploy an NFT collection with 5% royalty",
78                },
79                ],
80                [
81                {
82                    input: {
83                        metadata: {
84                            name: "My NFT",
85                            uri: "https://example.com/nft.json",
86                        }                        
87                    },
88                    output: {
89                        status: "success",
90                        message: "Collection deployed successfully",
91                        collectionAddress: "8nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkM",
92                        name: "Basic Collection",
93                    },
94                    explanation: "Deploy a basic NFT collection without royalties",
95                },
96                ],
97            ],
98
99            "#
100            .to_string(),
101            parameters: parameters_json_schema!(
102                metadata: NFTMetadata
103            ),
104        }
105    }
106
107    async fn call(&self, args: Self::Args) -> Result<Self::Output, Self::Error> {
108        let res = deploy_collection(&self.agent, &args.metadata).await.expect("deploy_collection");
109
110        Ok(DeployCollectionOutput { mint_address: res.mint, tx_signature: res.signature })
111    }
112}
113
114#[derive(Debug, thiserror::Error)]
115#[error("Init error")]
116pub struct InitError;
117
118impl ToolEmbedding for DeployCollection {
119    type InitError = InitError;
120    type Context = ();
121    type State = Arc<SolanaAgentKit>;
122
123    fn init(state: Self::State, _context: Self::Context) -> Result<Self, Self::InitError> {
124        Ok(DeployCollection { agent: state })
125    }
126
127    fn embedding_docs(&self) -> Vec<String> {
128        vec!["Deploy a new NFT collection on Solana blockchain.".into()]
129    }
130
131    fn context(&self) -> Self::Context {}
132}