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"]
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"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bitflags"
version = "1.3.2"
@ -1087,7 +1093,7 @@ dependencies = [
"once_cell",
"percent-encoding",
"pin-project-lite",
"rustls-pemfile",
"rustls-pemfile 1.0.4",
"serde",
"serde_json",
"serde_urlencoded",
@ -1103,6 +1109,21 @@ dependencies = [
"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]]
name = "rustc-demangle"
version = "0.1.24"
@ -1122,6 +1143,33 @@ dependencies = [
"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]]
name = "rustls-pemfile"
version = "1.0.4"
@ -1131,6 +1179,33 @@ dependencies = [
"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]]
name = "rustversion"
version = "1.0.17"
@ -1287,12 +1362,24 @@ dependencies = [
"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]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "2.0.66"
@ -1431,6 +1518,7 @@ dependencies = [
"mio",
"pin-project-lite",
"socket2",
"tokio-macros",
"windows-sys 0.48.0",
]
@ -1444,6 +1532,17 @@ dependencies = [
"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]]
name = "tokio-native-tls"
version = "0.3.1"
@ -1454,6 +1553,17 @@ dependencies = [
"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]]
name = "tokio-stream"
version = "0.1.15"
@ -1497,7 +1607,11 @@ dependencies = [
"percent-encoding",
"pin-project",
"prost",
"rustls-native-certs",
"rustls-pemfile 2.1.2",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tokio-stream",
"tower",
"tower-layer",
@ -1623,6 +1737,12 @@ version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.5.0"
@ -1905,6 +2025,32 @@ dependencies = [
"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]]
name = "funnylog"
version = "0.1.0"
@ -1916,7 +2062,3 @@ version = "0.1.0"
[[patch.unused]]
name = "funnylog_macros"
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
tokio = { version = "1", features = ["sync", "rt"] }
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-types = "0.12"

View file

@ -1,14 +1,18 @@
pub use tinkoff_invest::Account;
use tinkoff_invest::{
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::{
service::{interceptor::InterceptedService, Interceptor},
transport::Channel,
*,
};
use transport::ClientTlsConfig;
#[derive(Debug)]
pub struct TinkoffInterceptor {
@ -20,14 +24,14 @@ impl Interceptor for TinkoffInterceptor {
let mut req = request;
req.metadata_mut().append(
"authorization",
format!("bearer {}", self.token).parse().unwrap(),
format!("bearer {}", self.token).parse().expect("failed to token"),
);
req.metadata_mut().append(
"x-tracking-id",
uuid::Uuid::new_v4().to_string().parse().unwrap(),
);
req.metadata_mut()
.append("x-app-name", "sanetrade".parse().unwrap());
.append("x-app-name", "minky.sanetrade".parse().unwrap());
Ok(req)
}
@ -52,11 +56,15 @@ impl TinkoffGenericClient {
}
pub async fn create_channel(&self) -> Result<Channel, TinkoffError> {
let tls = ClientTlsConfig::new();
Ok(Channel::from_static(if self.sandbox {
"https://sandbox-invest-public-api.tinkoff.ru:443"
} else {
"https://invest-public-api.tinkoff.ru:443"
})
.tls_config(tls)
.expect("tls?? hello??")
.connect()
.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(
@ -105,8 +135,21 @@ pub struct TinkoffUsersClient(
pub UsersServiceClient<InterceptedService<Channel, TinkoffInterceptor>>,
);
pub struct TinkoffMarketDataClient(
pub MarketDataServiceClient<InterceptedService<Channel, TinkoffInterceptor>>,
);
pub struct TinkoffMarketDataStreamClient(
pub MarketDataStreamServiceClient<InterceptedService<Channel, TinkoffInterceptor>>,
);
impl TinkoffUsersClient {
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)
}
}