UNPKG

@dfinity/vetkeys

Version:

JavaScript and TypeScript library to use Internet Computer vetKeys

493 lines (492 loc) 19.9 kB
import { Principal } from '@dfinity/principal'; import { DerivedKeyMaterial } from '../utils/utils'; import { AccessRights, ByteBuf } from '../declarations/ic_vetkeys_manager_canister/ic_vetkeys_manager_canister.did'; export { DefaultEncryptedMapsClient } from './encrypted_maps_canister'; export type { AccessRights, ByteBuf, } from '../declarations/ic_vetkeys_manager_canister/ic_vetkeys_manager_canister.did'; /** * The **EncryptedMaps** frontend library facilitates interaction with an [**EncryptedMaps-enabled canister**](https://docs.rs/ic-vetkeys/latest/ic_vetkeys/encrypted_maps/struct.EncryptedMaps.html) on the **Internet Computer (ICP)**. * It allows web applications to securely store, retrieve, and manage encrypted key-value pairs within named maps while handling user access control and key sharing. * * ## Core Features * * - **Encrypted Key-Value Storage**: Store and retrieve encrypted key-value pairs within named maps. * - **Retrieve Encrypted VetKeys**: Fetch encrypted VetKeys and decrypt them locally using a **transport secret key**. * - **Shared Maps Access Information**: Query which maps a user has access to. * - **Manage User Access**: Assign, modify, and revoke user rights on stored maps. * - **Retrieve VetKey Verification Key**: Fetch the public verification key for validating VetKeys. * * ## Security Considerations * * - **Access Rights** should be carefully managed to prevent unauthorized access. * - VetKeys should be decrypted **only in trusted environments** such as user browsers to prevent leaks. * * @example * ```ts * import { EncryptedMaps } from "@dfinity/vetkeys/encrypted_maps"; * * // Initialize the EncryptedMaps Client * const encryptedMaps = new EncryptedMaps(encryptedMapsClientInstance); * * // Retrieve shared maps * const sharedMaps = await encryptedMaps.getAccessibleSharedMapNames(); * * const mapOwner = Principal.fromText("aaaaa-aa"); * const mapName = "passwords"; * const mapKey = "email_account"; * * // Store an encrypted value * const value = new TextEncoder().encode("my_secure_password"); * const result = await encryptedMaps.setValue(mapOwner, mapName, mapKey, value); * * // Retrieve a stored value * const storedValue = await encryptedMaps.getValue(mapOwner, mapName, mapKey); * * // Manage user access rights * const user = Principal.fromText("bbbbbb-bb"); * const accessRights = { ReadWrite: null }; * const result = await encryptedMaps.setUserRights(mapOwner, mapName, user, accessRights); * ``` */ export declare class EncryptedMaps { /** * The client instance for interacting with the EncryptedMaps canister. */ canisterClient: EncryptedMapsClient; /** * The cached verification key for validating encrypted VetKeys. */ verificationKey: Uint8Array | undefined; /** * Creates a new instance of the EncryptedMaps client. * * @example * ```ts * import { EncryptedMaps } from "@dfinity/vetkeys/encrypted_maps"; * * const encryptedMaps = new EncryptedMaps(encryptedMapsClientInstance); * ``` */ constructor(canisterClient: EncryptedMapsClient); /** * Retrieves a list of maps that were shared with the user and the user still has access to. * * @example * ```ts * const sharedMaps = await encryptedMaps.getAccessibleSharedMapNames(); * console.log("Shared Maps:", sharedMaps); * ``` * * @returns Promise resolving to an array of `[Principal, Uint8Array]` pairs representing accessible map identifiers. */ getAccessibleSharedMapNames(): Promise<[Principal, Uint8Array][]>; /** * Retrieves a list of non-empty maps owned by the caller. * * @returns Promise resolving to an array of map names */ getOwnedNonEmptyMapNames(): Promise<Array<Uint8Array>>; /** * Retrieves all accessible values across all maps the user has access to. * * @returns Promise resolving to an array of map data with decrypted values */ getAllAccessibleValues(): Promise<Array<[[Principal, Uint8Array], Array<[Uint8Array, Uint8Array]>]>>; /** * Retrieves all accessible maps with their decrypted values. * * @returns Promise resolving to an array of map data */ getAllAccessibleMaps(): Promise<Array<MapData>>; /** * Retrieves and decrypts a stored value from a map. * * @example * ```ts * const mapOwner = Principal.fromText("aaaaa-aa"); * const mapName = "passwords"; * const mapKey = "email_account"; * * const storedValue = await encryptedMaps.getValue(mapOwner, mapName, mapKey); * console.log("Decrypted Value:", new TextDecoder().decode(storedValue)); * ``` * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @param mapKey - The key to retrieve * @returns Promise resolving to the decrypted value * @throws Error if the operation fails */ getValue(mapOwner: Principal, mapName: Uint8Array, mapKey: Uint8Array): Promise<Uint8Array>; /** * Retrieves all values from a specific map. * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @returns Promise resolving to an array of key-value pairs * @throws Error if the operation fails */ getValuesForMap(mapOwner: Principal, mapName: Uint8Array): Promise<Array<[Uint8Array, Uint8Array]>>; /** * Stores an encrypted value in a map. * * @example * ```ts * const value = new TextEncoder().encode("my_secure_password"); * const result = await encryptedMaps.setValue(mapOwner, mapName, mapKey, value); * console.log("Replaced Value:", result); * ``` * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @param mapKey - The key to store * @param data - The value to store * @returns Promise resolving to the previous value if it existed * @throws Error if the operation fails */ setValue(mapOwner: Principal, mapName: Uint8Array, mapKey: Uint8Array, data: Uint8Array): Promise<Uint8Array | undefined>; /** * Removes a value from a map. * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @param mapKey - The key to remove * @returns Promise resolving to the removed value if it existed * @throws Error if the operation fails */ removeEncryptedValue(mapOwner: Principal, mapName: Uint8Array, mapKey: Uint8Array): Promise<Uint8Array | undefined>; /** * Removes all values from a map. * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @returns Promise resolving to an array of removed keys * @throws Error if the operation fails */ removeMapValues(mapOwner: Principal, mapName: Uint8Array): Promise<Array<Uint8Array>>; /** * Retrieves the public verification key for validating encrypted VetKeys. * The vetkeys obtained via `getVetkey` are verified using this key, * and, therefore, this method is not needed for using `getVetkey`. * * @example * ```ts * const verificationKey = await encryptedMaps.getVetkeyVerificationKey(); * console.log("Verification Key:", verificationKey); * ``` * * @returns Promise resolving to the verification key bytes */ getVetkeyVerificationKey(): Promise<Uint8Array>; /** * Grants or modifies access rights for a user. * * @example * ```ts * const owner = Principal.fromText("aaaaa-aa"); * const user = Principal.fromText("bbbbbb-bb"); * const accessRights = { ReadWrite: null }; * * const result = await encryptedMaps.setUserRights( * owner, * mapName, * user, * accessRights, * ); * console.log("Access Rights Updated:", result); * ``` * * @param owner - The principal of the map owner * @param mapName - The name/identifier of the map * @param user - The principal of the user to grant/modify rights for * @param userRights - The access rights to grant * @returns Promise resolving to the previous access rights if they existed * @throws Error if the operation fails */ setUserRights(owner: Principal, mapName: Uint8Array, user: Principal, userRights: AccessRights): Promise<AccessRights | undefined>; /** * Checks a user's access rights. * * @example * ```ts * const userRights = await encryptedMaps.get_user_rights(owner, mapName, user); * console.log("User Access Rights:", userRights); * ``` * * @param owner - The principal of the map owner * @param mapName - The name/identifier of the map * @param user - The principal of the user to check rights for * @returns Promise resolving to the user's access rights if they exist * @throws Error if the operation fails */ getUserRights(owner: Principal, mapName: Uint8Array, user: Principal): Promise<AccessRights | undefined>; /** * Gets all users that have access to a map and their access rights. * * @param owner - The principal of the map owner * @param mapName - The name/identifier of the map * @returns Promise resolving to an array of user-access rights pairs * @throws Error if the operation fails */ getSharedUserAccessForMap(owner: Principal, mapName: Uint8Array): Promise<Array<[Principal, AccessRights]>>; /** * Revokes a user's access. * * @example * ```ts * const removalResult = await encryptedMaps.remove_user(owner, mapName, user); * console.log("User Removed:", removalResult); * ``` * * @param owner - The principal of the map owner * @param mapName - The name/identifier of the map * @param user - The principal of the user to remove * @returns Promise resolving to the previous access rights if they existed * @throws Error if the operation fails */ removeUser(owner: Principal, mapName: Uint8Array, user: Principal): Promise<AccessRights | undefined>; /** * Derives a key material for a specific map. * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @returns Promise resolving to the derived key material * @throws Error if the operation fails */ getDerivedKeyMaterial(mapOwner: Principal, mapName: Uint8Array): Promise<DerivedKeyMaterial>; /** * Encrypts a value for a specific map and key. * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @param mapKey - The key to encrypt for * @param cleartext - The value to encrypt * @returns Promise resolving to the encrypted value */ encryptFor(mapOwner: Principal, mapName: Uint8Array, mapKey: Uint8Array, cleartext: Uint8Array): Promise<Uint8Array>; /** * Decrypts a value for a specific map and key. * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @param mapKey - The key to decrypt for * @param encryptedValue - The value to decrypt * @returns Promise resolving to the decrypted value */ decryptFor(mapOwner: Principal, mapName: Uint8Array, mapKey: Uint8Array, encryptedValue: Uint8Array): Promise<Uint8Array>; /** * Gets or fetches the derived key material for a map. * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @returns Promise resolving to the derived key material */ getDerivedKeyMaterialOrFetchIfNeeded(mapOwner: Principal, mapName: Uint8Array): Promise<DerivedKeyMaterial>; } /** * Interface for map data structure. */ export interface MapData { accessControl: Array<[Principal, AccessRights]>; keyvals: Array<[Uint8Array, Uint8Array]>; mapName: Uint8Array; mapOwner: Principal; } /** * An interface that maps `EncryptedMaps` calls to IC canister calls that will call the respective method of the backend `EncryptedMaps`. * For example, `get_user_rights` will call the `get_user_rights` method of the backend `EncryptedMaps`. */ export interface EncryptedMapsClient { /** * Retrieves a list of maps that were shared with the user and the user still has access to. * * @returns Promise resolving to an array of `[Principal, ByteBuf]` pairs representing accessible map identifiers. */ get_accessible_shared_map_names(): Promise<[Principal, ByteBuf][]>; /** * Gets all users that have access to a map and their access rights. * * @param owner - The principal of the map owner * @param mapName - The name/identifier of the map * @returns Promise resolving to an array of user-access rights pairs, or an error if the operation fails */ get_shared_user_access_for_map(owner: Principal, mapName: ByteBuf): Promise<{ Ok: Array<[Principal, AccessRights]>; } | { Err: string; }>; /** * Retrieves a list of non-empty maps owned by the caller. * * @returns Promise resolving to an array of map names */ get_owned_non_empty_map_names(): Promise<Array<ByteBuf>>; /** * Retrieves all accessible values across all maps the user has access to. * * @returns Promise resolving to an array of map data with encrypted values */ get_all_accessible_encrypted_values(): Promise<[ [Principal, ByteBuf], [ByteBuf, ByteBuf][] ][]>; /** * Retrieves all accessible maps with their encrypted values. * * @returns Promise resolving to an array of encrypted map data */ get_all_accessible_encrypted_maps(): Promise<Array<EncryptedMapData>>; /** * Retrieves an encrypted value from a map. * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @param mapKey - The key to retrieve * @returns Promise resolving to the encrypted value if it exists, or an error if the operation fails */ get_encrypted_value(mapOwner: Principal, mapName: ByteBuf, mapKey: ByteBuf): Promise<{ Ok: [] | [ByteBuf]; } | { Err: string; }>; /** * Retrieves all encrypted values from a specific map. * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @returns Promise resolving to an array of key-value pairs, or an error if the operation fails */ get_encrypted_values_for_map(mapOwner: Principal, mapName: ByteBuf): Promise<{ Ok: Array<[ByteBuf, ByteBuf]>; } | { Err: string; }>; /** * Stores an encrypted value in a map. * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @param mapKey - The key to store * @param data - The encrypted value to store * @returns Promise resolving to the previous value if it existed, or an error if the operation fails */ insert_encrypted_value(mapOwner: Principal, mapName: ByteBuf, mapKey: ByteBuf, data: ByteBuf): Promise<{ Ok: [] | [ByteBuf]; } | { Err: string; }>; /** * Removes a value from a map. * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @param mapKey - The key to remove * @returns Promise resolving to the removed value if it existed, or an error if the operation fails */ remove_encrypted_value(mapOwner: Principal, mapName: ByteBuf, mapKey: ByteBuf): Promise<{ Ok: [] | [ByteBuf]; } | { Err: string; }>; /** * Removes all values from a map. * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @returns Promise resolving to an array of removed keys, or an error if the operation fails */ remove_map_values(mapOwner: Principal, mapName: ByteBuf): Promise<{ Ok: Array<ByteBuf>; } | { Err: string; }>; /** * Grants or modifies access rights for a user. * * @param owner - The principal of the map owner * @param mapName - The name/identifier of the map * @param user - The principal of the user to grant/modify rights for * @param userRights - The access rights to grant * @returns Promise resolving to the previous access rights if they existed, or an error if the operation fails */ set_user_rights(owner: Principal, mapName: ByteBuf, user: Principal, userRights: AccessRights): Promise<{ Ok: [] | [AccessRights]; } | { Err: string; }>; /** * Checks a user's access rights. * * @param owner - The principal of the map owner * @param mapName - The name/identifier of the map * @param user - The principal of the user to check rights for * @returns Promise resolving to the user's access rights if they exist, or an error if the operation fails */ get_user_rights(owner: Principal, mapName: ByteBuf, user: Principal): Promise<{ Ok: [] | [AccessRights]; } | { Err: string; }>; /** * Revokes a user's access. * * @param owner - The principal of the map owner * @param mapName - The name/identifier of the map * @param user - The principal of the user to remove * @returns Promise resolving to the previous access rights if they existed, or an error if the operation fails */ remove_user(owner: Principal, mapName: ByteBuf, user: Principal): Promise<{ Ok: [] | [AccessRights]; } | { Err: string; }>; /** * Fetches an encrypted VetKey. * * @param mapOwner - The principal of the map owner * @param mapName - The name/identifier of the map * @param transportKey - The public transport key to use for encryption * @returns Promise resolving to the encrypted VetKey bytes, or an error if the operation fails */ get_encrypted_vetkey(mapOwner: Principal, mapName: ByteBuf, transportKey: ByteBuf): Promise<{ Ok: ByteBuf; } | { Err: string; }>; /** * Retrieves the public verification key for validating encrypted VetKeys. * * @returns Promise resolving to the verification key bytes */ get_vetkey_verification_key(): Promise<ByteBuf>; } /** * This interface represents the structure of an encrypted map as stored in the backend canister. * It contains all the necessary information about a map, including its access control settings, * encrypted key-value pairs, and metadata. */ export interface EncryptedMapData { /** * Access control list for the map (excluding the map owner), specifying which users have what level of access. * Each entry is a tuple of [Principal, AccessRights] where: * - Principal: The user's identity * - AccessRights: The level of access granted (Read, ReadWrite, or ReadWriteManage) */ access_control: Array<[Principal, AccessRights]>; /** * The encrypted key-value pairs stored in the map. * Each entry is a tuple of [ByteBuf, ByteBuf] where: * - First ByteBuf: The encrypted key * - Second ByteBuf: The encrypted value */ keyvals: Array<[ByteBuf, ByteBuf]>; /** * The name/identifier of the map. * This is used to uniquely identify the map within the system. */ map_name: ByteBuf; /** * The principal of the map owner. * This identifies who created and owns the map. */ map_owner: Principal; }