solagent_rig_solana/
transfer.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    SolanaAgentKit,
22};
23use solagent_parameters::parameters;
24use solagent_plugin_solana::transfer;
25use std::sync::Arc;
26
27#[derive(Deserialize)]
28pub struct TransferArgs {
29    pub to: String,
30    pub amount: u64,
31    pub mint: Option<String>,
32}
33
34#[derive(Deserialize, Serialize)]
35pub struct TransferOutput {
36    pub tx: String,
37}
38
39#[derive(Debug, thiserror::Error)]
40#[error("Transfer error")]
41pub struct TransferError;
42
43pub struct Transfer {
44    agent: Arc<SolanaAgentKit>,
45}
46
47impl Transfer {
48    pub fn new(agent: Arc<SolanaAgentKit>) -> Self {
49        Transfer { agent }
50    }
51}
52
53impl Tool for Transfer {
54    const NAME: &'static str = "transfer";
55
56    type Error = TransferError;
57    type Args = TransferArgs;
58    type Output = TransferOutput;
59
60    async fn definition(&self, _prompt: String) -> ToolDefinition {
61        ToolDefinition {
62            name: "transfer".to_string(),
63            description: r#"
64            Transfer tokens or SOL to another address (also called as wallet address).
65
66            examples: [
67                [
68                    {
69                        input: {
70                            to: "8x2dR8Mpzuz2YqyZyZjUbYWKSWesBo5jMx2Q9Y86udVk",
71                            amount: 1,
72                        },
73                        output: {
74                            status: "success",
75                            message: "Transfer completed successfully",
76                            amount: 1,
77                            recipient: "8x2dR8Mpzuz2YqyZyZjUbYWKSWesBo5jMx2Q9Y86udVk",
78                            token: "SOL",
79                            transaction:
80                                "5UfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKgvHYmXJgqJKxEqy9k4Rz9LpXrHF9kUZB7",
81                        },
82                        explanation: "Transfer 1 SOL to the recipient address",
83                    },
84                ],
85                [
86                    {
87                        input: {
88                            to: "8x2dR8Mpzuz2YqyZyZjUbYWKSWesBo5jMx2Q9Y86udVk",
89                            amount: 100,
90                            mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
91                        },
92                        output: {
93                            status: "success",
94                            message: "Transfer completed successfully",
95                            amount: 100,
96                            recipient: "8x2dR8Mpzuz2YqyZyZjUbYWKSWesBo5jMx2Q9Y86udVk",
97                            token: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
98                            transaction:
99                                "4VfgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKgvHYmXJgqJKxEqy9k4Rz9LpXrHF9kUZB7",
100                        },
101                        explanation: "Transfer 100 USDC tokens to the recipient address",
102                    },
103                ],
104            ],
105 
106            "#
107            .to_string(),
108            parameters: parameters!(
109                to: String,
110                amount: f64,
111                mint: String,
112            ),
113        }
114    }
115
116    async fn call(&self, args: Self::Args) -> Result<Self::Output, Self::Error> {
117        let tx = transfer(&self.agent, &args.to, args.amount, args.mint)
118            .await
119            .expect("transfer");
120
121        Ok(TransferOutput { tx })
122    }
123}
124
125#[derive(Debug, thiserror::Error)]
126#[error("Init error")]
127pub struct InitError;
128
129impl ToolEmbedding for Transfer {
130    type InitError = InitError;
131    type Context = ();
132    type State = Arc<SolanaAgentKit>;
133
134    fn init(_state: Self::State, _context: Self::Context) -> Result<Self, Self::InitError> {
135        Ok(Transfer { agent: _state })
136    }
137
138    fn embedding_docs(&self) -> Vec<String> {
139        vec!["Transfer tokens or SOL to another address (also called as wallet address).".into()]
140    }
141
142    fn context(&self) -> Self::Context {}
143}