UNPKG

@daml/ledger

Version:

Client side API implementation for a Daml based ledger. This library implements the JSON based API for a Daml ledger documented in https://docs.daml.com/json-api/index.html.

605 lines (604 loc) • 22.8 kB
import { Choice, ChoiceFrom, DisclosedContract, ContractId, List, Party, Template, TemplateOrInterface, Text } from "@daml/types"; /** * The result of a ``query`` against the ledger. * * Note: this is meant to be used by @daml/react. * * @typeparam T The contract template type of the query. * @typeparam K The contract key type of the query. * @typeparam I The template id type. */ export type QueryResult<T extends object, K, I extends string> = { /** Contracts matching the query. */ contracts: readonly CreateEvent<T, K, I>[]; /** Indicator for whether the query is executing. */ loading: boolean; }; /** * Full information about a Party. * */ export type PartyInfo = { identifier: Party; displayName?: string; isLocal: boolean; }; export type User = { userId: string; primaryParty?: Party; }; export type CanActAs = { type: "CanActAs"; party: string; }; export type CanReadAs = { type: "CanReadAs"; party: string; }; export type ParticipantAdmin = { type: "ParticipantAdmin"; }; export type UserRight = CanActAs | CanReadAs | ParticipantAdmin; export declare class UserRightHelper { static canActAs(party: string): UserRight; static canReadAs(party: string): UserRight; static participantAdmin: UserRight; } export type PackageId = string; /** * A newly created contract. * * @typeparam T The contract payload type. * @typeparam K The contract key type. * @typeparam I The contract type id. * */ export type CreateEvent<T extends object, K = unknown, I extends string = string> = { templateId: I; contractId: ContractId<T>; signatories: List<Party>; observers: List<Party>; agreementText: Text; key: K; payload: T; }; /** * An archived contract. * * @typeparam T The contract template or interface type. * @typeparam I The template or interface id. */ export type ArchiveEvent<T extends object, I extends string = string> = { templateId: I; contractId: ContractId<T>; }; /** * An event is either the creation or archival of a contract. * * @typeparam T The contract template type. * @typeparam K The contract key type. * @typeparam I The contract id type. */ export type Event<T extends object, K = unknown, I extends string = string> = { created: CreateEvent<T, K, I>; matchedQueries: number[]; } | { created: CreateEvent<T, K, I>; } | { archived: ArchiveEvent<T, I>; }; /** @internal * exported for testing only */ export declare function assert(b: boolean, m: string): void; /** * `Query<T>` is the type of queries for searching for contracts of template * or interface type `T`. * * `Query<T>` is an object consisting of a subset of the fields of `T`. * * Comparison queries are not yet supported. * * NB: This type is heavily related to the `DeepPartial` type that can be found * in the TypeScript community. * * @typeparam T The contract template type. * */ export type Query<T> = T extends object ? { [K in keyof T]?: Query<T[K]>; } : T; /** * Error code and messages returned by the ledger. */ export type LedgerError = { status: number; errors: string[]; warnings: unknown | undefined; }; export type CommandMeta = { workflowId?: string; disclosedContracts?: DisclosedContract[]; }; /** * Event emitted when a stream gets closed. */ export type StreamCloseEvent = { code: number; reason: string; }; /** * Interface for streams returned by the streaming methods of the `Ledger` * class. Each `'change'` event contains accumulated state of type `State` as * well as the ledger events that triggered the current state change. * * @typeparam T The contract template type. * @typeparam K The contract key type. * @typeparam I The contract id type. * @typeparam State The accumulated state. */ export interface Stream<T extends object, K, I extends string, State> { /** * Register a callback that will be called when the state of the stream has * caught up with the Active Contract Set and is now receiving new transactions. * @param type 'live' * @param listener function taking the state of the stream as an argument. */ on(type: "live", listener: (state: State) => void): void; /** * Register a callback that will be called when the state of the stream changes, * eg. new contract creates or archives. * @param type 'change' * @param listener function taking the state of the stream and new events as * arguments. */ on(type: "change", listener: (state: State, events: readonly Event<T, K, I>[]) => void): void; /** * Register a callback that will be called when the underlying stream is closed. * @param type 'close' * @param listener a function taking a StreamCloseEvent as an argument. */ on(type: "close", listener: (closeEvent: StreamCloseEvent) => void): void; /** * Remove the registered callback for the 'live' event. * @param type 'live' * @param listener function to be deregistered. */ off(type: "live", listener: (state: State) => void): void; /** * Remove the registered callback for the 'change' event. * @param type 'change' * @param listener function to be deregistered. */ off(type: "change", listener: (state: State, events: readonly Event<T, K, I>[]) => void): void; /** * Remove the registered callback for the 'close' event. * @param type 'close' * @param listener function to be deregistered. */ off(type: "close", listener: (closeEvent: StreamCloseEvent) => void): void; /** * Close the Stream and stop receiving events. */ close(): void; } /** * Options for creating a handle to a Daml ledger. */ export type LedgerOptions = { /** JSON web token used for authentication. */ token: string; /** * Optional base URL for the non-streaming endpoints of the JSON API. If this parameter is not * provided, the protocol, host and port of the `window.location` object are used. */ httpBaseUrl?: string; /** * Optional base URL for the streaming endpoints of the JSON API. If this parameter is not * provided, the base URL for the non-streaming endpoints is used with the protocol 'http' or * 'https' replaced by 'ws' or 'wss', respectively. Specifying this parameter explicitly can be * useful when the non-streaming requests are proxied but the streaming request cannot be proxied, * as it is the case with the development server of `create-react-app`. */ wsBaseUrl?: string; /** * Optional number of milliseconds a connection has to be live to be considered healthy. If the * connection is closed after being live for at least this amount of time, the `Ledger` tries to * reconnect, else not. */ reconnectThreshold?: number; /** * Optional to enable/disable feature of all streaming request to the query endpoint being multiplexed * through a single web socket, is enabled by default. */ multiplexQueryStreams?: boolean; }; export declare enum WsState { Connecting = 0, Open = 1, Closing = 2, Closed = 3 } /** * An object of type `Ledger` represents a handle to a Daml ledger. */ export declare class Ledger { private readonly token; private readonly httpBaseUrl; private readonly wsBaseUrl; private readonly reconnectThreshold; private readonly multiplexQueryStreams; private readonly queryStreamsManager; /** * Construct a new `Ledger` object. See [[LedgerOptions]] for the constructor arguments. */ constructor({ token, httpBaseUrl, wsBaseUrl, reconnectThreshold, multiplexQueryStreams, }: LedgerOptions); /** * @internal */ private auth; /** * @internal */ private throwOnError; /** * @internal * * Internal function to submit a command to the JSON API. */ private submit; /** * Retrieve contracts for a given template. * * When no `query` argument is given, all contracts visible to the submitting party are returned. * When a `query` argument is given, only those contracts matching the query are returned. See * https://docs.daml.com/json-api/search-query-language.html for a description of the query * language. * * @param template The contract template of the contracts to be matched against. * @param query The contract query for the contracts to be matched against. * * @typeparam T The contract template type. * @typeparam K The contract key type. * @typeparam I The contract id type. * */ query<T extends object, K, I extends string>(template: TemplateOrInterface<T, K, I>, query?: Query<T>): Promise<CreateEvent<T, K, I>[]>; /** * Fetch a contract identified by its contract ID. * * @param template The template of the contract to be fetched. * @param contractId The contract id of the contract to be fetched. * * @typeparam T The contract template type. * @typeparam K The contract key type. * @typeparam I The contract id type. * */ fetch<T extends object, K, I extends string>(template: TemplateOrInterface<T, K, I>, contractId: ContractId<T>): Promise<CreateEvent<T, K, I> | null>; /** * Fetch a contract identified by its contract key. * * Same as [[fetch]], but the contract to be fetched is identified by its contract key instead of * its contract id. * * @param template The template of the contract to be fetched. * @param key The contract key of the contract to be fetched. * * @typeparam T The contract template type. * @typeparam K The contract key type. * @typeparam I The contract id type. */ fetchByKey<T extends object, K, I extends string>(template: Template<T, K, I>, key: K): Promise<CreateEvent<T, K, I> | null>; /** * Create a contract for a given template. * * @param template The template of the contract to be created. * @param payload The template arguments for the contract to be created. * @param meta Optional meta fields to specify additional data on a command submission. * * @typeparam T The contract template type. * @typeparam K The contract key type. * @typeparam I The contract id type. * */ create<T extends object, K, I extends string>(template: Template<T, K, I>, payload: T, meta?: CommandMeta): Promise<CreateEvent<T, K, I>>; /** * Exercise a choice on a contract identified by its contract ID. * * @param choice The choice to exercise. * @param contractId The contract id of the contract to exercise. * @param argument The choice arguments. * @param meta Optional meta fields to specify additional data on a command submission. * * @typeparam T The contract template type. * @typeparam C The type of the contract choice. * @typeparam R The return type of the choice. * * @returns The return value of the choice together with a list of * [[event]]'s that were created as a result of exercising the choice. */ exercise<T extends object, C, R, K>(choice: Choice<T, C, R, K>, contractId: ContractId<T>, argument: C, meta?: CommandMeta): Promise<[R, Event<object>[]]>; /** * Exercse a choice on a newly-created contract, in a single transaction. * * @param choice The choice to exercise. * @param payload The template arguments for the newly-created contract. * @param argument The choice arguments. * @param meta Optional meta fields to specify additional data on a command submission. * * @typeparam T The contract template type. * @typeparam C The type of the contract choice. * @typeparam R The return type of the choice. * * @returns The return value of the choice together with a list of * [[event]]'s that includes the creation event for the created contract as * well as all the events that were created as a result of exercising the * choice, including the archive event for the created contract if the choice * is consuming (or otherwise archives it as part of its execution). * */ createAndExercise<T extends object, C, R, K>(choice: ChoiceFrom<Template<T, K>> & Choice<T, C, R, K>, payload: T, argument: C, meta?: CommandMeta): Promise<[R, Event<object>[]]>; /** * Exercise a choice on a contract identified by its contract key. * * Same as [[exercise]], but the contract is identified by its contract key instead of its * contract id. * * @param choice The choice to exercise. * @param key The contract key of the contract to exercise. * @param argument The choice arguments. * @param meta Optional meta fields to specify additional data on a command submission. * * @typeparam T The contract template type. * @typeparam C The type of the contract choice. * @typeparam R The return type of the choice. * @typeparam K The type of the contract key. * * @returns The return value of the choice together with a list of [[event]]'s that where created * as a result of exercising the choice. */ exerciseByKey<T extends object, C, R, K>(choice: ChoiceFrom<Template<T, K>> & Choice<T, C, R, K>, key: K, argument: C, meta?: CommandMeta): Promise<[R, Event<object>[]]>; /** * Archive a contract identified by its contract ID. * * @param template The template of the contract to archive. * @param contractId The contract id of the contract to archive. * @param meta Optional meta fields to specify additional data on a command submission. * * @typeparam T The contract template type. * @typeparam K The contract key type. * @typeparam I The contract id type. * */ archive<T extends object, K, I extends string>(template: Template<T, K, I>, contractId: ContractId<T>, meta?: CommandMeta): Promise<ArchiveEvent<T, I>>; /** * Archive a contract identified by its contract key. * Same as [[archive]], but the contract to be archived is identified by its contract key. * * @param template The template of the contract to be archived. * @param key The contract key of the contract to be archived. * @param meta Optional meta fields to specify additional data on a command submission. * * @typeparam T The contract template type. * @typeparam K The contract key type. * @typeparam I The contract id type. * */ archiveByKey<T extends object, K, I extends string>(template: Template<T, K, I>, key: K, meta?: CommandMeta): Promise<ArchiveEvent<T, I>>; /** * @internal * * Internal command to submit a request to a streaming endpoint of the * JSON API. Returns a stream consisting of accumulated state together with * the events that produced the latest state change. The `change` function * must be an operation of the monoid `Event<T, K, I>[]` on the set `State`, * i.e., for all `s: State` and `x, y: Event<T, K, I>[]` we * must have the structural equalities * ``` * change(s, []) == s * change(s, x.concat(y)) == change(change(s, x), y) * ``` * Also, `change` must never change its arguments. */ private streamSubmit; /** * Retrieve a consolidated stream of events for a given template and query. * * The accumulated state is the current set of active contracts matching the query. When no * `query` argument is given, all events visible to the submitting party are returned. When a * `query` argument is given, only those create events matching the query are returned. See * https://docs.daml.com/json-api/search-query-language.html for a description of the query * language. * * @deprecated Prefer `streamQueries`. * * @param template The contract template to match contracts against. * @param query The query to match contracts agains. * * @typeparam T The contract template type. * @typeparam K The contract key type. * @typeparam I The contract id type. * */ streamQuery<T extends object, K, I extends string>(template: TemplateOrInterface<T, K, I>, query?: Query<T>): Stream<T, K, I, readonly CreateEvent<T, K, I>[]>; /** * @internal * */ private streamQueryCommon; /** * Retrieve a consolidated stream of events for a given template and queries. * * If the given list is empty, the accumulated state is the set of all active * contracts for the given template. Otherwise, the accumulated state is the * set of all contracts that match at least one of the given queries. * * See https://docs.daml.com/json-api/search-query-language.html for a * description of the query language. * * @param template The contract template to match contracts against. * @param queries A query to match contracts against. * * @typeparam T The contract template type. * @typeparam K The contract key type. * @typeparam I The contract id type. */ streamQueries<T extends object, K, I extends string>(template: TemplateOrInterface<T, K, I>, queries: Query<T>[]): Stream<T, K, I, readonly CreateEvent<T, K, I>[]>; /** * Retrieve a consolidated stream of events for a given template and contract key. * * The accumulated state is either the current active contract for the given * key, or null if there is no active contract for the given key. * * @deprecated Prefer `streamFetchByKeys`. * * @typeparam T The contract template type. * @typeparam K The contract key type. * @typeparam I The contract id type. * */ streamFetchByKey<T extends object, K, I extends string>(template: Template<T, K, I>, key: K): Stream<T, K, I, CreateEvent<T, K, I> | null>; /** * @internal * * Returns the same API as [[streamSubmit]] but does not, in fact, establish * any socket connection. Instead, this is a stream that always has the given * value as its accumulated state. */ private constantStream; /** * Retrieve a consolidated stream of events for a list of keys and a single * template. * * The accumulated state is an array of the same length as the given list of * keys, with positional correspondence. Each element in the array represents * the current contract for the given key, or is explicitly null if there is * currently no active contract matching that key. * * Note: the given `key` objects will be compared for (deep) equality with * the values returned by the API. As such, they have to be given in the * "output" format of the API, including the values of * `encodeDecimalAsString` and `encodeInt64AsString`. See [the JSON API docs * for details](https://docs.daml.com/json-api/lf-value-specification.html). * * @typeparam T The contract template type. * @typeparam K The contract key type. * @typeparam I The contract id type. */ streamFetchByKeys<T extends object, K, I extends string>(template: Template<T, K, I>, keys: K[]): Stream<T, K, I, (CreateEvent<T, K, I> | null)[]>; /** * Fetch parties by identifier. * * @param parties An array of Party identifiers. * * @returns An array of the same length, where each element corresponds to * the same-index element of the given parties, ans is either a PartyInfo * object if the party exists or null if it does not. * */ getParties(parties: Party[]): Promise<(PartyInfo | null)[]>; /** * Fetch all parties on the ledger. * * @returns All parties on the ledger, in no particular order. * */ listKnownParties(): Promise<PartyInfo[]>; /** * Get the current user details obtained by the currently used JWT. * * @param userId The user id * * @returns User details * */ getUser(userId?: string): Promise<User>; /** * Lists the users on the ledger * * @returns user list * */ listUsers(): Promise<User[]>; /** * Lists the rights associated with the given user id * * @param userId, if empty then the user id will obtained by the currently used JWT. * * @returns list of user rights */ listUserRights(userId?: string): Promise<UserRight[]>; /** * Grants rights to a user * * @param userId The user to which rights shall be granted * * @param rights The rights which shall be granted * * @returns The rights which actually were granted (if a right was already granted, then it will not be in the return list) */ grantUserRights(userId: string, rights: UserRight[]): Promise<UserRight[]>; /** * Revokes rights from a user * * @param userId The user from which rights shall be revoked * * @param rights The rights which shall be revoked * * @returns The rights which actually were revoked (if a right was already revoked, then it will not be in the return list) */ revokeUserRights(userId: string, rights: UserRight[]): Promise<UserRight[]>; /** * Creates a user * * @param userId The user ID * @param rights The initial rights the user should have * @param primaryParty The primary party the user should have * */ createUser(userId: string, rights: UserRight[], primaryParty?: string): Promise<void>; /** * Deletes a user * * @param userId The user ID * @param rights The initial rights the user should have * @param primaryParty The primary party the user should have * */ deleteUser(userId: string): Promise<void>; /** * Allocate a new party. * * @param partyOpt Parameters for party allocation. * * @returns PartyInfo for the newly created party. * */ allocateParty(partyOpt: { identifierHint?: string; displayName?: string; }): Promise<PartyInfo>; /** * Fetch a list of all package IDs from the ledger. * * @returns List of package IDs. * */ listPackages(): Promise<PackageId[]>; /** * Fetch a binary package. * * @returns The content of the package as a raw ArrayBuffer. * */ getPackage(id: PackageId): Promise<ArrayBuffer>; /** * Upload a binary archive. Note that this requires admin privileges. * * @returns No return value on success; throws on error. * */ uploadDarFile(abuf: Buffer<ArrayBufferLike>): Promise<void>; } export default Ledger;