tinkoff_invest_api/
lib.rs1use tcs::{
2 instruments_service_client::InstrumentsServiceClient,
3 market_data_service_client::MarketDataServiceClient,
4 market_data_stream_service_client::MarketDataStreamServiceClient,
5 operations_service_client::OperationsServiceClient,
6 orders_stream_service_client::OrdersStreamServiceClient,
7 sandbox_service_client::SandboxServiceClient,
8 stop_orders_service_client::StopOrdersServiceClient, users_service_client::UsersServiceClient,
9};
10use tonic::{
11 codegen::InterceptedService,
12 service::Interceptor,
13 transport::{self, Channel, ClientTlsConfig},
14 Status,
15};
16
17#[path = "google.api.rs"]
18pub mod google_api;
19pub mod tcs;
20
21#[derive(Debug)]
22pub struct TinkoffInvestService {
23 token: String,
24}
25
26#[derive(Debug)]
27pub struct DefaultInterceptor {
28 token: String,
29}
30
31impl Interceptor for DefaultInterceptor {
32 fn call(&mut self, request: tonic::Request<()>) -> Result<tonic::Request<()>, Status> {
33 let mut req = request;
34 req.metadata_mut().append(
35 "authorization",
36 format!("bearer {}", self.token).parse().unwrap(),
37 );
38 req.metadata_mut().append(
39 "x-tracking-id",
40 uuid::Uuid::new_v4().to_string().parse().unwrap(),
41 );
42 req.metadata_mut()
43 .append("x-app-name", "ovr.tinkoffInvestRust".parse().unwrap());
44
45 Ok(req)
46 }
47}
48
49#[derive(Debug)]
50pub enum TIError {
51 TransportError(transport::Error),
53 StatusError(tonic::Status),
55}
56
57impl From<transport::Error> for TIError {
58 fn from(e: transport::Error) -> Self {
59 TIError::TransportError(e)
60 }
61}
62
63impl From<tonic::Status> for TIError {
64 fn from(e: tonic::Status) -> Self {
65 TIError::StatusError(e)
66 }
67}
68
69pub type TIResult<T> = std::result::Result<T, TIError>;
70
71impl TinkoffInvestService {
72 pub fn new(token: String) -> Self {
73 Self { token }
74 }
75
76 pub async fn create_channel(&self) -> TIResult<Channel> {
77 let tls = ClientTlsConfig::new();
78
79 let channel = Channel::from_static("https://invest-public-api.tinkoff.ru:443/")
80 .tls_config(tls)?
81 .connect()
82 .await?;
83
84 Ok(channel)
85 }
86
87 pub async fn users(
88 &self,
89 channel: Channel,
90 ) -> TIResult<UsersServiceClient<InterceptedService<Channel, DefaultInterceptor>>> {
91 let client = UsersServiceClient::with_interceptor(
92 channel,
93 DefaultInterceptor {
94 token: self.token.clone(),
95 },
96 );
97
98 Ok(client)
99 }
100
101 pub async fn operations(
102 &self,
103 channel: Channel,
104 ) -> TIResult<OperationsServiceClient<InterceptedService<Channel, DefaultInterceptor>>> {
105 let client = OperationsServiceClient::with_interceptor(
106 channel,
107 DefaultInterceptor {
108 token: self.token.clone(),
109 },
110 );
111
112 Ok(client)
113 }
114
115 pub async fn instruments(
116 &self,
117 channel: Channel,
118 ) -> TIResult<InstrumentsServiceClient<InterceptedService<Channel, DefaultInterceptor>>> {
119 let client = InstrumentsServiceClient::with_interceptor(
120 channel,
121 DefaultInterceptor {
122 token: self.token.clone(),
123 },
124 );
125
126 Ok(client)
127 }
128
129 pub async fn marketdata(
130 &self,
131 channel: Channel,
132 ) -> TIResult<MarketDataServiceClient<InterceptedService<Channel, DefaultInterceptor>>> {
133 let client = MarketDataServiceClient::with_interceptor(
134 channel,
135 DefaultInterceptor {
136 token: self.token.clone(),
137 },
138 );
139
140 Ok(client)
141 }
142
143 pub async fn marketdata_stream(
144 &self,
145 channel: Channel,
146 ) -> TIResult<MarketDataStreamServiceClient<InterceptedService<Channel, DefaultInterceptor>>>
147 {
148 let client = MarketDataStreamServiceClient::with_interceptor(
149 channel,
150 DefaultInterceptor {
151 token: self.token.clone(),
152 },
153 );
154
155 Ok(client)
156 }
157
158 pub async fn orders_stream(
159 &self,
160 channel: Channel,
161 ) -> TIResult<OrdersStreamServiceClient<InterceptedService<Channel, DefaultInterceptor>>> {
162 let client = OrdersStreamServiceClient::with_interceptor(
163 channel,
164 DefaultInterceptor {
165 token: self.token.clone(),
166 },
167 );
168
169 Ok(client)
170 }
171
172 pub async fn stop_orders(
173 &self,
174 channel: Channel,
175 ) -> TIResult<StopOrdersServiceClient<InterceptedService<Channel, DefaultInterceptor>>> {
176 let client = StopOrdersServiceClient::with_interceptor(
177 channel,
178 DefaultInterceptor {
179 token: self.token.clone(),
180 },
181 );
182
183 Ok(client)
184 }
185
186 pub async fn sandbox(
187 &self,
188 channel: Channel,
189 ) -> TIResult<SandboxServiceClient<InterceptedService<Channel, DefaultInterceptor>>> {
190 let client = SandboxServiceClient::with_interceptor(
191 channel,
192 DefaultInterceptor {
193 token: self.token.clone(),
194 },
195 );
196
197 Ok(client)
198 }
199}