diff --git a/src/contract/Contract.ts b/src/contract/Contract.ts index 4d6da3c5..7ba8a931 100644 --- a/src/contract/Contract.ts +++ b/src/contract/Contract.ts @@ -106,15 +106,15 @@ export interface Contract { * Returns state of the contract at required sortKey or blockHeight. * * @param sortKeyOrBlockHeight - either a sortKey or block height at which the contract should be read - * - * @param currentTx - a set of currently evaluating interactions, that should - * be skipped during contract inner calls - to prevent the infinite call loop issue - * (mostly related to contract that use the Foreign Call Protocol) + * @param interactions - optional interactions to be applied on state + * @param signal - allows to communicate with a DOM request (such as Fetch) and abort it + * @param state - uses specified state to read contract state (overrides reading state from the cache) */ readState( sortKeyOrBlockHeight?: string | number, interactions?: GQLNodeInterface[], - signal?: AbortSignal + signal?: AbortSignal, + state?: SortKeyCacheResult> ): Promise>>; /** @@ -128,10 +128,18 @@ export interface Contract { signal?: AbortSignal ): Promise>>; + /** + * Reads state at a specified sortKey and applies indicated interactions + * @param sortKey - sortKey at which the contract should be read + * @param interactions - optional interactions to be applied on state + * @param signal - allows to communicate with a DOM request (such as Fetch) and abort it + * @param state - uses specified state to read contract state (overrides reading state from the cache) + */ readStateFor( sortKey: string, interactions: GQLNodeInterface[], - signal?: AbortSignal + signal?: AbortSignal, + state?: SortKeyCacheResult> ): Promise>>; /** diff --git a/src/contract/HandlerBasedContract.ts b/src/contract/HandlerBasedContract.ts index 4de00042..ed2c2947 100644 --- a/src/contract/HandlerBasedContract.ts +++ b/src/contract/HandlerBasedContract.ts @@ -149,7 +149,8 @@ export class HandlerBasedContract implements Contract { async readState( sortKeyOrBlockHeight?: string | number, interactions?: GQLNodeInterface[], - signal?: AbortSignal + signal?: AbortSignal, + state?: SortKeyCacheResult> ): Promise>> { this.logger.info('Read state for', { contractTxId: this._contractTxId, @@ -181,7 +182,8 @@ export class HandlerBasedContract implements Contract { sortKey, false, interactions, - signal + signal, + state ); this.logger.info('Execution Context', { srcTxId: executionContext.contractDefinition?.srcTxId, @@ -221,9 +223,10 @@ export class HandlerBasedContract implements Contract { async readStateFor( sortKey: string, interactions: GQLNodeInterface[], - signal?: AbortSignal + signal?: AbortSignal, + state?: SortKeyCacheResult> ): Promise>> { - return this.readState(sortKey, interactions, signal); + return this.readState(sortKey, interactions, signal, state); } async readStateBatch( @@ -635,7 +638,8 @@ export class HandlerBasedContract implements Contract { upToSortKey?: string, forceDefinitionLoad = false, interactions?: GQLNodeInterface[], - signal?: AbortSignal + signal?: AbortSignal, + state?: SortKeyCacheResult> ): Promise>> { const { definitionLoader, interactionsLoader, stateEvaluator } = this.warp; let cachedState: SortKeyCacheResult>; @@ -646,7 +650,7 @@ export class HandlerBasedContract implements Contract { EvalStateResult >; } - cachedState = cachedState || (await stateEvaluator.latestAvailableState(contractTxId, upToSortKey)); + cachedState = state || cachedState || (await stateEvaluator.latestAvailableState(contractTxId, upToSortKey)); if (upToSortKey && this.evaluationOptions().strictSortKey && cachedState?.sortKey != upToSortKey) { throw new Error(`State not cached at the exact required ${upToSortKey} sortKey`); }