solagent_rig_solana/
mint_nft.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 serde::{Deserialize, Serialize};
16use solagent_core::{
17    rig::{
18        completion::ToolDefinition,
19        tool::{Tool, ToolEmbedding},
20    },
21    solana_sdk::pubkey::Pubkey,
22    SolanaAgentKit,
23};
24use solagent_parameters::parameters;
25use solagent_plugin_solana::{mint_nft_to_collection, NFTMetadata};
26use std::sync::Arc;
27
28#[derive(serde::Serialize, serde::Deserialize)]
29pub struct MintNFTArgs {
30    collection: Pubkey,
31    metadata: NFTMetadata,
32}
33
34#[derive(Deserialize, Serialize)]
35pub struct MintNFTOutput {
36    pub mint_address: String,
37    pub tx_signature: String,
38}
39
40#[derive(Debug, thiserror::Error)]
41#[error("MintNFT error")]
42pub struct MintNFTError;
43
44pub struct MintNFT {
45    agent: Arc<SolanaAgentKit>,
46}
47
48impl MintNFT {
49    pub fn new(agent: Arc<SolanaAgentKit>) -> Self {
50        MintNFT { agent }
51    }
52}
53
54impl Tool for MintNFT {
55    const NAME: &'static str = "mint_nft";
56
57    type Error = MintNFTError;
58    type Args = MintNFTArgs;
59    type Output = MintNFTOutput;
60
61    async fn definition(&self, _prompt: String) -> ToolDefinition {
62        ToolDefinition {
63            name: "mint_nft".to_string(),
64            description: r#"
65            Mint a new NFT in a collection on Solana blockchain.
66
67            examples: [
68                [
69                    {
70                        input: {
71                            collection: "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w",
72                            metadata: {
73                                name: "My NFT",
74                                uri: "https://example.com/nft.json",
75                                basis_points: Option<u16>,
76                            }
77                        },
78                        output: {
79                            status: "success",
80                            message: "NFT minted successfully",
81                            mintAddress: "7nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkN",
82                            metadata: {
83                                name: "My NFT",
84                                uri: "https://example.com/nft.json",
85                            },
86                            recipient: "7nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkN",
87                        },
88                        explanation: "Mint an NFT to the default wallet",
89                    },
90                ],
91                [
92                    {
93                        input: {
94                            collection: "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w",
95                            metadata: {
96                                name: "My NFT",
97                                uri: "https://example.com/nft.json",
98                                basis_points: Option<u16>,
99                                creators: [
100                                    address: "address",
101                                    verified: false,
102                                    share: 100,
103                                ]                        
104                            }                        
105                        },
106                        output: {
107                            status: "success",
108                            message: "NFT minted successfully",
109                            mintAddress: "8nE9GvcwsqzYxmJLSrYmSB1V1YoJWVK1KWzAcWAzjXkM",
110                            metadata: {
111                                name: "Gift NFT",
112                                uri: "https://example.com/gift.json",
113                            },
114                            recipient: "9aUn5swQzUTRanaaTwmszxiv89cvFwUCjEBv1vZCoT1u",
115                        },
116                        explanation: "Mint an NFT to a specific recipient",
117                    },
118                ],
119            ],
120
121            "#
122            .to_string(),
123            parameters: parameters!(
124                collection: Pubkey,
125                metadata: NFTMetadata,
126            ),
127        }
128    }
129
130    async fn call(&self, args: Self::Args) -> Result<Self::Output, Self::Error> {
131        let res = mint_nft_to_collection(&self.agent, args.collection, args.metadata)
132            .await
133            .expect("mint_nft");
134
135        Ok(MintNFTOutput {
136            mint_address: res.mint,
137            tx_signature: res.signature,
138        })
139    }
140}
141
142#[derive(Debug, thiserror::Error)]
143#[error("Init error")]
144pub struct InitError;
145
146impl ToolEmbedding for MintNFT {
147    type InitError = InitError;
148    type Context = ();
149    type State = Arc<SolanaAgentKit>;
150
151    fn init(state: Self::State, _context: Self::Context) -> Result<Self, Self::InitError> {
152        Ok(MintNFT { agent: state })
153    }
154
155    fn embedding_docs(&self) -> Vec<String> {
156        vec!["Mint a new NFT in a collection on Solana blockchain.".into()]
157    }
158
159    fn context(&self) -> Self::Context {}
160}