This commit is contained in:
Borodinov Ilya 2024-08-21 21:06:23 +03:00
parent 5f9ca355b0
commit 2f17b8088b
Signed by: noth
GPG key ID: 75503B2EF596D1BD
6 changed files with 198 additions and 13 deletions

View file

@ -0,0 +1 @@
/nix/store/clgnapkqpby0ida8dkg5915w8x64l9ds-source

View file

@ -1 +0,0 @@
/nix/store/lvg59dwzvw3q6l1kpf4mirnzv2fflmra-source

2
.gitmodules vendored
View file

@ -1,3 +1,3 @@
[submodule "crates/tinkoff_invest/investapi"] [submodule "crates/tinkoff_invest/investapi"]
path = crates/tinkoff_invest/investapi path = crates/tinkoff_invest/investapi
url = https://github.com/tinkoff/investapi url = https://github.com/russianinvestments/investapi

152
Cargo.lock generated
View file

@ -206,6 +206,12 @@ version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@ -1087,7 +1093,7 @@ dependencies = [
"once_cell", "once_cell",
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"rustls-pemfile", "rustls-pemfile 1.0.4",
"serde", "serde",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
@ -1103,6 +1109,21 @@ dependencies = [
"winreg", "winreg",
] ]
[[package]]
name = "ring"
version = "0.17.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
dependencies = [
"cc",
"cfg-if",
"getrandom",
"libc",
"spin",
"untrusted",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.24" version = "0.1.24"
@ -1122,6 +1143,33 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "rustls"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
dependencies = [
"log",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-native-certs"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792"
dependencies = [
"openssl-probe",
"rustls-pemfile 2.1.2",
"rustls-pki-types",
"schannel",
"security-framework",
]
[[package]] [[package]]
name = "rustls-pemfile" name = "rustls-pemfile"
version = "1.0.4" version = "1.0.4"
@ -1131,6 +1179,33 @@ dependencies = [
"base64 0.21.7", "base64 0.21.7",
] ]
[[package]]
name = "rustls-pemfile"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
dependencies = [
"base64 0.22.1",
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
[[package]]
name = "rustls-webpki"
version = "0.102.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.17" version = "1.0.17"
@ -1287,12 +1362,24 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.11.1" version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.66" version = "2.0.66"
@ -1431,6 +1518,7 @@ dependencies = [
"mio", "mio",
"pin-project-lite", "pin-project-lite",
"socket2", "socket2",
"tokio-macros",
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
@ -1444,6 +1532,17 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "tokio-macros"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "tokio-native-tls" name = "tokio-native-tls"
version = "0.3.1" version = "0.3.1"
@ -1454,6 +1553,17 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "tokio-rustls"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
dependencies = [
"rustls",
"rustls-pki-types",
"tokio",
]
[[package]] [[package]]
name = "tokio-stream" name = "tokio-stream"
version = "0.1.15" version = "0.1.15"
@ -1497,7 +1607,11 @@ dependencies = [
"percent-encoding", "percent-encoding",
"pin-project", "pin-project",
"prost", "prost",
"rustls-native-certs",
"rustls-pemfile 2.1.2",
"rustls-pki-types",
"tokio", "tokio",
"tokio-rustls",
"tokio-stream", "tokio-stream",
"tower", "tower",
"tower-layer", "tower-layer",
@ -1623,6 +1737,12 @@ version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]] [[package]]
name = "url" name = "url"
version = "2.5.0" version = "2.5.0"
@ -1905,6 +2025,32 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "zeroize"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
[[patch.unused]]
name = "careless"
version = "0.1.0"
[[patch.unused]]
name = "photon"
version = "0.1.0"
[[patch.unused]]
name = "photon_effects"
version = "0.1.0"
[[patch.unused]]
name = "photon_wire"
version = "0.1.0"
[[patch.unused]]
name = "photon_wire_derive"
version = "0.1.0"
[[patch.unused]] [[patch.unused]]
name = "funnylog" name = "funnylog"
version = "0.1.0" version = "0.1.0"
@ -1916,7 +2062,3 @@ version = "0.1.0"
[[patch.unused]] [[patch.unused]]
name = "funnylog_macros" name = "funnylog_macros"
version = "0.1.0" version = "0.1.0"
[[patch.unused]]
name = "careless"
version = "0.1.0"

View file

@ -15,6 +15,6 @@ tinkoff_invest.path = "crates/tinkoff_invest"
## deps ## deps
tokio = { version = "1", features = ["sync", "rt"] } tokio = { version = "1", features = ["sync", "rt"] }
futures-core = { version = "0.3", features = ["std"], default-features = false } futures-core = { version = "0.3", features = ["std"], default-features = false }
tonic = "0.11" tonic = { version = "0.11", features = ["channel", "codegen", "prost", "tls", "tls-roots"] }
prost = "0.12" prost = "0.12"
prost-types = "0.12" prost-types = "0.12"

View file

@ -1,14 +1,18 @@
pub use tinkoff_invest::Account;
use tinkoff_invest::{ use tinkoff_invest::{
instruments_service_client::InstrumentsServiceClient, instruments_service_client::InstrumentsServiceClient,
operations_service_client::OperationsServiceClient, users_service_client::UsersServiceClient, GetAccountsRequest, market_data_service_client::MarketDataServiceClient,
market_data_stream_service_client::MarketDataStreamServiceClient,
operations_service_client::OperationsServiceClient, users_service_client::UsersServiceClient,
GetAccountsRequest,
}; };
pub use tinkoff_invest::Account;
use tonic::{ use tonic::{
service::{interceptor::InterceptedService, Interceptor}, service::{interceptor::InterceptedService, Interceptor},
transport::Channel, transport::Channel,
*, *,
}; };
use transport::ClientTlsConfig;
#[derive(Debug)] #[derive(Debug)]
pub struct TinkoffInterceptor { pub struct TinkoffInterceptor {
@ -20,14 +24,14 @@ impl Interceptor for TinkoffInterceptor {
let mut req = request; let mut req = request;
req.metadata_mut().append( req.metadata_mut().append(
"authorization", "authorization",
format!("bearer {}", self.token).parse().unwrap(), format!("bearer {}", self.token).parse().expect("failed to token"),
); );
req.metadata_mut().append( req.metadata_mut().append(
"x-tracking-id", "x-tracking-id",
uuid::Uuid::new_v4().to_string().parse().unwrap(), uuid::Uuid::new_v4().to_string().parse().unwrap(),
); );
req.metadata_mut() req.metadata_mut()
.append("x-app-name", "sanetrade".parse().unwrap()); .append("x-app-name", "minky.sanetrade".parse().unwrap());
Ok(req) Ok(req)
} }
@ -52,11 +56,15 @@ impl TinkoffGenericClient {
} }
pub async fn create_channel(&self) -> Result<Channel, TinkoffError> { pub async fn create_channel(&self) -> Result<Channel, TinkoffError> {
let tls = ClientTlsConfig::new();
Ok(Channel::from_static(if self.sandbox { Ok(Channel::from_static(if self.sandbox {
"https://sandbox-invest-public-api.tinkoff.ru:443" "https://sandbox-invest-public-api.tinkoff.ru:443"
} else { } else {
"https://invest-public-api.tinkoff.ru:443" "https://invest-public-api.tinkoff.ru:443"
}) })
.tls_config(tls)
.expect("tls?? hello??")
.connect() .connect()
.await?) .await?)
} }
@ -91,6 +99,28 @@ impl TinkoffGenericClient {
}, },
))) )))
} }
pub async fn market_data(&self) -> Result<TinkoffMarketDataClient, TinkoffError> {
Ok(TinkoffMarketDataClient(
MarketDataServiceClient::with_interceptor(
self.create_channel().await?,
TinkoffInterceptor {
token: self.token.clone(),
},
),
))
}
pub async fn market_data_stream(&self) -> Result<TinkoffMarketDataStreamClient, TinkoffError> {
Ok(TinkoffMarketDataStreamClient(
MarketDataStreamServiceClient::with_interceptor(
self.create_channel().await?,
TinkoffInterceptor {
token: self.token.clone(),
},
),
))
}
} }
pub struct TinkoffOperationsClient( pub struct TinkoffOperationsClient(
@ -105,8 +135,21 @@ pub struct TinkoffUsersClient(
pub UsersServiceClient<InterceptedService<Channel, TinkoffInterceptor>>, pub UsersServiceClient<InterceptedService<Channel, TinkoffInterceptor>>,
); );
pub struct TinkoffMarketDataClient(
pub MarketDataServiceClient<InterceptedService<Channel, TinkoffInterceptor>>,
);
pub struct TinkoffMarketDataStreamClient(
pub MarketDataStreamServiceClient<InterceptedService<Channel, TinkoffInterceptor>>,
);
impl TinkoffUsersClient { impl TinkoffUsersClient {
pub async fn accounts(&mut self) -> Result<Vec<Account>, TinkoffError> { pub async fn accounts(&mut self) -> Result<Vec<Account>, TinkoffError> {
Ok(self.0.get_accounts(GetAccountsRequest {}).await?.into_inner().accounts) Ok(self
.0
.get_accounts(GetAccountsRequest {})
.await?
.into_inner()
.accounts)
} }
} }