@dfinity/vetkeys
Version:
JavaScript and TypeScript library to use Internet Computer vetKeys
493 lines (492 loc) • 19.9 kB
TypeScript
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;
}