Welcome to the Time Storage Backend! This project provides a highly secure and scalable way to manage and store key-value pairs associated with unique identifiers (UUIDs). It also includes support for file uploads and value locking mechanisms to ensure data integrity. Letβs dive into how to set up, use, and interact with the canisters!
Canister | URL |
---|---|
timestorage_admin | https://ru4eh-syaaa-aaaah-qp5hq-cai.icp0.io/ |
timestorage_frontend | https://rt5ct-7aaaa-aaaah-qp5ha-cai.icp0.io/ |
Canister | URL |
---|---|
internet-identity | https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=rdmx6-jaaaa-aaaaa-aaadq-cai |
test_runner | https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=snmf5-yqaaa-aaaah-qp5oa-cai |
timestorage_backend | https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=r26jp-jiaaa-aaaah-qp5gq-cai |
Hereβs a breakdown of the most important files:
dfx start --background
dfx deploy timestorage_backend
Here is a detailed list of the canister βendpointsβ available in the Time Storage Backend. Each endpoint is explained with its parameters, usage examples, and expected responses.
Description: Checks if the caller is an admin.
Endpoint:
public shared query (msg) func isAdmin() : async Bool
Example Command:
dfx canister call timestorage_backend isAdmin
Response:
true
false
Description: Checks if the caller is an editor.
Endpoint:
public shared query (msg) func isEditor() : async Bool
Example Command:
dfx canister call timestorage_backend isEditor
Response:
true
false
β οΈ Admin role required to execute this function
Description: Adds a new admin to the system.
Endpoint:
public shared (msg) func addAdmin(newAdmin: Principal) : async Result.Result<Text, Text>
Parameters:
newAdmin
(Principal): The principal ID of the new admin.Example Command:
dfx canister call timestorage_backend addAdmin '(principal "[principal_id]")'
Response:
(variant { ok = "New admin added successfully." })
(variant { err = "Unauthorized: Only admins can add new admins." })
(variant { err = "Admin already exist." })
β οΈ Admin role required to execute this function
Description: Adds a new editor to the system.
Endpoint:
public shared (msg) func addEditor(newEditor : Principal) : async Result.Result<Text, Text>
Parameters:
newEditor
(Principal): The principal ID of the new editor.Example Command:
dfx canister call timestorage_backend addEditor '(principal "[principal_id]")'
Response:
(variant { ok = "New editor added successfully." })
(variant { err = "Unauthorized: Only admins can add new editors." })
(variant { err = "Editor already exist." })
β οΈ Admin role required to execute this function
Description: Remove an admin from the system.
Endpoint:
public shared (msg) func removeAdmin(adminToRemove: Principal) : async Result.Result<Text, Text>
Parameters:
adminToRemove
(Principal): The principal ID of the admin.Example Command:
dfx canister call timestorage_backend removeAdmin '(principal "[principal_id]")'
Response:
(variant { ok = "Admin removed successfully." })
(variant { err = "Unauthorized: Only admins can add remove admins." })
(variant { err = "Admin does not exist." })
β οΈ Admin role required to execute this function
Description: Remove an editor from the system.
Endpoint:
public shared (msg) func removeEditor(editorToRemove : Principal) : async Result.Result<Text, Text>
Parameters:
editorToRemove
(Principal): The principal ID of the editor.Example Command:
dfx canister call timestorage_backend editorToRemove '(principal "[principal_id]")'
Response:
(variant { ok = "Editor removed successfully." })
(variant { err = "Unauthorized: Only admins can add remove editors." })
(variant { err = "Editor does not exist." })
Operation | Admin | Editor | Public |
---|---|---|---|
Add/Remove Admin | β | β | β |
Manage UUIDs | β | β | β |
View All UUIDs | β | β | β |
Manage Own UUIDs | β | β | β |
Lock Values | β | β | β |
Unlock Values | β | β | β |
β οΈ Admin role required to execute this function
π οΈβ Editor role required to execute this function
Description: Inserts a new structure for a given UUID and memorize the register owner.
Endpoint:
public shared (msg) func insertUUIDStructure(uuid: Text, schema: Text) : async Result.Result<Text, Text>
Parameters:
uuid
(Text): The unique identifier to associate with the structure.schema
(Text): The structure in JSON format.Example Command:
dfx canister call timestorage_backend insertUUIDStructure '("uuid-dummy", "{\"name\": \"value\"}")'
Response:
(variant { ok = "UUID inserted successfully." })
(variant { err = "Invalid UUID format." })
Description: Uploads a file and associates it with a given UUID.
Endpoint:
public shared (msg) func uploadFile(uuid: Text, base64FileData: Text, metadata: Types.FileMetadata) : async Result.Result<Text, Text>
Parameters:
uuid
(Text): The UUID to associate the file with.base64FileData
(Text): The file data in Base64 format.metadata
(Types.FileMetadata): Metadata about the file (e.g., name, type).Example Command:
dfx canister call timestorage_backend uploadFile '("uuid-dummy", "<base64_data>", record { fileName = "example.txt"; mimeType = "text/plain"; uploadTimestamp = 1234567890 })'
Response:
(variant { ok = "File uploaded successfully with ID: file-{NUMBER_GENERATED}" })
(variant { err = "Error: UUID does not exist." })
Description: Retrieves a file associated with a UUID and a file ID.
Endpoint:
public shared query (msg) func getFileByUUIDAndId(uuid: Text, fileId: Text) : async Types.Result<Types.FileResponse, Text>
Parameters:
uuid
(Text): The UUID of the file.fileId
(Text): The unique file ID.Example Command:
dfx canister call timestorage_backend getFileByUUIDAndId '("uuid-dummy", "file-1")'
Response:
(
variant {
ok = record {
metadata = record {
fileData = "<base64_data>";
mimeType = "text/plain";
fileName = "example.txt";
uploadTimestamp = "1234567890";
};
uuid = "uuid-dummy";
}
},
)
(variant { err = "File not found." })
Description: Updates a specific value associated with a UUID.
Endpoint:
public shared (msg) func updateValue(req: Types.ValueUpdateRequest) : async Result.Result<Text, Text>
Parameters:
req
(Types.ValueUpdateRequest): The request containing the UUID, key, and new value.Example Command:
dfx canister call timestorage_backend updateValue '(record { uuid = "uuid-dummy"; key = "exampleKey"; newValue = "newValue" })'
Response:
(variant { ok = "Value updated successfully." })
(variant { err = "UUID not found or not initialized." })
Description: Updates multiple key-value pairs for a given UUID.
Endpoint:
public shared (msg) func updateManyValues(uuid: Text, updates: [(Text, Text)]) : async Result.Result<Text, [Text]>
Parameters:
uuid
(Text): The UUID to update.updates
([(Text, Text)]): A list of key-value pairs to update.Example Command:
dfx canister call timestorage_backend updateManyValues '("uuid-dummy", vec { record { "exampleKey"; "new-value1" }; record { "key2"; "new-value2" }; record { "key3"; "value3" } })'
Response:
(variant { ok = "All values updated successfully." })
(variant { err = ["UUID not found", "Key not found"] })
(variant { ok = "Some keys could not be updated: key2, key3" })
Description: Locks a specific value for a UUID.
Endpoint:
public shared (msg) func lockValue(req: Types.ValueLockRequest) : async Result.Result<Text, Text>
Parameters:
req
(Types.ValueLockRequest): The request containing the UUID, key, and lock status.Example Command:
dfx canister call timestorage_backend lockValue '(record { uuid = "uuid-dummy"; key = "exampleKey"; lock = true })'
Response:
(variant { ok = "Value locked successfully." })
(variant { err = "Value is already locked." })
(variant { err = "UUID not found." })
β οΈ Admin role required to execute this function
Description: Unlocks a specific value for a UUID.
Endpoint:
public shared (msg) func unlockValue(req: Types.ValueUnlockRequest) : async Result.Result<Text, Text>
Parameters:
req
(Types.ValueUnlockRequest): The request containing the UUID, key.Example Command:
dfx canister call timestorage_backend unlockValue '(record { uuid = "uuid-dummy"; key = "exampleKey"})'
Response:
(variant { ok = "Value unlocked successfully." })
(variant { err = "Value is already unlocked." })
(variant { err = "Value lock status not found." })
(variant { err = "UUID not found." })
Description: Locks all values for a given UUID.
Endpoint:
public shared (msg) func lockAllValues(req: Types.ValueLockAllRequest) : async Result.Result<Text, Text>
Parameters:
req
(Types.ValueLockAllRequest): The request containing the UUID and lock status.Example Command:
dfx canister call timestorage_backend lockAllValues '(record { uuid = "uuid-dummy"; lock = true })'
Response:
(variant { ok = "All values locked successfully." })
(variant { err = "UUID not found." })
β οΈ Admin role required to execute this function
Description: Unlocks all values for a given UUID.
Endpoint:
public shared (msg) func unlockAllValues(req : Types.ValueUnlockAllRequest) : async Result.Result<Text, Text>
Parameters:
req
(Types.ValueUnlockAllRequest): The request containing the UUID.Example Command:
dfx canister call timestorage_backend unlockAllValues '(record { uuid = "uuid-dummy" })'
Response:
(variant { ok = "All values unlocked successfully." })
(variant { err = "UUID not found." })
Description: Retrieves a specific value associated with a UUID.
Endpoint:
public shared query (msg) func getValue(req: Types.ValueRequest) : async Result.Result<Text, Text>
Parameters:
req
(Types.ValueRequest): The request containing the UUID and key.Example Command:
dfx canister call timestorage_backend getValue '(record { uuid = "uuid-dummy"; key = "exampleKey" })'
Response:
(variant { ok = "new-value1" })
(variant { err = "UUID not found." })
(variant { err = "Key not found." })
Description: Retrieves all key-value pairs associated with a UUID.
Endpoint:
public shared query (msg) func getAllValues(uuid: Text) : async Result.Result<[(Text, Text)], Text>
Parameters:
uuid
(Text): The UUID to retrieve values for.Example Command:
dfx canister call timestorage_backend getAllValues '("uuid-dummy")'
Response:
(variant { ok = vec { record { "exampleKey"; "new-value1" } } })
(variant { err = "UUID not found." })
Description: Retrieves the lock status of a specific value.
Endpoint:
public shared query (msg) func getValueLockStatus(req: Types.ValueLockStatusRequest) : async Result.Result<Types.ValueLockStatus, Text>
Parameters:
req
(Types.ValueLockStatusRequest): The request containing the UUID and key.Example Command:
dfx canister call timestorage_backend getValueLockStatus '(record { uuid = "uuid-dummy"; key = "exampleKey" })'
Response:
(variant { ok = record { locked = true; lockedBy = ?principal "[principal_id]" } })
(variant { err = "No lock status found (value not locked)." })
β οΈ Admin role required to execute this function
π οΈβ Editor role required to execute this function
Descrizione: Retrieves all UUIDs minted or UUIDs owned by a specific principal if specified.
Endpoint:
public shared query (msg) func getAllUUIDs(ownerPrincipal : ?Principal) : async Result.Result<[Text], Text>
Parameters:
ownerPrincipal
(optional): Principal ID to filter UUIDs by ownerAccess Control:
Example Commands:
# Get all UUIDs (admin only)
dfx canister call timestorage_backend getAllUUIDs
# Get UUIDs for specific principal
dfx canister call timestorage_backend getAllUUIDs '(opt principal [principal_id])'
Responses:
(variant { ok = vec { "uuid-123"; "uuid-456"; } })
(variant { err = "Unauthorized: Admin or Editor role required." })
(variant { err = "Unauthorized: Can only query your own UUIDs" })
Description: Retrieves all information associated with a UUID.
Endpoint:
public shared query (msg) func getUUIDInfo(uuid: Text) : async Result.Result<(Text, [Types.FileResponse]), Text>
Parameters:
uuid
(Text): The UUID to retrieve information for.Example Command:
dfx canister call timestorage_backend getUUIDInfo '("uuid-dummy")'
Response:
(
variant {
ok = record {
"{\"name\": \"value\"},\"values\":{\"exampleKey\":\"new-value1\"},\"lockStatus\":{\"exampleKey\":\"unlocked\"}}";
vec {
record {
metadata = record {
fileData = "<base64_data>";
mimeType = "text/plain";
fileName = "example.txt";
uploadTimestamp = "1234567890";
};
uuid = "uuid-dummy";
};
};
}
},
)
(variant { err = "UUID not found." })