@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
TypeScript
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;