openzeppelin_relayer/api/routes/docs/
plugin_docs.rs

1use crate::{
2    models::{ApiResponse, PluginCallRequest, PluginModel},
3    repositories::PaginatedResult,
4    services::plugins::PluginHandlerError,
5};
6
7/// Calls a plugin method.
8///
9/// Logs and traces are only returned when the plugin is configured with `emit_logs` / `emit_traces`.
10/// Plugin-provided errors are normalized into a consistent payload (`code`, `details`) and a derived
11/// message so downstream clients receive a stable shape regardless of how the handler threw.
12#[utoipa::path(
13    post,
14    path = "/api/v1/plugins/{plugin_id}/call",
15    tag = "Plugins",
16    operation_id = "callPlugin",
17    summary = "Execute a plugin and receive the sanitized result",
18    security(
19        ("bearer_auth" = [])
20    ),
21    params(
22        ("plugin_id" = String, Path, description = "The unique identifier of the plugin")
23    ),
24    request_body = PluginCallRequest,
25    responses(
26        (
27            status = 200,
28            description = "Plugin call successful",
29            body = ApiResponse<serde_json::Value>,
30            example = json!({
31                "success": true,
32                "data": "done!",
33                "metadata": {
34                    "logs": [
35                        {
36                            "level": "info",
37                            "message": "Plugin started..."
38                        }
39                    ],
40                    "traces": [
41                        {
42                            "method": "sendTransaction",
43                            "relayerId": "sepolia-example",
44                            "requestId": "6c1f336f-3030-4f90-bd99-ada190a1235b"
45                        }
46                    ]
47                },
48                "error": null
49            })
50        ),
51        (
52            status = 400,
53            description = "BadRequest (plugin-provided)",
54            body = ApiResponse<PluginHandlerError>,
55            example = json!({
56                "success": false,
57                "error": "Validation failed",
58                "data": { "code": "VALIDATION_FAILED", "details": { "field": "email" } },
59                "metadata": {
60                    "logs": [
61                        {
62                            "level": "error",
63                            "message": "Validation failed for field: email"
64                        }
65                    ]
66                }
67            })
68        ),
69        (
70            status = 401,
71            description = "Unauthorized",
72            body = ApiResponse<String>,
73            example = json!({
74                "success": false,
75                "error": "Unauthorized",
76                "data": null
77            })
78        ),
79        (
80            status = 404,
81            description = "Not Found",
82            body = ApiResponse<String>,
83            example = json!({
84                "success": false,
85                "error": "Plugin with ID plugin_id not found",
86                "data": null
87            })
88        ),
89        (
90            status = 429,
91            description = "Too Many Requests",
92            body = ApiResponse<String>,
93            example = json!({
94                "success": false,
95                "error": "Too Many Requests",
96                "data": null
97            })
98        ),
99        (
100            status = 500,
101            description = "Internal server error",
102            body = ApiResponse<String>,
103            example = json!({
104                "success": false,
105                "error": "Internal Server Error",
106                "data": null
107            })
108        ),
109    )
110)]
111#[allow(dead_code)]
112fn doc_call_plugin() {}
113
114/// List plugins.
115#[utoipa::path(
116    get,
117    path = "/api/v1/plugins",
118    tag = "Plugins",
119    operation_id = "listPlugins",
120    security(
121        ("bearer_auth" = [])
122    ),
123    params(
124        ("page" = Option<usize>, Query, description = "Page number for pagination (starts at 1)"),
125        ("per_page" = Option<usize>, Query, description = "Number of items per page (default: 10)")
126    ),
127    responses(
128        (
129            status = 200,
130            description = "Plugins listed successfully",
131            body = ApiResponse<PaginatedResult<PluginModel>>
132        ),
133        (
134            status = 400,
135            description = "BadRequest",
136            body = ApiResponse<String>,
137            example = json!({
138                "success": false,
139                "error": "Bad Request",
140                "data": null
141            })
142        ),
143        (
144            status = 401,
145            description = "Unauthorized",
146            body = ApiResponse<String>,
147            example = json!({
148                "success": false,
149                "error": "Unauthorized",
150                "data": null
151            })
152        ),
153        (
154            status = 404,
155            description = "Not Found",
156            body = ApiResponse<String>,
157            example = json!({
158                "success": false,
159                "error": "Plugin with ID plugin_id not found",
160                "data": null
161            })
162        ),
163        (
164            status = 429,
165            description = "Too Many Requests",
166            body = ApiResponse<String>,
167            example = json!({
168                "success": false,
169                "error": "Too Many Requests",
170                "data": null
171            })
172        ),
173        (
174            status = 500,
175            description = "Internal server error",
176            body = ApiResponse<String>,
177            example = json!({
178                "success": false,
179                "error": "Internal Server Error",
180                "data": null
181            })
182        ),
183    )
184)]
185#[allow(dead_code)]
186fn doc_list_plugins() {}