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}