From fa0f4d4221a45bbfcdaf5306b9c214bce025c000 Mon Sep 17 00:00:00 2001 From: 0xZensh Date: Sat, 21 Dec 2024 23:03:55 +0800 Subject: [PATCH] chore: improve documents. --- README.md | 158 +++++++------------------- docs/access_control.md | 91 +++++++++++++++ examples/ai_canister/README.md | 3 +- examples/upload_js/README.md | 3 +- src/ic_oss/README.md | 7 +- src/ic_oss_bucket/Cargo.toml | 2 +- src/ic_oss_bucket/README.md | 200 ++++++++++++++------------------- src/ic_oss_can/README.md | 63 +++++++---- src/ic_oss_cli/README.md | 51 +++++---- src/ic_oss_cluster/README.md | 172 +++++++++++----------------- src/ic_oss_ts/README.md | 3 +- src/ic_oss_types/README.md | 3 +- 12 files changed, 371 insertions(+), 385 deletions(-) create mode 100644 docs/access_control.md diff --git a/README.md b/README.md index ab495e4..669c9eb 100644 --- a/README.md +++ b/README.md @@ -2,140 +2,66 @@ 🗂 A decentralized Object Storage Service on the Internet Computer. -💝 This project received a **$25k Developer Grant** from the [DFINITY Foundation](https://dfinity.org/grants). +💝 Backed by a **$25k Developer Grant** from the [DFINITY Foundation](https://dfinity.org/grants). ## Overview -`ic-oss` is a fully open-source decentralized object storage service running on the Internet Computer. It provides a simple and efficient way to store and retrieve files, supports large files, and offers unlimited horizontal scalability. It can serve as a reliable decentralized file infrastructure for NFT, chain blocks, verifiable credentials, blogs, documents, knowledge bases, games and other decentralized applications. +`ic-oss` is a decentralized object storage service fully running on the Internet Computer that provides: +- Simple and efficient file storage/retrieval +- File directory tree structure +- Unlimited horizontal scalability +- Enterprise-grade access control -In decentralized enterprise applications, `ic-oss` will be an essential infrastructure. - -`ic-oss` is a file infrastructure service, not a end user product. +Perfect for NFTs, chain blocks, verifiable credentials, blogs, documents, and decentralized applications. ![IC-OSS](./ic-oss.webp) -## Features - -- [x] Supports large file uploads and downloads through file sharding, concurrent high-speed uploads, resumable uploads, and segmented downloads. -- [x] Provides data verification based on ICP's verification mechanisms to ensure file integrity during reading. -- [x] Supports file directory tree. -- [x] Access control with permissions for public, private, read-only, and write-only for files, folders, and buckets. -- [x] Based on a file bucket and cluster architecture, with each bucket corresponding to a ICP canister, allowing for unlimited horizontal scalability. - -## Libraries - -| Library | Description | -| :--------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------- | -| [ic_oss_bucket](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_bucket) | An ICP smart contract and a storage bucket in the ic-oss cluster for storing files and folders. | -| [ic_oss_cluster](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_cluster) | An ICP smart contract and the manager of the ic-oss cluster. | -| [ic-oss-can](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_can) | A Rust library for implementing large file storage in ICP canisters. | -| [ic-oss-types](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_types) | A Rust types library used for integrating with ic-oss cluster. | -| [ic-oss](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss) | The Rust version of the client SDK for the ic-oss cluster. | -| [ic_oss_ts](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_ts) | The Typescript version of the client SDK for the ic-oss cluster. | -| [ic-oss-cli](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_cli) | A command-line tool implemented in Rust for the ic-oss cluster. | -| [examples/ai_canister](https://github.com/ldclabs/ic-oss/tree/main/examples/ai_canister) | A Rust demonstration project used to show how to implement large file storage in the ICP canister by using `ic-oss-can`. | -| [examples/upload_js](https://github.com/ldclabs/ic-oss/tree/main/examples/upload_js) | A Javascript demonstration project used to show how to upload files to ic_oss_bucket canister by using `@ldclabs/ic_oss_ts`. | - -## Integration Workflow - -![IC-OSS Sequence](./ic-oss-sequence.webp) - -How to integrate `ic-oss`: -1. The backend of the Dapp calls the API of `ic_oss_cluster` to add access control policies for the user. -2. The frontend of the Dapp uses the `ic-oss-ts` SDK to obtain the `access_token` of the target `ic_oss_bucket` from `ic_oss_cluster`. -3. The frontend of the Dapp uses the `access_token` to call the API of the target `ic_oss_bucket` to operate the authorized files and folders. - -## Access Control - -`ic-oss` provides 4 different access control mechanisms for file resources, which can adapt to scenarios ranging from minimalist ones to complex enterprise-level permission control scenarios. - -### The `managers` and `auditors` attributes of the Bucket - -Managers can operate on all files and folders in the bucket, including creating, deleting, moving, modifying, etc. - -Auditors can view all files and folders in the bucket, including archived (status == -1) resources, but cannot perform modification operations. - -The `admin_set_managers` interface and the `admin_set_auditors` interface can set the managers and auditors of the bucket, and the `admin_update_bucket` can update other attributes of the bucket. However, only the controllers of the canister have the permission to call these 3 interfaces. +## Key Features -### The `visibility` attribute of the Bucket +- Large File Support + - File sharding + - File encryption + - Concurrent high-speed uploads + - Resumable uploads + - Segmented downloads +- Advanced Organization + - File directory tree structure + - Bucket-based clustering +- Flexible Access Control + - Public/private access + - Read/write permissions + - File/folder/bucket level controls -`visibility` controls the visibility of the bucket and has 2 values: -- 0: Private, only users with access permission to the bucket can access it. -- 1: Public, any user without permission can view all files and folders in the bucket, but does not include archived (status == -1) resources, and cannot perform modification operations. +## Packages -The `admin_update_bucket` can update the `visibility` attribute of the bucket. +| Package | Description | +| :------------------------------------------------------------------------------- | :----------------------------------------------------------- | +| [ic_oss_bucket](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_bucket) | Storage bucket smart contract | +| [ic_oss_cluster](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_cluster) | Cluster management smart contract | +| [ic-oss-can](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_can) | Rust library for implementing file storage in smart contract | +| [ic-oss-types](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_types) | Rust shared type definitions | +| [ic-oss](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss) | Rust client SDK | +| [ic_oss_ts](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_ts) | Typescript client SDK | +| [ic-oss-cli](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_cli) | Command-line tool implemented in Rust | -### The `status` attribute of the Bucket +## Who's using? -`status` controls the status of the bucket and has 3 values: -- 0: Normal, all operations can be performed. -- 1: Read-only, only read operations can be performed, and write operations cannot be performed. -- -1: Archived. Only `managers` and `auditors` can view all files and folders in the bucket, and no other operations can be performed. -Files and folders also have a `status` attribute, and its definition is similar to the above. +- [dMsg.net](https://dmsg.net): The world's 1st decentralized end-to-end encrypted messaging application fully running on the Internet Computer blockchain. -### Access Control based on `access_token` and Permissions Policy +If you plan to use this project and have any questions, feel free to open an issue. I will address it as soon as possible. -Based on `access_token` and permissions policy, more complex and fine-grained access control can be achieved for files and folders in the bucket. +## Integration -`ic_oss_cluster` records the user's permissions policies and issues `access_token` for the user. The `access_token` contains the user's permission information. `ic_oss_bucket` verifies the `access_token` and determines whether the user has the permission to perform the operation based on the permission information in it. - -The managers of `ic_oss_cluster` can use the `admin_attach_policies` and `admin_detach_policies` interfaces to assign or cancel permissions for the user. - -#### Access Token - -The `access_token` implemented by `ic-oss` based on COSE (RFC9052) and CWT (RFC8392) supports two signature algorithms: Secp256k1 and Ed25519. The permissions policies are stored in the `scope (9)` field of the `access_token`. The core information of the Token is as follows: - -```rust -pub struct Token { - pub subject: Principal, // the owner of the token - pub audience: Principal, // the canister id of the bucket - pub policies: String, // the permission policies -} -``` -For the complete implementation, please refer to the [ic-oss-cose](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_cose) library. - -#### Permissions Policy - -`ic-oss` has designed a set of simple yet powerful permission policy patterns, which can achieve from simple read and write permissions to complex enterprise-level permission control. - -The basic expression of Permission is as follows: - -```shell -Resource.Operation[.Constraint] -``` - -Permission examples: -```shell -* # == *.* -File.Read # == File.Read.* -Folder.Write # == Folder.Write.* -Bucket.Read # == Bucket.Read.* -Bucket.Read.Info -Bucket.*.File -``` - -The basic expression of Permission Policy is as follows: - -```shell -Permission:Resource1,Resource2,... -``` - -Permission Policy examples: -```shell -File.*:* # == File.* -File.Read:* # == File.Read -Folder.Write:1,2 -Bucket.Read:* # == Bucket.Read -``` +![IC-OSS Sequence](./ic-oss-sequence.webp) -The scope of `access_token` contains 1 to n Permission Policies, separated by spaces. +1. Dapp backend: Configure access control via `ic_oss_cluster` +2. Dapp frontend: Obtain `access_token` using `ic-oss-ts` SDK +3. Dapp frontend: Use token to interact with `ic_oss_bucket` -Permission Policies examples: -```shell -scope = "File.*:1 Folder.*:2,3,5 Folder.Read Bucket.Read" -``` +## Examples -For the complete implementation, please refer to the [ic-oss-types](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_types) library. +- [examples/ai_canister](https://github.com/ldclabs/ic-oss/tree/main/examples/ai_canister): A Rust demonstration project used to show how to implement large file storage in the ICP canister by using `ic-oss-can`. +- [examples/upload_js](https://github.com/ldclabs/ic-oss/tree/main/examples/upload_js): A Javascript demonstration project used to show how to upload files to ic_oss_bucket canister by using `@ldclabs/ic_oss_ts`. ## License Copyright © 2024-2025 [LDC Labs](https://github.com/ldclabs). diff --git a/docs/access_control.md b/docs/access_control.md new file mode 100644 index 0000000..1490a1a --- /dev/null +++ b/docs/access_control.md @@ -0,0 +1,91 @@ +# `IC-OSS` Access Control + +`ic-oss` provides 4 different access control mechanisms for file resources, which can adapt to scenarios ranging from minimalist ones to complex enterprise-level permission control scenarios. + +## The `managers` and `auditors` attributes of the Bucket + +Managers can operate on all files and folders in the bucket, including creating, deleting, moving, modifying, etc. + +Auditors can view all files and folders in the bucket, including archived (status == -1) resources, but cannot perform modification operations. + +The `admin_set_managers` interface and the `admin_set_auditors` interface can set the managers and auditors of the bucket, and the `admin_update_bucket` can update other attributes of the bucket. However, only the controllers of the canister have the permission to call these 3 interfaces. + +## The `visibility` attribute of the Bucket + +`visibility` controls the visibility of the bucket and has 2 values: +- 0: Private, only users with access permission to the bucket can access it. +- 1: Public, any user without permission can view all files and folders in the bucket, but does not include archived (status == -1) resources, and cannot perform modification operations. + +The `admin_update_bucket` can update the `visibility` attribute of the bucket. + +## The `status` attribute of the Bucket + +`status` controls the status of the bucket and has 3 values: +- 0: Normal, all operations can be performed. +- 1: Read-only, only read operations can be performed, and write operations cannot be performed. +- -1: Archived. Only `managers` and `auditors` can view all files and folders in the bucket, and no other operations can be performed. +Files and folders also have a `status` attribute, and its definition is similar to the above. + +## Access Control based on `access_token` and Permissions Policy + +Based on `access_token` and permissions policy, more complex and fine-grained access control can be achieved for files and folders in the bucket. + +`ic_oss_cluster` records the user's permissions policies and issues `access_token` for the user. The `access_token` contains the user's permission information. `ic_oss_bucket` verifies the `access_token` and determines whether the user has the permission to perform the operation based on the permission information in it. + +The managers of `ic_oss_cluster` can use the `admin_attach_policies` and `admin_detach_policies` interfaces to assign or cancel permissions for the user. + +### Access Token + +The `access_token` implemented by `ic-oss` based on COSE (RFC9052) and CWT (RFC8392) supports two signature algorithms: Secp256k1 and Ed25519. The permissions policies are stored in the `scope (9)` field of the `access_token`. The core information of the Token is as follows: + +```rust +pub struct Token { + pub subject: Principal, // the owner of the token + pub audience: Principal, // the canister id of the bucket + pub policies: String, // the permission policies +} +``` +For the complete implementation, please refer to the [ic-oss-cose](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_cose) library. + +### Permissions Policy + +`ic-oss` has designed a set of simple yet powerful permission policy patterns, which can achieve from simple read and write permissions to complex enterprise-level permission control. + +The basic expression of Permission is as follows: + +```shell +Resource.Operation[.Constraint] +``` + +Permission examples: +```shell +* # == *.* +File.Read # == File.Read.* +Folder.Write # == Folder.Write.* +Bucket.Read # == Bucket.Read.* +Bucket.Read.Info +Bucket.*.File +``` + +The basic expression of Permission Policy is as follows: + +```shell +Permission:Resource1,Resource2,... +``` + +Permission Policy examples: +```shell +File.*:* # == File.* +File.Read:* # == File.Read +Folder.Write:1,2 +Bucket.Read:* # == Bucket.Read +``` + +The scope of `access_token` contains 1 to n Permission Policies, separated by spaces. + +Permission Policies examples: +```shell +scope = "File.*:1 Folder.*:2,3,5 Folder.Read Bucket.Read" +``` + +For the complete implementation, please refer to the [ic-oss-types](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_types) library. diff --git a/examples/ai_canister/README.md b/examples/ai_canister/README.md index 4bea75d..b58f300 100644 --- a/examples/ai_canister/README.md +++ b/examples/ai_canister/README.md @@ -43,6 +43,7 @@ dfx canister call ai_canister list_files '(0, null, null, null)' ``` ## License + Copyright © 2024-2025 [LDC Labs](https://github.com/ldclabs). -`ldclabs/ic-oss` is licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for the full license text. +Licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for details. diff --git a/examples/upload_js/README.md b/examples/upload_js/README.md index f370ff7..ecf6639 100644 --- a/examples/upload_js/README.md +++ b/examples/upload_js/README.md @@ -43,6 +43,7 @@ dfx canister call ai_canister list_files '(0, null, null, null)' ``` ## License + Copyright © 2024-2025 [LDC Labs](https://github.com/ldclabs). -`ldclabs/ic-oss` is licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for the full license text. +Licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for details. diff --git a/src/ic_oss/README.md b/src/ic_oss/README.md index ac7706c..f9c9405 100644 --- a/src/ic_oss/README.md +++ b/src/ic_oss/README.md @@ -9,7 +9,12 @@ `ic-oss` is the Rust version of the client SDK for the ic-oss cluster. +## Documentation + +For detailed documentation, please visit: https://docs.rs/ic-oss + ## License + Copyright © 2024-2025 [LDC Labs](https://github.com/ldclabs). -`ldclabs/ic-oss` is licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for the full license text. \ No newline at end of file +Licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for details. diff --git a/src/ic_oss_bucket/Cargo.toml b/src/ic_oss_bucket/Cargo.toml index c56801c..60d8325 100644 --- a/src/ic_oss_bucket/Cargo.toml +++ b/src/ic_oss_bucket/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ic_oss_bucket" -description = "An ICP smart contract and a storage bucket in the ic-oss cluster for storing files and folders." +description = "A decentralized Object Storage Service bucket on the Internet Computer, part of IC-OSS." publish = false repository = "https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_bucket" version.workspace = true diff --git a/src/ic_oss_bucket/README.md b/src/ic_oss_bucket/README.md index 62451d8..53533d4 100644 --- a/src/ic_oss_bucket/README.md +++ b/src/ic_oss_bucket/README.md @@ -1,76 +1,56 @@ # `ic_oss_bucket` -[ic-oss](https://github.com/ldclabs/ic-oss) is a decentralized Object Storage Service on the Internet Computer. +A decentralized Object Storage Service bucket on the Internet Computer, part of [ic-oss](https://github.com/ldclabs/ic-oss). -`ic_oss_bucket` is an ICP smart contract and a storage bucket in the `ic-oss` cluster for storing files and folders. The `ic-oss` cluster can deploy one or more buckets for horizontal file storage scaling, managed by `ic_oss_cluster`. +## Overview -**Online Demo**: https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=mmrxu-fqaaa-aaaap-ahhna-cai - -Get the file `0` in browser: -- Download by file id: https://mmrxu-fqaaa-aaaap-ahhna-cai.icp0.io/f/0 -- Download by file hash: https://mmrxu-fqaaa-aaaap-ahhna-cai.icp0.io/h/aff18ec0c48fecaae80ee7f506f3feddd8640f9c03a98aed1d4b7a39bb5c7fdc -- Get it inline by file id: https://mmrxu-fqaaa-aaaap-ahhna-cai.icp0.io/f/0?inline -- Get it inline by file hash: https://mmrxu-fqaaa-aaaap-ahhna-cai.icp0.io/h/aff18ec0c48fecaae80ee7f506f3feddd8640f9c03a98aed1d4b7a39bb5c7fdc?inline +`ic_oss_bucket` is an ICP smart contract that functions as a storage bucket in the `ic-oss` cluster. Multiple buckets can be deployed for horizontal scaling, all managed by `ic_oss_cluster`. ## Features -- [x] Supports large file uploads and downloads through file sharding, concurrent high-speed uploads, resumable uploads, and segmented downloads. -- [x] Provides data verification based on ICP's verification mechanisms to ensure file integrity during reading. -- [x] Supports file directory tree. -- [x] Access control with permissions for public, private, read-only, and write-only for files, folders, and buckets. - -## Candid API - -```shell -admin_add_auditors : (vec principal) -> (Result); -admin_add_managers : (vec principal) -> (Result); -admin_remove_auditors : (vec principal) -> (Result); -admin_remove_managers : (vec principal) -> (Result); -admin_set_auditors : (vec principal) -> (Result); -admin_set_managers : (vec principal) -> (Result); -admin_update_bucket : (UpdateBucketInput) -> (Result); -api_version : () -> (nat16) query; -batch_delete_subfiles : (nat32, vec nat32, opt blob) -> (Result_1); -create_file : (CreateFileInput, opt blob) -> (Result_2); -create_folder : (CreateFolderInput, opt blob) -> (Result_2); -delete_file : (nat32, opt blob) -> (Result_3); -delete_folder : (nat32, opt blob) -> (Result_3); -get_bucket_info : (opt blob) -> (Result_4) query; -get_canister_status : () -> (Result_5); -get_file_ancestors : (nat32, opt blob) -> (Result_6) query; -get_file_chunks : (nat32, nat32, opt nat32, opt blob) -> (Result_7) query; -get_file_info : (nat32, opt blob) -> (Result_8) query; -get_file_info_by_hash : (blob, opt blob) -> (Result_8) query; -get_folder_ancestors : (nat32, opt blob) -> (Result_6) query; -get_folder_info : (nat32, opt blob) -> (Result_9) query; -list_files : (nat32, opt nat32, opt nat32, opt blob) -> (Result_10) query; -list_folders : (nat32, opt nat32, opt nat32, opt blob) -> (Result_11) query; -move_file : (MoveInput, opt blob) -> (Result_12); -move_folder : (MoveInput, opt blob) -> (Result_12); -update_file_chunk : (UpdateFileChunkInput, opt blob) -> (Result_13); -update_file_info : (UpdateFileInput, opt blob) -> (Result_12); -update_folder_info : (UpdateFolderInput, opt blob) -> (Result_12); -validate2_admin_set_auditors : (vec principal) -> (Result_14); -validate2_admin_set_managers : (vec principal) -> (Result_14); -validate2_admin_update_bucket : (UpdateBucketInput) -> (Result_14); -validate_admin_add_auditors : (vec principal) -> (Result_14); -validate_admin_add_managers : (vec principal) -> (Result_14); -validate_admin_remove_auditors : (vec principal) -> (Result_14); -validate_admin_remove_managers : (vec principal) -> (Result_14); -validate_admin_set_auditors : (vec principal) -> (Result); -validate_admin_set_managers : (vec principal) -> (Result); -validate_admin_update_bucket : (UpdateBucketInput) -> (Result); +- Supports large file uploads and downloads through file sharding, concurrent high-speed uploads, resumable uploads, and segmented downloads. +- Enables HTTP streaming and HTTP range downloads. +- Ensures file deduplication and retrieval using file hash indexing. +- Supports encrypted file storage and file-level encryption keys. +- Allows custom metadata for files. +- Provides a directory tree structure, enabling file and folder movement within the same bucket. +- Offers public and private modes for a bucket. +- Supports archive, read-write, and read-only status for files, folders, and buckets. +- Enables fine-grained access control for reading, writing, and deleting files, folders, and buckets. +- Includes auditors with the ability to read all contents within a bucket. + +## Demo + +Try it online: https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=mmrxu-fqaaa-aaaap-ahhna-cai + +Access file through HTTPs: ``` +# Direct download +https://mmrxu-fqaaa-aaaap-ahhna-cai.icp0.io/f/1 # By ID +https://mmrxu-fqaaa-aaaap-ahhna-cai.icp0.io/h/ # By hash, when enable_hash_index = true -The complete Candid API definition can be found in the [ic_oss_bucket.did](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_bucket/ic_oss_bucket.did) file. +# Download with filename +https://mmrxu-fqaaa-aaaap-ahhna-cai.icp0.io/f/1?filename=mydoc.md + +# Download with token +https://mmrxu-fqaaa-aaaap-ahhna-cai.icp0.io/f/1?filename=mydoc.md&token= + +# Inline viewing +https://mmrxu-fqaaa-aaaap-ahhna-cai.icp0.io/f/1?inline +https://mmrxu-fqaaa-aaaap-ahhna-cai.icp0.io/f/2?inline +``` -## Running locally +## Quick Start -Deploy to local network: +### Local Deployment + +1. Deploy the canister: ```bash dfx deploy ic_oss_bucket +``` -# or with arguments +Or with custom configuration: +```bash # dfx canister create --specified-id mmrxu-fqaaa-aaaap-ahhna-cai ic_oss_bucket dfx deploy ic_oss_bucket --argument "(opt variant {Init = record { @@ -84,78 +64,70 @@ dfx deploy ic_oss_bucket --argument "(opt variant {Init = enable_hash_index = false; } })" +``` -dfx canister call ic_oss_bucket get_bucket_info '(null)' - +2. Set up permissions: +```bash +# Get your principal MYID=$(dfx identity get-principal) +# Get the uploader principal ic-oss-cli -i debug/uploader.pem identity # principal: nprym-ylvyz-ig3fr-lgcmn-zzzt4-tyuix-3v6bm-fsel7-6lq6x-zh2w7-zqe -# add managers -dfx canister call ic_oss_bucket admin_set_managers "(vec {principal \"$MYID\"; principal \"nprym-ylvyz-ig3fr-lgcmn-zzzt4-tyuix-3v6bm-fsel7-6lq6x-zh2w7-zqe\"})" +# Add managers +dfx canister call ic_oss_bucket admin_add_managers "(vec {principal \"$MYID\"; principal \"nprym-ylvyz-ig3fr-lgcmn-zzzt4-tyuix-3v6bm-fsel7-6lq6x-zh2w7-zqe\"})" -# add public keys to verify the access tokens +# Configure public keys and visibility dfx canister call ic_oss_bucket admin_update_bucket '(record { - name = null; - max_file_size = null; - max_folder_depth = null; - max_children = null; - max_custom_data_size = null; - enable_hash_index = null; - status = null; visibility = opt 1; - trusted_ecdsa_pub_keys = opt vec {blob "\02\bd\ef\d5\d8\91\7a\81\cc\91\60\ba\19\95\69\d4\47\d9\d4\7e\e6\71\6c\b8\dc\18\aa\d2\be\8c\4c\cd\eb"}; - trusted_eddsa_pub_keys = opt vec {vec {19; 152; 246; 44; 109; 26; 69; 124; 81; 186; 106; 75; 95; 61; 189; 47; 105; 252; 169; 50; 22; 33; 141; 200; 153; 126; 65; 107; 209; 125; 147; 202}}; + trusted_eddsa_pub_keys = opt vec {blob "..."}; # Your public key here }, null)' +``` -# list files in the folder 2, with a access token -dfx canister call ic_oss_bucket list_files '(2, null, null, opt blob "\84\44\a1\01\38\2e\a0\58\ac\a7\01\78\1b\61\6a\75\71\34\2d\72\75\61\61\61\2d\61\61\61\61\61\2d\71\61\61\67\61\2d\63\61\69\02\78\3f\7a\37\77\6a\70\2d\76\36\66\65\33\2d\6b\6b\73\75\35\2d\32\36\66\36\34\2d\64\65\64\74\77\2d\6a\37\6e\64\6a\2d\35\37\6f\6e\78\2d\71\67\61\36\63\2d\65\74\35\65\33\2d\6e\6a\78\35\33\2d\74\61\65\03\78\1b\6d\6d\72\78\75\2d\66\71\61\61\61\2d\61\61\61\61\70\2d\61\68\68\6e\61\2d\63\61\69\04\1a\66\8f\ce\68\05\1a\66\8f\c0\58\06\1a\66\8f\c0\58\09\78\18\46\6f\6c\64\65\72\2e\2a\3a\31\20\42\75\63\6b\65\74\2e\52\65\61\64\2e\2a\58\40\52\66\3e\e7\55\7e\99\2c\66\6d\65\56\54\9f\30\a1\2e\aa\56\69\66\b6\c6\e9\75\d7\c9\02\4c\24\1d\5d\7e\83\7d\c1\13\c6\00\91\56\d9\6a\ae\34\c3\a5\c9\b4\99\b3\47\b7\68\54\8d\dd\9c\9a\9b\a0\f9\1a\f5")' - -# list folders in the root folder 0 -dfx canister call ic_oss_bucket list_folders '(0, null, null, null)' +3. Basic operations: +```bash +# Get bucket info +dfx canister call ic_oss_bucket get_bucket_info '(null)' -# upload a file to the bucket +# Upload a file ic-oss-cli -i debug/uploader.pem put -b mmrxu-fqaaa-aaaap-ahhna-cai --path README.md -# read the file info -dfx canister call ic_oss_bucket get_file_info '(1, null)' - -# update the file 1's status to 0 -dfx canister call ic_oss_bucket update_file_info "(record { - id = 1; - status = opt 0; -}, null)" - -# create a folder in the root folder -dfx canister call ic_oss_bucket create_folder "(record { - parent = 0; - name = \"home\"; -}, null)" - -dfx canister call ic_oss_bucket create_folder "(record { - parent = 1; - name = \"jarvis\"; -}, null)" - -# move the file 1 from the root folder 0 to the folder 2 -dfx canister call ic_oss_bucket move_file "(record { - id = 1; - from = 0; - to = 2; -}, null)" - -dfx canister call ic_oss_bucket list_files '(2, null, null, null)' - -# delete the file 1 -dfx canister call ic_oss_bucket delete_file '(1, null)' +# Create folders +dfx canister call ic_oss_bucket create_folder '(record { parent = 0; name = "home"; }, null)' + +# List contents +dfx canister call ic_oss_bucket list_files '(0, null, null, null)' # Files +dfx canister call ic_oss_bucket list_folders '(0, null, null, null)' # Folders ``` -Download the file in browser: -- by file id: `http://mmrxu-fqaaa-aaaap-ahhna-cai.localhost:4943/f/1` -- by file hash: `http://mmrxu-fqaaa-aaaap-ahhna-cai.localhost:4943/h/b7bb9040d64479a7ca56c8e03ae2daddc819859f7b858488c0b998eeded6dede` +## API Reference +The canister exposes a comprehensive Candid API. Key endpoints include: + +```candid +# File Operations +create_file : (CreateFileInput, opt blob) -> (Result_2) +update_file_chunk : (UpdateFileChunkInput, opt blob) -> (Result_13) +update_file_info : (UpdateFileInput, opt blob) -> (Result_12) +get_file_info : (nat32, opt blob) -> (Result_8) query +get_file_chunks : (nat32, nat32, opt nat32, opt blob) -> (Result_7) query +list_files : (nat32, opt nat32, opt nat32, opt blob) -> (Result_10) query +delete_file : (nat32, opt blob) -> (Result_3) + +# Folder Operations +create_folder : (CreateFolderInput, opt blob) -> (Result_2) +list_folders : (nat32, opt nat32, opt nat32, opt blob) -> (Result_11) query +delete_folder : (nat32, opt blob) -> (Result_3) + +# Admin Operations +admin_add_managers : (vec principal) -> (Result) +admin_update_bucket : (UpdateBucketInput) -> (Result) +``` + +Full Candid API definition: [ic_oss_bucket.did](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_bucket/ic_oss_bucket.did) ## License + Copyright © 2024-2025 [LDC Labs](https://github.com/ldclabs). -`ldclabs/ic-oss` is licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for the full license text. \ No newline at end of file +Licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for details. \ No newline at end of file diff --git a/src/ic_oss_can/README.md b/src/ic_oss_can/README.md index cab9dad..88c6dee 100644 --- a/src/ic_oss_can/README.md +++ b/src/ic_oss_can/README.md @@ -1,18 +1,33 @@ # `ic-oss-can` ![License](https://img.shields.io/crates/l/ic-oss.svg) -[![Crates.io](https://img.shields.io/crates/d/ic-oss.svg)](https://crates.io/crates/ic-oss) +[![Crates.io](https://img.shields.io/crates/d/ic-oss-can.svg)](https://crates.io/crates/ic-oss-can) [![CI](https://github.com/ldclabs/ic-oss/actions/workflows/ci.yml/badge.svg)](https://github.com/ldclabs/ic-oss/actions/workflows/ci.yml) -[![Docs.rs](https://img.shields.io/docsrs/ic-oss?label=docs.rs)](https://docs.rs/ic-oss) -[![Latest Version](https://img.shields.io/crates/v/ic-oss.svg)](https://crates.io/crates/ic-oss) +[![Docs.rs](https://img.shields.io/docsrs/ic-oss-can?label=docs.rs)](https://docs.rs/ic-oss-can) +[![Latest Version](https://img.shields.io/crates/v/ic-oss-can.svg)](https://crates.io/crates/ic-oss-can) -[ic-oss](https://github.com/ldclabs/ic-oss) is a decentralized Object Storage Service on the Internet Computer. +A Rust library for implementing large file storage in Internet Computer (ICP) canisters. Part of the [ic-oss](https://github.com/ldclabs/ic-oss). -`ic-oss-can` is a Rust library for implementing large file storage in ICP canisters. By including the `ic_oss_fs!` macro in your canister, a `fs` module and a set of Candid filesystem APIs will be automatically generated. You can use the `ic-oss-cli` tool to upload files to the ICP canister. +## Features -## Usage +- Simple integration with the `ic_oss_fs!` macro +- Automatic generation of filesystem APIs in Candid format +- Using given `FS_CHUNKS_STORE` stable storage +- File chunk management and retrieval +- Access control with manager roles +- Compatible with `ic-oss-cli` for file uploads -The following example is a minimal version using the `ic_oss_fs!` macro. Its only dependency is a thread-local constant named `FS_CHUNKS_STORE` of type `RefCell>`. +## Quick Start + +Add the following dependencies to your `Cargo.toml`: + +```toml +[dependencies] +ic-oss-can = "0.9" +ic-oss-types = "0.9" +``` + +### Basic Implementation ```rust use ic_stable_structures::{ @@ -46,31 +61,36 @@ thread_local! { ic_oss_fs!(); ``` -For a more complete example, refer to [examples/ai_canister](https://github.com/ldclabs/ic-oss/tree/main/examples/ai_canister). +## Available APIs -### FS Module +### Rust Module APIs ```rust -fs::set_max_file_size(size: u64); -fs::set_visibility(visibility: u8); -fs::set_managers(managers: BTreeSet); -fs::is_manager(caller: &Principal) -> bool; -fs::with(f: impl FnOnce(&Files) -> R) -> R; -fs::load(); -fs::save(); +// File Management fs::get_file(id: u32) -> Option; fs::list_files(prev: u32, take: u32) -> Vec; fs::add_file(file: FileMetadata) -> Result; fs::update_file(change: UpdateFileInput, now_ms: u64) -> Result<(), String>; +fs::delete_file(id: u32) -> Result; + +// Chunk Operations fs::get_chunk(id: u32, chunk_index: u32) -> Option; fs::get_full_chunks(id: u32) -> Result, String>; fs::update_chunk(id: u32, chunk_index: u32, now_ms: u64, chunk: Vec) -> Result; -fs::delete_file(id: u32) -> Result; + +// Configuration +fs::set_max_file_size(size: u64); +fs::set_visibility(visibility: u8); +fs::set_managers(managers: BTreeSet); +fs::is_manager(caller: &Principal) -> bool; +fs::with(f: impl FnOnce(&Files) -> R) -> R; +fs::load(); +fs::save(); ``` -### FS Candid API +### Candid Interface -```shell +```candid create_file : (CreateFileInput, opt blob) -> (Result_2); delete_file : (nat32, opt blob) -> (Result_3); list_files : (nat32, opt nat32, opt nat32, opt blob) -> (Result_4) query; @@ -78,9 +98,10 @@ update_file_chunk : (UpdateFileChunkInput, opt blob) -> (Result_6); update_file_info : (UpdateFileInput, opt blob) -> (Result_7); ``` -The complete module API Candid API definition can be found in the [store.rs](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_can/src/store.rs) file. +For complete API definitions and examples, see: +- [Full Example](https://github.com/ldclabs/ic-oss/tree/main/examples/ai_canister) ## License Copyright © 2024-2025 [LDC Labs](https://github.com/ldclabs). -`ldclabs/ic-oss` is licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for the full license text. +Licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for details. diff --git a/src/ic_oss_cli/README.md b/src/ic_oss_cli/README.md index c5eda6c..640a9cc 100644 --- a/src/ic_oss_cli/README.md +++ b/src/ic_oss_cli/README.md @@ -5,53 +5,62 @@ [![Docs.rs](https://img.shields.io/docsrs/ic-oss-cli?label=docs.rs)](https://docs.rs/ic-oss-cli) [![Latest Version](https://img.shields.io/crates/v/ic-oss-cli.svg)](https://crates.io/crates/ic-oss-cli) -[ic-oss](https://github.com/ldclabs/ic-oss) is a decentralized Object Storage Service on the Internet Computer. +A command-line tool implemented in Rust for [ic-oss](https://github.com/ldclabs/ic-oss), a decentralized Object Storage Service on the Internet Computer. -`ic-oss-cli` is a command-line tool implemented in Rust for the `ic-oss` cluster. +## Installation -## Usage - -Install: +### Via Cargo ```sh cargo install ic-oss-cli # get help info ic-oss-cli --help -ic-oss-cli identity --help -ic-oss-cli upload --help - -# Generate a new identity -ic-oss-cli identity --new --path myid.pem -# Output: -# principal: lxph3-nvpsv-yrevd-im4ug-qywcl-5ir34-rpsbs-6olvf-qtugo-iy5ai-jqe -# new identity: myid.pem ``` -Build from source: +### From Source ```sh git clone https://github.com/ldclabs/ic-oss.git cd ic-oss -# build cargo build -p ic-oss-cli --release # get help info target/release/ic-oss-cli --help ``` -Upload a file to the local canister: +## Quick Start + +### Identity Management ```sh -ic-oss-cli -i myid.pem put -b mmrxu-fqaaa-aaaap-ahhna-cai --path test.tar.gz +# Generate a new identity +ic-oss-cli identity --new --path myid.pem + +# Expected output: +# principal: lxph3-nvpsv-yrevd-im4ug-qywcl-5ir34-rpsbs-6olvf-qtugo-iy5ai-jqe +# new identity: myid.pem ``` -Upload a file to the mainnet canister: +### File Operations ```sh +# Upload to local canister +ic-oss-cli -i myid.pem put -b mmrxu-fqaaa-aaaap-ahhna-cai --path test.tar.gz + +# Upload to mainnet canister ic-oss-cli -i myid.pem put -b mmrxu-fqaaa-aaaap-ahhna-cai --path test.tar.gz --ic + +# Add WASM to cluster +ic-oss-cli -i debug/uploader.pem cluster-add-wasm \ + -c x5573-nqaaa-aaaap-ahopq-cai \ + --path target/wasm32-unknown-unknown/release/ic_oss_bucket.wasm ``` -Add a wasm file to the cluster: +## Documentation +For detailed usage instructions: ```sh -ic-oss-cli -i debug/uploader.pem cluster-add-wasm -c x5573-nqaaa-aaaap-ahopq-cai --path target/wasm32-unknown-unknown/release/ic_oss_bucket.wasm +ic-oss-cli --help +ic-oss-cli identity --help +ic-oss-cli upload --help ``` ## License + Copyright © 2024-2025 [LDC Labs](https://github.com/ldclabs). -`ldclabs/ic-oss` is licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for the full license text. \ No newline at end of file +Licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for details. \ No newline at end of file diff --git a/src/ic_oss_cluster/README.md b/src/ic_oss_cluster/README.md index 72a0056..5c7202c 100644 --- a/src/ic_oss_cluster/README.md +++ b/src/ic_oss_cluster/README.md @@ -1,80 +1,23 @@ # `ic_oss_cluster` -[ic-oss](https://github.com/ldclabs/ic-oss) is a decentralized Object Storage Service on the Internet Computer. +A decentralized Object Storage Service manager on the Internet Computer, part of [ic-oss](https://github.com/ldclabs/ic-oss). -`ic_oss_cluster` is an ICP smart contract and the manager of the `ic-oss` cluster. +## Features -**Online Demo**: https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=x5573-nqaaa-aaaap-ahopq-cai +- Bucket permission policies management and access_token issuance +- Bucket deployment management +- Bucket recharge management -## Features +## Demo -- [x] Manages access control policies and issue access tokens for users. -- [x] Manages `ic_oss_bucket` smart contract versions, including deploying and upgrading buckets. - -## Candid API - -```shell -access_token : (principal) -> (Result); -admin_add_committers : (vec principal) -> (Result_1); -admin_add_managers : (vec principal) -> (Result_1); -admin_add_wasm : (AddWasmInput, opt blob) -> (Result_1); -admin_attach_policies : (Token) -> (Result_1); -admin_batch_call_buckets : (vec principal, text, opt blob) -> (Result_2); -admin_create_bucket : (opt CanisterSettings, opt blob) -> (Result_3); -admin_deploy_bucket : (DeployWasmInput, opt blob) -> (Result_1); -admin_detach_policies : (Token) -> (Result_1); -admin_ed25519_access_token : (Token) -> (Result); -admin_remove_committers : (vec principal) -> (Result_1); -admin_remove_managers : (vec principal) -> (Result_1); -admin_set_managers : (vec principal) -> (Result_1); -admin_sign_access_token : (Token) -> (Result); -admin_topup_all_buckets : () -> (Result_4); -admin_update_bucket_canister_settings : (UpdateSettingsArgument) -> ( - Result_1, - ); -admin_upgrade_all_buckets : (opt blob) -> (Result_1); -admin_weak_access_token : (Token, nat64, nat64) -> (Result) query; -bucket_deployment_logs : (opt nat, opt nat) -> (Result_5) query; -ed25519_access_token : (principal) -> (Result); -get_bucket_wasm : (blob) -> (Result_6) query; -get_buckets : () -> (Result_7) query; -get_canister_status : (opt principal) -> (Result_8); -get_cluster_info : () -> (Result_9) query; -get_deployed_buckets : () -> (Result_5) query; -get_subject_policies : (principal) -> (Result_10) query; -get_subject_policies_for : (principal, principal) -> (Result_11) query; -validate2_admin_add_wasm : (AddWasmInput, opt blob) -> (Result_11); -validate2_admin_batch_call_buckets : (vec principal, text, opt blob) -> ( - Result_11, - ); -validate2_admin_deploy_bucket : (DeployWasmInput, opt blob) -> (Result_11); -validate2_admin_set_managers : (vec principal) -> (Result_11); -validate2_admin_upgrade_all_buckets : (opt blob) -> (Result_11); -validate_admin_add_committers : (vec principal) -> (Result_11); -validate_admin_add_managers : (vec principal) -> (Result_11); -validate_admin_add_wasm : (AddWasmInput, opt blob) -> (Result_1); -validate_admin_batch_call_buckets : (vec principal, text, opt blob) -> ( - Result_2, - ); -validate_admin_create_bucket : (opt CanisterSettings, opt blob) -> ( - Result_11, - ); -validate_admin_deploy_bucket : (DeployWasmInput, opt blob) -> (Result_1); -validate_admin_remove_committers : (vec principal) -> (Result_11); -validate_admin_remove_managers : (vec principal) -> (Result_11); -validate_admin_set_managers : (vec principal) -> (Result_1); -validate_admin_update_bucket_canister_settings : (UpdateSettingsArgument) -> ( - Result_11, - ); -validate_admin_upgrade_all_buckets : (opt blob) -> (Result_1); -``` +Try it online: https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=x5573-nqaaa-aaaap-ahopq-cai -The complete Candid API definition can be found in the [ic_oss_cluster.did](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_bucket/ic_oss_cluster.did) file. +## Quick Start -## Running locally +### Deploy Locally -Deploy to local network: ```bash +# Deploy the cluster # dfx canister create --specified-id x5573-nqaaa-aaaap-ahopq-cai ic_oss_cluster dfx deploy ic_oss_cluster --argument "(opt variant {Init = record { @@ -87,60 +30,75 @@ dfx deploy ic_oss_cluster --argument "(opt variant {Init = } })" +# Get cluster info dfx canister call ic_oss_cluster get_cluster_info '()' +``` +### Common Operations + +```bash +# Add managers MYID=$(dfx identity get-principal) -ic-oss-cli -i debug/uploader.pem identity -# principal: nprym-ylvyz-ig3fr-lgcmn-zzzt4-tyuix-3v6bm-fsel7-6lq6x-zh2w7-zqe +dfx canister call ic_oss_cluster admin_add_managers "(vec {principal \"$MYID\"})" -# add managers -dfx canister call ic_oss_cluster admin_set_managers "(vec {principal \"$MYID\"; principal \"nprym-ylvyz-ig3fr-lgcmn-zzzt4-tyuix-3v6bm-fsel7-6lq6x-zh2w7-zqe\"})" +# Add a wasm file to the cluster: +ic-oss-cli -i debug/uploader.pem cluster-add-wasm -c x5573-nqaaa-aaaap-ahopq-cai --path debug/ic_oss_bucket.wasm.gz --description "ic_oss_bucket v0.9.8" -# add managers -dfx canister call ic_oss_cluster admin_set_managers "(vec {principal \"$MYID\"})" +# create a bucket with default settings +dfx canister call ic_oss_cluster admin_create_bucket '(null, null)' +# (variant { Ok = principal "ctiya-peaaa-aaaaa-qaaja-cai" }) -# sign a access token -dfx canister call ic_oss_cluster admin_sign_access_token '(record { - subject = principal "z7wjp-v6fe3-kksu5-26f64-dedtw-j7ndj-57onx-qga6c-et5e3-njx53-tae"; - audience = principal "mmrxu-fqaaa-aaaap-ahhna-cai"; +# Get bucket status +dfx canister call ic_oss_cluster get_canister_status '(opt principal "YOUR_BUCKET_ID")' +``` + +### Access Control Examples + +```bash +# Sign access token +dfx canister call ic_oss_cluster admin_ed25519_access_token '(record { + subject = principal "USER_ID"; + audience = principal "YOUR_BUCKET_ID"; scope = "Folder.*:1 Bucket.Read.*"; })' -# attach policies +# Attach policies dfx canister call ic_oss_cluster admin_attach_policies '(record { - subject = principal "z7wjp-v6fe3-kksu5-26f64-dedtw-j7ndj-57onx-qga6c-et5e3-njx53-tae"; - audience = principal "mmrxu-fqaaa-aaaap-ahhna-cai"; - scope = "Folder.* Bucket.List.*"; + subject = principal "USER_ID"; + audience = principal "YOUR_BUCKET_ID"; + scope = "Folder.* Bucket.List.*"; })' +``` -# detach policies -dfx canister call ic_oss_cluster admin_detach_policies '(record { - subject = principal "z7wjp-v6fe3-kksu5-26f64-dedtw-j7ndj-57onx-qga6c-et5e3-njx53-tae"; - audience = principal "mmrxu-fqaaa-aaaap-ahhna-cai"; - scope = "Folder.*:1"; -})' - -# get access token for a audience -dfx canister call ic_oss_cluster access_token '(principal "mmrxu-fqaaa-aaaap-ahhna-cai")' - - -# Add a wasm file to the cluster: -ic-oss-cli -i debug/uploader.pem cluster-add-wasm -c x5573-nqaaa-aaaap-ahopq-cai --path debug/ic_oss_bucket.wasm.gz --description "ic_oss_bucket v0.9.8" - -# get wasm file -shasum -a 256 debug/ic_oss_bucket.wasm.gz -dfx canister call ic_oss_cluster get_bucket_wasm '(blob "\2d\f4\25\d7\ed\ea\ba\3c\27\39\f0\f5\66\73\90\66\69\5c\f1\8c\53\fd\38\cf\9b\ef\cb\14\e9\f6\22\57")' - -# create a bucket with default settings -dfx canister call ic_oss_cluster admin_create_bucket '(null, null)' -# (variant { Ok = principal "ctiya-peaaa-aaaaa-qaaja-cai" }) - -# get canister status -dfx canister call ic_oss_cluster get_canister_status '(null)' -dfx canister call ic_oss_cluster get_canister_status '(opt principal "ctiya-peaaa-aaaaa-qaaja-cai")' +## API Reference + +The canister exposes a comprehensive Candid API. Key endpoints include: + +```candid +# Permissions Operations +admin_attach_policies : (Token) -> (Result_1) +get_subject_policies : (principal) -> (Result_10) query +admin_ed25519_access_token : (Token) -> (Result) +admin_weak_access_token : (Token, nat64, nat64) -> (Result) query +access_token : (principal) -> (Result) + +# Buckets Operations +admin_add_wasm : (AddWasmInput, opt blob) -> (Result_1) +admin_create_bucket : (opt CanisterSettings, opt blob) -> (Result_3) +admin_deploy_bucket : (DeployWasmInput, opt blob) -> (Result_1) +admin_upgrade_all_buckets : (opt blob) -> (Result_1) +admin_topup_all_buckets : () -> (Result_4) +bucket_deployment_logs : (opt nat, opt nat) -> (Result_5) query + +# Admin Operations +admin_add_managers : (vec principal) -> (Result_1) +admin_add_committers : (vec principal) -> (Result_1) ``` +Full Candid API definition: [ic_oss_bucket.did](https://github.com/ldclabs/ic-oss/tree/main/src/ic_oss_cluster/ic_oss_cluster.did) + ## License + Copyright © 2024-2025 [LDC Labs](https://github.com/ldclabs). -`ldclabs/ic-oss` is licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for the full license text. \ No newline at end of file +Licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for details. \ No newline at end of file diff --git a/src/ic_oss_ts/README.md b/src/ic_oss_ts/README.md index 8363db4..2cae698 100644 --- a/src/ic_oss_ts/README.md +++ b/src/ic_oss_ts/README.md @@ -8,6 +8,7 @@ `@ldclabs/ic_oss_ts` is the Typescript version of the client SDK for the ic-oss cluster. ## License + Copyright © 2024-2025 [LDC Labs](https://github.com/ldclabs). -`ldclabs/ic-oss` is licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for the full license text. \ No newline at end of file +Licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for details. \ No newline at end of file diff --git a/src/ic_oss_types/README.md b/src/ic_oss_types/README.md index 3265504..697c580 100644 --- a/src/ic_oss_types/README.md +++ b/src/ic_oss_types/README.md @@ -10,6 +10,7 @@ `ic-oss-type` is a Rust types library used for integrating with [ic-oss](https://github.com/ldclabs/ic-oss) cluster. ## License + Copyright © 2024-2025 [LDC Labs](https://github.com/ldclabs). -`ldclabs/ic-oss` is licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for the full license text. \ No newline at end of file +Licensed under the MIT License. See [LICENSE](../../LICENSE-MIT) for details. \ No newline at end of file