UNPKG

hollowdb

Version:

A decentralized privacy-preserving key-value database

292 lines (290 loc) 11 kB
import { Warp, Contract, ArWallet, CustomSignature, SortKeyCacheResult } from "warp-contracts"; import { SortKeyCacheRangeOptions } from "warp-contracts/lib/types/cache/SortKeyCacheRangeOptions"; /** * A type-utility to convert an array of `T`s into a mapped type, * that can be used for example as a mapping key type. * * If the array is empty, defaults to `T`. */ type OpitonalArray<A extends T[], T> = A extends [] ? T : A[number]; /** * A type to describe whitelists and proofs (circuits) used within a contract. */ type ContractMode = { whitelists: string[]; proofs: string[]; }; /** * A generic contract input. */ type ContractInputGeneric = { function: string; value: any; }; /** * A contract state. For example, HollowDB state is defined as: * * ```ts * ContractState<{circuits: ['auth']; whitelists: ['put', 'update']}> * ``` * * because we have an `auth` circuit, and we have two whitelists names `put` and `update`. * * @template M a type where whitelists and circuit names are specified. If none, pass in empty array `[]` to each. */ type ContractState<M extends ContractMode = ContractMode> = { version: string; canEvolve: boolean; evolve?: string; owner: string; isProofRequired: { [name in OpitonalArray<M['proofs'], string>]: boolean; }; verificationKeys: { [name in OpitonalArray<M['proofs'], string>]: any; }; whitelists: { [name in OpitonalArray<M['whitelists'], string>]: { [address: string]: boolean; }; }; isWhitelistRequired: { [name in OpitonalArray<M['whitelists'], string>]: boolean; }; }; declare class Base<M extends ContractMode> { readonly contract: Contract<ContractState<M>>; readonly warp: Warp; readonly signer: ArWallet | CustomSignature; constructor(signer: ArWallet | CustomSignature, contractTxId: string, warp: Warp); /** * Return the latest contract state. * * This is a good way to trigger Warp to fetch the latest data from Arweave. * Note that if the contract has many transactions, fetching up to the latest * state may take some time. * * @returns contract state along with corresponding sort key */ readState(): Promise<import("warp-contracts").SortKeyCacheResult<import("warp-contracts").EvalStateResult<ContractState<M>>>>; /** * A typed wrapper around `dryWrite`, which evaluates a given input * on the local state, without creating a transaction. This may provide * better UX for some use-cases. * @param input input in the form of `{function, value}` * @returns interaction result */ dryWrite<I extends ContractInputGeneric>(input: I): Promise<import("warp-contracts").InteractionResult<ContractState<M>, unknown>>; /** * A typed wrapper around `writeInteraction`, which creates a * transaction. You are likely to use this after `dryWrite`, or you * may directly call this function. * @param input input in the form of `{function, value}` * @returns interaction response */ writeInteraction<I extends ContractInputGeneric>(input: I): Promise<import("warp-contracts").WriteInteractionResponse | null>; /** * A typed wrapper around `dryWrite` followed by `writeInteraction`. This * function first executes the interaction locally via `dryWrite`, and if * there is an error, throws an error with an optional prefix in the message. * @param input input in the form of `{function, value}` * @param errorPrefix optional prefix for the error message */ dryWriteInteraction<I extends ContractInputGeneric>(input: I): Promise<void>; /** * A typed wrapper around `viewState` followed with a repsonse type check. * If response type is not `ok`, it will throw an error. * @param input input in the form of `{function, value}` * @returns interaction result */ safeReadInteraction<I extends ContractInputGeneric, V>(input: I): Promise<V>; /** * A typed wrapper around `viewState`, which is a read interaction. * @param input input in the form of `{function, value}` * @returns interaction result */ viewState<I extends ContractInputGeneric, R>(input: I): Promise<import("warp-contracts").InteractionResult<ContractState<M>, R>>; } declare class Admin<M extends ContractMode = ContractMode> { constructor(base: Base<M>); /** * Sets the owner as the given wallet address. * @param newOwner address of the new owner, make sure that this is correct! */ updateOwner(newOwner: string): Promise<void>; /** * Changes the whitelist for the selected list. * @param users an array of user addresses * @param name name of the list to be updated * @param op whether to `add` the users to whitelist or `remove` them */ updateWhitelist(users: string[], name: OpitonalArray<M['whitelists'], string>, op: 'add' | 'remove'): Promise<void>; /** * Update a verification key. * @param name name of the circuit that the verification key belongs to * @param verificationKey verification key */ updateVerificationKey(name: OpitonalArray<M['proofs'], string>, verificationKey: any): Promise<void>; /** * Disable or enable whitelist checks for a specific whitelist. * @param name name of the list * @param value a boolean */ updateWhitelistRequirement(name: OpitonalArray<M['whitelists'], string>, value: boolean): Promise<void>; /** * Disable or enable proof checks for a specific circuit. * @param name name of the circuit * @param value a boolean */ updateProofRequirement(name: OpitonalArray<M['proofs'], string>, value: boolean): Promise<void>; } export class BaseSDK<V = unknown, M extends ContractMode = ContractMode> { readonly base: Base<M>; readonly admin: Admin<M>; /** * Connects to the given contract via the provided Warp instance using the provided signer. * @param signer a Signer, such as Arweave wallet or Ethereum CustomSignature * @param contractTxId contract txId to connect to * @param warp a Warp instace, such as `WarpFactory.forMainnet()` */ constructor(signer: ArWallet | CustomSignature, contractTxId: string, warp: Warp); /** The smart-contract that we are connected to. */ get contract(): Contract<ContractState<M>>; /** Warp instance. */ get warp(): Warp; /** Contract transaction id. */ get contractTxId(): string; /** Signer. */ get signer(): ArWallet | CustomSignature; /** * Returns the latest contract state. * * For a more fine-grained state data, use `base.readState()`. * * @returns contract state object */ getState(): Promise<ContractState<M>>; /** * Alternative method of getting key values. Uses the underlying `getStorageValues` * function, returns a Map instead of an array. * * @param keys an array of keys * @returns `SortKeyCacheResult` of a key-value `Map` */ getStorageValues(keys: string[]): Promise<SortKeyCacheResult<Map<string, V | null>>>; /** * Returns keys with respect to a range option. * * If no option is provided, it will get all keys. * * @param options optional range * @returns an array of keys */ getKeys(options?: SortKeyCacheRangeOptions): Promise<string[]>; /** * Returns all keys in the database. * * @returns an array of all keys */ getAllKeys(): Promise<string[]>; /** * Returns a mapping of keys and values with respect to a range option. * If no option is provided, all values are returned. * * @param options optional range * @returns a key-value `Map` */ getKVMap(options?: SortKeyCacheRangeOptions): Promise<Map<string, V | null>>; /** * Gets the value of the given key. * @param key the key of the value to be returned * @returns the value of the given key */ get(key: string): Promise<V | null>; /** * Gets the values at the given keys as an array. * * If a value does not exist, it is returned as `null`. * * Note that the transaction limit may become a problem for too many keys. * * @param keys an array of keys * @returns an array of corresponding values */ getMany(keys: string[]): Promise<(V | null)[]>; /** * Inserts the given value into database. * * There must not be a value at the given key. * * @param key the key of the value to be inserted * @param value the value to be inserted */ put(key: string, value: V): Promise<void>; /** * Inserts an array of value into database. * * There must not be a value at the given key. * * @param keys the keys of the values to be inserted * @param values the values to be inserted */ putMany(keys: string[], values: V[]): Promise<void>; /** * Updates the value of given key. * @param key key of the value to be updated * @param value new value * @param proof optional zero-knowledge proof */ update(key: string, value: V, proof?: object): Promise<void>; /** * Removes the value of given key along with the key. * Checks if the proof is valid. * @param key key of the value to be removed * @param proof optional zero-knowledge proof */ remove(key: string, proof?: object): Promise<void>; } export class SDK<V = unknown> extends BaseSDK<V, { proofs: ['auth']; whitelists: ['put', 'update']; }> { } /** Just like HollowDB SDK, but supports `Set` and `SetMany` operations. * The user must be whitelisted for `set` separately to use them. * * A `set` operation is like a `put` but the key can exist already and will be overwritten. */ export class SetSDK<V = unknown> extends BaseSDK<V, { proofs: ['auth']; whitelists: ['put', 'update', 'set']; }> { /** * Inserts the given value into database. * * Overwrites the existing values at the given key. * * @param key the key of the value to be inserted * @param value the value to be inserted */ set(key: string, value: V): Promise<void>; /** * Inserts an array of value into database. * * Overwrites the existing values at the given keys. * * @param keys the keys of the values to be inserted * @param values the values to be inserted */ setMany(keys: string[], values: V[]): Promise<void>; /** * Overwrites the contract state. * * Note that this is an owner-only operation, and a wrongfully * overwritten state may break some of the contract methods. * * @param state the key of the value to be inserted */ setState(state: Awaited<ReturnType<this['getState']>>): Promise<void>; } //# sourceMappingURL=index.d.ts.map