1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use bytes::Bytes;
use cryptohelpers::sha256;
use reqwest::multipart::Part;
use serde::Deserialize;
use solana_sdk::pubkey::Pubkey;
use std::path::Path;
use tokio::fs::File;
pub use shadow_drive_user_staking::instructions::{
decrease_storage::UnstakeInfo,
initialize_account::{StorageAccount, UserInfo},
store_file::File as FileAccount,
};
pub mod payload;
use crate::error::{Error, FileError};
use payload::Payload;
pub type ShadowDriveResult<T> = Result<T, Error>;
#[derive(Clone, Debug, Deserialize)]
pub struct ShdwDriveResponse {
pub txid: String,
}
#[derive(Clone, Debug, Deserialize)]
pub struct CreateStorageAccountResponse {
pub shdw_bucket: Option<String>,
pub transaction_signature: String,
}
#[derive(Debug)]
pub struct UploadingData {
pub size: u64,
pub sha256_hash: sha256::Sha256Hash,
pub url: String,
pub file: ShadowFile,
}
impl UploadingData {
pub async fn to_form_part(&self) -> ShadowDriveResult<Part> {
match &self.file.data {
Payload::File(path) => {
let file = File::open(path).await.map_err(Error::FileSystemError)?;
Ok(Part::stream_with_length(file, self.size).file_name(self.file.name.clone()))
}
Payload::Bytes(data) => Ok(Part::stream_with_length(Bytes::clone(&data), self.size)
.file_name(self.file.name.clone())),
}
}
}
#[derive(Debug)]
pub struct ShadowFile {
pub name: String,
pub data: Payload,
}
impl ShadowFile {
pub fn file<T: AsRef<Path>>(name: String, path: T) -> Self {
Self {
name,
data: Payload::File(path.as_ref().to_owned()),
}
}
pub fn bytes<T: Into<Bytes>>(name: String, data: T) -> Self {
Self {
name,
data: Payload::Bytes(data.into()),
}
}
pub async fn prepare_upload(
self,
storage_account_key: &Pubkey,
) -> Result<UploadingData, Vec<FileError>> {
Payload::prepare_upload(self.data, storage_account_key, self.name).await
}
}
#[derive(Clone, Debug, Deserialize)]
pub struct ShadowUploadResponse {
pub finalized_location: String,
pub transaction_signature: String,
}
#[derive(Clone, Debug, Deserialize)]
pub(crate) struct ShdwDriveBatchServerResponse {
pub _finalized_locations: Option<Vec<String>>,
pub transaction_signature: String,
}
#[derive(Clone, Debug, Deserialize)]
pub enum BatchUploadStatus {
Uploaded,
AlreadyExists,
Error(String),
}
#[derive(Clone, Debug, Deserialize)]
pub struct ShadowBatchUploadResponse {
pub file_name: String,
pub status: BatchUploadStatus,
pub location: Option<String>,
pub transaction_signature: Option<String>,
}
#[derive(Clone, Debug, Deserialize)]
pub struct FileDataResponse {
pub file_data: FileData,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct FileData {
pub file_account_pubkey: String,
pub owner_account_pubkey: String,
pub storage_account_pubkey: String,
}
#[derive(Clone, Debug, Deserialize)]
pub struct ListObjectsResponse {
pub keys: Vec<String>,
}