neo3/neo_fs/mod.rs
1// Copyright (c) 2023-2025 R3E Network
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14//! # Neo File Storage (NeoFS) Module (v0.4.1)
15//!
16//! NeoFS is a decentralized distributed object storage network integrated with
17//! the Neo Blockchain. It provides a robust platform for storing, retrieving,
18//! and managing digital assets with blockchain-level security.
19//!
20//! ## Overview
21//!
22//! This module provides Rust bindings to interact with NeoFS services, including:
23//!
24//! - **Container Management**: Create, retrieve, list, and delete NeoFS containers
25//! - **Object Operations**: Upload, download, and manage objects in containers
26//! - **Access Control**: Manage permissions and generate access tokens
27//! - **Extended Features**: Support for multipart uploads and specialized storage operations
28//!
29//! ## Example
30//!
31//! ```ignore
32//! use neo3::neo_fs::{NeoFSClient, NeoFSConfig};
33//! use neo3::neo_fs::container::Container;
34//! use neo3::neo_fs::object::{Object, ObjectId};
35//! use neo3::neo_protocol::Account;
36//! use std::path::Path;
37//!
38//! async fn example() -> Result<(), Box<dyn std::error::Error>> {
39//! // Create an account from a WIF for authentication
40//! let account = Account::from_wif("KwVEKk78X65fDrJ3VgqHLcpPpbQVfJLjXrkFUCozHQBJ5nT2xwP8")?;
41//!
42//! // Configure NeoFS client
43//! let config = NeoFSConfig {
44//! endpoint: "grpc+tls://st01.testnet.fs.neo.org:8082".to_string(),
45//! auth: Some(neo3::neo_fs::NeoFSAuth {
46//! wallet_address: account.get_address(),
47//! private_key: account.key_pair().as_ref().map(|kp| kp.private_key().to_string()),
48//! }),
49//! timeout_sec: 30,
50//! insecure: false,
51//! };
52//!
53//! // Initialize the NeoFS client
54//! let client = NeoFSClient::new(config).await?;
55//!
56//! // List available containers
57//! let containers = client.list_containers().await?;
58//! println!("Found {} containers", containers.len());
59//!
60//! // Create a new container with basic attributes
61//! let mut new_container = Container::new();
62//! new_container.set_name("my-documents");
63//! new_container.set_basic_acl(true, false); // Public read, private write
64//!
65//! // Create the container in NeoFS
66//! let container_id = client.create_container(&new_container).await?;
67//! println!("Created container with ID: {}", container_id);
68//!
69//! // Upload a file to the container
70//! let file_path = Path::new("./example.txt");
71//! let file_data = std::fs::read(file_path)?;
72//!
73//! let mut object = Object::new();
74//! object.set_file_name("example.txt");
75//! object.set_data(file_data);
76//!
77//! let object_id = client.put_object(&container_id, &object).await?;
78//! println!("Uploaded object with ID: {}", object_id);
79//!
80//! // Download the object
81//! let retrieved_object = client.get_object(&container_id, &object_id).await?;
82//! println!("Downloaded object: {} ({} bytes)",
83//! retrieved_object.file_name(),
84//! retrieved_object.data().len());
85//!
86//! // Clean up - delete the object and container
87//! client.delete_object(&container_id, &object_id).await?;
88//! client.delete_container(&container_id).await?;
89//!
90//! Ok(())
91//! }
92//! ```
93
94pub mod acl;
95pub mod client;
96pub mod container;
97pub mod error;
98pub mod object;
99pub mod types;
100
101pub use client::NeoFSClient;
102pub use error::{NeoFSError, NeoFSResult};
103
104// Re-export types directly from types module
105pub use acl::{BearerToken, SessionToken};
106pub use container::Container;
107pub use object::{MultipartUpload, MultipartUploadResult, Object, Part};
108pub use types::{
109 AccessPermission, Attributes, ContainerId, ObjectId, ObjectType, OwnerId, PlacementPolicy,
110};
111
112use async_trait::async_trait;
113use chrono::{DateTime, Utc};
114use serde::{Deserialize, Serialize};
115
116/// The default mainnet NeoFS endpoint
117pub const DEFAULT_MAINNET_ENDPOINT: &str = "grpc+tls://st01.testnet.fs.neo.org:8082";
118
119/// The default testnet NeoFS endpoint
120pub const DEFAULT_TESTNET_ENDPOINT: &str = "grpc+tls://st01.testnet.fs.neo.org:8082";
121
122/// Default NeoFS endpoint
123pub const DEFAULT_ENDPOINT: &str = "grpc.main.fs.neo.org:8082";
124
125/// Represents a NeoFS service provider configuration
126#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct NeoFSConfig {
128 /// The NeoFS service endpoint URL
129 pub endpoint: String,
130 /// Authentication information, typically from a Neo wallet
131 pub auth: Option<NeoFSAuth>,
132 /// Timeout for NeoFS operations in seconds
133 pub timeout_sec: u64,
134 /// Specifies whether to use insecure connections
135 pub insecure: bool,
136}
137
138impl Default for NeoFSConfig {
139 fn default() -> Self {
140 Self {
141 endpoint: DEFAULT_TESTNET_ENDPOINT.to_string(),
142 auth: None,
143 timeout_sec: 60,
144 insecure: false,
145 }
146 }
147}
148
149/// Authentication information for NeoFS
150#[derive(Debug, Clone, Serialize, Deserialize)]
151pub struct NeoFSAuth {
152 /// The wallet account used for authentication
153 pub wallet_address: String,
154 /// The private key to sign NeoFS requests
155 pub private_key: Option<String>,
156}
157
158/// Service trait for interacting with NeoFS
159#[async_trait]
160pub trait NeoFSService {
161 /// Creates a new container in NeoFS
162 async fn create_container(&self, container: &Container) -> NeoFSResult<ContainerId>;
163
164 /// Gets a container by its ID
165 async fn get_container(&self, id: &ContainerId) -> NeoFSResult<Container>;
166
167 /// Lists all containers owned by the current account
168 async fn list_containers(&self) -> NeoFSResult<Vec<ContainerId>>;
169
170 /// Deletes a container by its ID
171 async fn delete_container(&self, id: &ContainerId) -> NeoFSResult<bool>;
172
173 /// Uploads an object to a container
174 async fn put_object(
175 &self,
176 container_id: &ContainerId,
177 object: &Object,
178 ) -> NeoFSResult<ObjectId>;
179
180 /// Gets an object by its ID from a container
181 async fn get_object(
182 &self,
183 container_id: &ContainerId,
184 object_id: &ObjectId,
185 ) -> NeoFSResult<Object>;
186
187 /// Lists all objects in a container
188 async fn list_objects(&self, container_id: &ContainerId) -> NeoFSResult<Vec<ObjectId>>;
189
190 /// Deletes an object by its ID from a container
191 async fn delete_object(
192 &self,
193 container_id: &ContainerId,
194 object_id: &ObjectId,
195 ) -> NeoFSResult<bool>;
196
197 /// Creates a bearer token for accessing objects in a container
198 async fn create_bearer_token(
199 &self,
200 container_id: &ContainerId,
201 permissions: Vec<AccessPermission>,
202 expires_sec: u64,
203 ) -> NeoFSResult<BearerToken>;
204
205 /// Gets a session token for the current account
206 async fn get_session_token(&self) -> NeoFSResult<SessionToken>;
207
208 /// Initiates a multipart upload for a large object
209 async fn initiate_multipart_upload(
210 &self,
211 container_id: &ContainerId,
212 object: &Object,
213 ) -> NeoFSResult<MultipartUpload>;
214
215 /// Uploads a part of a multipart upload
216 async fn upload_part(
217 &self,
218 upload: &MultipartUpload,
219 part_number: u32,
220 data: Vec<u8>,
221 ) -> NeoFSResult<Part>;
222
223 /// Completes a multipart upload
224 async fn complete_multipart_upload(
225 &self,
226 upload: &MultipartUpload,
227 parts: Vec<Part>,
228 ) -> NeoFSResult<MultipartUploadResult>;
229
230 /// Aborts a multipart upload
231 async fn abort_multipart_upload(&self, upload: &MultipartUpload) -> NeoFSResult<bool>;
232}