diff --git a/CHANGELOG.md b/CHANGELOG.md index 43f499ef..b8af918b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ All notable changes will be documented in this file. Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. ## Unreleased + - TBD + +## 10.0.0-alpha.5 - [Breaking change: adjustements to transaction awaitening and completion, transaction watcher](https://github.com/ElrondNetwork/elrond-sdk-erdjs/pull/173) - [Breaking change: simplify network config / improve design - not a singleton anymore](https://github.com/ElrondNetwork/elrond-sdk-erdjs/pull/176) - [Fix / improve results parser (better heuristics)](https://github.com/ElrondNetwork/elrond-sdk-erdjs/pull/177) @@ -18,6 +21,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how - [Breaking change: unifying provider interfaces, preparing network providers for extraction - step 5](https://github.com/ElrondNetwork/elrond-sdk-erdjs/pull/185) - [Breaking change: extractions (network providers and contract wrappers)](https://github.com/ElrondNetwork/elrond-sdk-erdjs/pull/186) - [Breaking change: rename "methods" to "methodsExplicit". Rename "methodsAuto" to "methods" (default choice)](https://github.com/ElrondNetwork/elrond-sdk-erdjs/pull/187) + - [Remove SmartContractController (downgraded to a mere test utility)](https://github.com/ElrondNetwork/elrond-sdk-erdjs/pull/188) **Breaking changes** - Removed utility functions: `transaction.awaitExecuted()`, `transaction.awaitPending()`. `TransactionWatcher` should be used directly, instead. @@ -38,6 +42,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how - https://github.com/ElrondNetwork/elrond-sdk-erdjs-network-providers - https://github.com/ElrondNetwork/elrond-sdk-erdjs-contract-wrappers - Rename `methods` to `methodsExplicit`. Rename `methodsAuto` (only added in erdjs 10 beta) to `methods` (default choice). Therefore, by default, interactions are created without having to pass `TypedValue` objects as parameters. Automatic type inference is applied. + - Remove `SmartContractController` (downgraded to a mere test utility). ## [10.0.0-beta.3] - [Extract dapp / signing providers to separate repositories](https://github.com/ElrondNetwork/elrond-sdk-erdjs/pull/170) diff --git a/package-lock.json b/package-lock.json index 306221ed..17a6dac7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@elrondnetwork/erdjs", - "version": "10.0.0-beta.3", + "version": "10.0.0-alpha.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@elrondnetwork/erdjs", - "version": "10.0.0-beta.3", + "version": "10.0.0-alpha.5", "license": "GPL-3.0-or-later", "dependencies": { "@elrondnetwork/transaction-decoder": "0.1.0", diff --git a/package.json b/package.json index 3e3d839b..3d79a68a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@elrondnetwork/erdjs", - "version": "10.0.0-beta.3", + "version": "10.0.0-alpha.5", "description": "Smart Contracts interaction framework", "main": "out/index.js", "types": "out/index.d.js", diff --git a/src/interface.ts b/src/interface.ts index ed65a7cc..ded6757f 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -1,16 +1,11 @@ import { Signature } from "./signature"; -import { ITransactionOnNetwork, ITransactionStatus } from "./interfaceOfNetwork"; +import { ITransactionOnNetwork } from "./interfaceOfNetwork"; export interface ITransactionFetcher { /** * Fetches the state of a {@link Transaction}. */ getTransaction(txHash: IHash, hintSender?: IBech32Address, withResults?: boolean): Promise; - - /** - * Queries the status of a {@link Transaction}. - */ - getTransactionStatus(txHash: IHash): Promise; } /** diff --git a/src/smartcontracts/index.ts b/src/smartcontracts/index.ts index f6566d43..5a973eac 100644 --- a/src/smartcontracts/index.ts +++ b/src/smartcontracts/index.ts @@ -8,7 +8,6 @@ export * from "./argSerializer"; export * from "./code"; export * from "./codec"; export * from "./codeMetadata"; -export * from "./smartContractController"; export * from "./function"; export * from "./interaction"; export * from "./interactionChecker"; diff --git a/src/smartcontracts/interaction.local.net.spec.ts b/src/smartcontracts/interaction.local.net.spec.ts index 56ae9400..fd8bde86 100644 --- a/src/smartcontracts/interaction.local.net.spec.ts +++ b/src/smartcontracts/interaction.local.net.spec.ts @@ -1,6 +1,5 @@ -import { DefaultSmartContractController } from "./smartContractController"; +import { ContractController } from "../testutils/contractController"; import { SmartContract } from "./smartContract"; -import { BigUIntValue, OptionalValue, OptionValue, TokenIdentifierValue, U32Value } from "./typesystem"; import { loadAbiRegistry, loadContractCode, loadTestWallets, TestWallet } from "../testutils"; import { SmartContractAbi } from "./abi"; import { assert } from "chai"; @@ -8,7 +7,6 @@ import { Interaction } from "./interaction"; import { GasLimit } from "../networkParams"; import { ReturnCode } from "./returnCode"; import BigNumber from "bignumber.js"; -import { BytesValue } from "./typesystem/bytes"; import { createLocalnetProvider } from "../testutils/networkProviders"; @@ -26,7 +24,7 @@ describe("test smart contract interactor", function () { let abiRegistry = await loadAbiRegistry(["src/testdata/answer.abi.json"]); let abi = new SmartContractAbi(abiRegistry, ["answer"]); let contract = new SmartContract({ abi: abi }); - let controller = new DefaultSmartContractController(abi, provider); + let controller = new ContractController(provider); let network = await provider.getNetworkConfig(); await alice.sync(provider); @@ -74,7 +72,7 @@ describe("test smart contract interactor", function () { let abiRegistry = await loadAbiRegistry(["src/testdata/counter.abi.json"]); let abi = new SmartContractAbi(abiRegistry, ["counter"]); let contract = new SmartContract({ abi: abi }); - let controller = new DefaultSmartContractController(abi, provider); + let controller = new ContractController(provider); let network = await provider.getNetworkConfig(); await alice.sync(provider); @@ -127,7 +125,7 @@ describe("test smart contract interactor", function () { let abiRegistry = await loadAbiRegistry(["src/testdata/lottery-esdt.abi.json"]); let abi = new SmartContractAbi(abiRegistry, ["Lottery"]); let contract = new SmartContract({ abi: abi }); - let controller = new DefaultSmartContractController(abi, provider); + let controller = new ContractController(provider); let network = await provider.getNetworkConfig(); await alice.sync(provider); diff --git a/src/smartcontracts/interaction.spec.ts b/src/smartcontracts/interaction.spec.ts index b44951a4..5ac9b6b7 100644 --- a/src/smartcontracts/interaction.spec.ts +++ b/src/smartcontracts/interaction.spec.ts @@ -1,4 +1,4 @@ -import { DefaultSmartContractController } from "./smartContractController"; +import { ContractController } from "../testutils/contractController"; import { SmartContract } from "./smartContract"; import { BigUIntValue, OptionalValue, OptionValue, TokenIdentifierValue, U32Value } from "./typesystem"; import { @@ -112,7 +112,7 @@ describe("test smart contract interactor", function() { let abiRegistry = await loadAbiRegistry(["src/testdata/answer.abi.json"]); let abi = new SmartContractAbi(abiRegistry, ["answer"]); let contract = new SmartContract({ address: dummyAddress, abi: abi }); - let controller = new DefaultSmartContractController(abi, provider); + let controller = new ContractController(provider); let interaction = contract.methods .getUltimateAnswer() @@ -174,9 +174,9 @@ describe("test smart contract interactor", function() { let abiRegistry = await loadAbiRegistry(["src/testdata/counter.abi.json"]); let abi = new SmartContractAbi(abiRegistry, ["counter"]); let contract = new SmartContract({ address: dummyAddress, abi: abi }); - let controller = new DefaultSmartContractController(abi, provider); + let controller = new ContractController(provider); - let getInteraction = contract.methodsExplicit.get(); + let getInteraction = contract.methodsExplicit.get().check(); let incrementInteraction = (contract.methods.increment()).withGasLimit(new GasLimit(543210)); let decrementInteraction = (contract.methods.decrement()).withGasLimit(new GasLimit(987654)); @@ -221,7 +221,7 @@ describe("test smart contract interactor", function() { let abiRegistry = await loadAbiRegistry(["src/testdata/lottery-esdt.abi.json"]); let abi = new SmartContractAbi(abiRegistry, ["Lottery"]); let contract = new SmartContract({ address: dummyAddress, abi: abi }); - let controller = new DefaultSmartContractController(abi, provider); + let controller = new ContractController(provider); let startInteraction = ( contract.methodsExplicit @@ -237,6 +237,7 @@ describe("test smart contract interactor", function() { OptionalValue.newMissing() ]) .withGasLimit(new GasLimit(5000000)) + .check() ); let statusInteraction = ( diff --git a/src/smartcontracts/interaction.ts b/src/smartcontracts/interaction.ts index 8001bafe..4ad6f309 100644 --- a/src/smartcontracts/interaction.ts +++ b/src/smartcontracts/interaction.ts @@ -4,12 +4,13 @@ import { Transaction } from "../transaction"; import { Query } from "./query"; import { ContractFunction } from "./function"; import { Address } from "../address"; -import { AddressValue, BigUIntValue, BytesValue, TypedValue, U64Value, U8Value } from "./typesystem"; +import { AddressValue, BigUIntValue, BytesValue, EndpointDefinition, TypedValue, U64Value, U8Value } from "./typesystem"; import { Nonce } from "../nonce"; import { ESDTNFT_TRANSFER_FUNCTION_NAME, ESDT_TRANSFER_FUNCTION_NAME, MULTI_ESDTNFT_TRANSFER_FUNCTION_NAME } from "../constants"; import { Account } from "../account"; import { CallArguments } from "./interface"; import { IChainID, IGasLimit, IGasPrice } from "../interface"; +import { InteractionChecker } from "./interactionChecker"; /** * Internal interface: the smart contract, as seen from the perspective of an {@link Interaction}. @@ -17,6 +18,7 @@ import { IChainID, IGasLimit, IGasPrice } from "../interface"; interface ISmartContractWithinInteraction { call({ func, args, value, gasLimit, receiver }: CallArguments): Transaction; getAddress(): Address; + getEndpoint(name: ContractFunction): EndpointDefinition; } /** @@ -65,6 +67,10 @@ export class Interaction { return this.function; } + getEndpoint(): EndpointDefinition { + return this.contract.getEndpoint(this.function); + } + getArguments(): TypedValue[] { return this.args; } @@ -198,6 +204,14 @@ export class Interaction { this.querent = querent; return this; } + + /** + * To perform custom checking, extend {@link Interaction} and override this method. + */ + check(): Interaction { + new InteractionChecker().checkInteraction(this, this.getEndpoint()); + return this; + } } class TokenTransfersWithinInteraction { diff --git a/src/smartcontracts/interactionChecker.ts b/src/smartcontracts/interactionChecker.ts index 7ca78b91..a2efd2be 100644 --- a/src/smartcontracts/interactionChecker.ts +++ b/src/smartcontracts/interactionChecker.ts @@ -1,7 +1,6 @@ import * as errors from "../errors"; import { EndpointDefinition } from "./typesystem"; import { Interaction } from "./interaction"; -import { IInteractionChecker } from "./interface"; /** * An interaction checker that aims to be as strict as possible. @@ -10,7 +9,7 @@ import { IInteractionChecker } from "./interface"; * - errors related to calling "non-payable" functions with some value provided * - gas estimation errors (not yet implemented) */ -export class InteractionChecker implements IInteractionChecker { +export class InteractionChecker { checkInteraction(interaction: Interaction, definition: EndpointDefinition): void { this.checkPayable(interaction, definition); this.checkArguments(interaction, definition); @@ -50,7 +49,3 @@ export class InteractionChecker implements IInteractionChecker { } } } - -export class NullInteractionChecker implements IInteractionChecker { - checkInteraction(_interaction: Interaction, _definition: EndpointDefinition): void { } -} diff --git a/src/smartcontracts/interface.ts b/src/smartcontracts/interface.ts index af024e0c..df7973b1 100644 --- a/src/smartcontracts/interface.ts +++ b/src/smartcontracts/interface.ts @@ -6,7 +6,6 @@ import { Transaction } from "../transaction"; import { Code } from "./code"; import { CodeMetadata } from "./codeMetadata"; import { ContractFunction } from "./function"; -import { Interaction } from "./interaction"; import { ReturnCode } from "./returnCode"; import { EndpointDefinition, TypedValue } from "./typesystem"; @@ -79,6 +78,7 @@ export interface TypedOutcomeBundle { firstValue?: TypedValue; secondValue?: TypedValue; thirdValue?: TypedValue; + lastValue?: TypedValue; } export interface UntypedOutcomeBundle { @@ -87,16 +87,6 @@ export interface UntypedOutcomeBundle { values: Buffer[]; } -export interface ISmartContractController { - deploy(transaction: Transaction): Promise<{ transactionOnNetwork: ITransactionOnNetwork, bundle: UntypedOutcomeBundle }>; - execute(interaction: Interaction, transaction: Transaction): Promise<{ transactionOnNetwork: ITransactionOnNetwork, bundle: TypedOutcomeBundle }>; - query(interaction: Interaction): Promise; -} - -export interface IInteractionChecker { - checkInteraction(interaction: Interaction, definition: EndpointDefinition): void; -} - export interface IResultsParser { parseQueryResponse(queryResponse: IContractQueryResponse, endpoint: EndpointDefinition): TypedOutcomeBundle; parseUntypedQueryResponse(queryResponse: IContractQueryResponse): UntypedOutcomeBundle; diff --git a/src/smartcontracts/resultsParser.ts b/src/smartcontracts/resultsParser.ts index d9c27e23..ac04bb19 100644 --- a/src/smartcontracts/resultsParser.ts +++ b/src/smartcontracts/resultsParser.ts @@ -36,7 +36,8 @@ export class ResultsParser implements IResultsParser { values: values, firstValue: values[0], secondValue: values[1], - thirdValue: values[2] + thirdValue: values[2], + lastValue: values[values.length - 1] }; } @@ -60,7 +61,8 @@ export class ResultsParser implements IResultsParser { values: values, firstValue: values[0], secondValue: values[1], - thirdValue: values[2] + thirdValue: values[2], + lastValue: values[values.length - 1] }; } diff --git a/src/smartcontracts/smartContract.ts b/src/smartcontracts/smartContract.ts index 6cba9bee..239d7f55 100644 --- a/src/smartcontracts/smartContract.ts +++ b/src/smartcontracts/smartContract.ts @@ -11,7 +11,7 @@ import { ContractFunction } from "./function"; import { Query } from "./query"; import { SmartContractAbi } from "./abi"; import { guardValueIsSet } from "../utils"; -import { TypedValue } from "./typesystem"; +import { EndpointDefinition, TypedValue } from "./typesystem"; import { bigIntToBuffer } from "./codec/utils"; import BigNumber from "bignumber.js"; import { Interaction } from "./interaction"; @@ -129,6 +129,10 @@ export class SmartContract implements ISmartContract { return this.abi!; } + getEndpoint(name: string | ContractFunction): EndpointDefinition { + return this.getAbi().getEndpoint(name); + } + /** * Creates a {@link Transaction} for deploying the Smart Contract to the Network. */ diff --git a/src/smartcontracts/smartContractController.ts b/src/smartcontracts/smartContractController.ts deleted file mode 100644 index 29f3d3e2..00000000 --- a/src/smartcontracts/smartContractController.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { Interaction } from "./interaction"; -import { Transaction } from "../transaction"; -import { TypedOutcomeBundle, IInteractionChecker, IResultsParser, ISmartContractController, UntypedOutcomeBundle } from "./interface"; -import { ContractFunction } from "./function"; -import { ResultsParser } from "./resultsParser"; -import { InteractionChecker, NullInteractionChecker } from "./interactionChecker"; -import { EndpointDefinition } from "./typesystem"; -import { Logger } from "../logger"; -import { TransactionWatcher } from "../transactionWatcher"; -import { IContractQueryResponse, ITransactionOnNetwork, ITransactionStatus } from "../interfaceOfNetwork"; -import { IHash } from "../interface"; -import { Query } from "./query"; - -/** - * @deprecated (controller will be extracted, as well, or removed) - */ -interface IDeprecatedProvider { - sendTransaction(transaction: Transaction): Promise; - getTransaction(hash: IHash): Promise; - getTransactionStatus(hash: IHash): Promise; - queryContract(query: Query): Promise; -} - -/** - * Internal interface: the smart contract ABI, as seen from the perspective of a {@link SmartContractController}. - */ -interface ISmartContractAbi { - getEndpoint(func: ContractFunction): EndpointDefinition; -} - -/** - * Internal interface: a transaction completion awaiter, as seen from the perspective of a {@link SmartContractController}. - */ -interface ITransactionCompletionAwaiter { - awaitCompleted(transaction: Transaction): Promise; -} - -/** - * A (frontend) controller, suitable for frontends and dApp, - * where signing is performed by means of an external wallet provider. - */ -export class SmartContractController implements ISmartContractController { - private readonly abi: ISmartContractAbi; - private readonly checker: IInteractionChecker; - private readonly parser: IResultsParser; - private readonly provider: IDeprecatedProvider; - private readonly transactionCompletionAwaiter: ITransactionCompletionAwaiter; - - constructor( - abi: ISmartContractAbi, - checker: IInteractionChecker, - parser: IResultsParser, - provider: IDeprecatedProvider, - transactionWatcher: ITransactionCompletionAwaiter - ) { - this.abi = abi; - this.checker = checker; - this.parser = parser; - this.provider = provider; - this.transactionCompletionAwaiter = transactionWatcher; - } - - async deploy(transaction: Transaction): Promise<{ transactionOnNetwork: ITransactionOnNetwork, bundle: UntypedOutcomeBundle }> { - Logger.info(`SmartContractController.deploy [begin]: transaction = ${transaction.getHash()}`); - - await this.provider.sendTransaction(transaction); - await this.transactionCompletionAwaiter.awaitCompleted(transaction); - let transactionOnNetwork = await this.provider.getTransaction(transaction.getHash()); - let bundle = this.parser.parseUntypedOutcome(transactionOnNetwork); - - Logger.info(`SmartContractController.deploy [end]: transaction = ${transaction.getHash()}, return code = ${bundle.returnCode}`); - return { transactionOnNetwork, bundle }; - } - - /** - * Broadcasts an alredy-signed interaction transaction, and also waits for its execution on the Network. - * - * @param interaction The interaction used to build the {@link transaction} - * @param transaction The interaction transaction, which must be signed beforehand - */ - async execute(interaction: Interaction, transaction: Transaction): Promise<{ transactionOnNetwork: ITransactionOnNetwork, bundle: TypedOutcomeBundle }> { - Logger.info(`SmartContractController.execute [begin]: function = ${interaction.getFunction()}, transaction = ${transaction.getHash()}`); - - let endpoint = this.getEndpoint(interaction); - - this.checker.checkInteraction(interaction, endpoint); - - await this.provider.sendTransaction(transaction); - await this.transactionCompletionAwaiter.awaitCompleted(transaction); - let transactionOnNetwork = await this.provider.getTransaction(transaction.getHash()); - let bundle = this.parser.parseOutcome(transactionOnNetwork, endpoint); - - Logger.info(`SmartContractController.execute [end]: function = ${interaction.getFunction()}, transaction = ${transaction.getHash()}, return code = ${bundle.returnCode}`); - return { transactionOnNetwork, bundle }; - } - - async query(interaction: Interaction): Promise { - Logger.debug(`SmartContractController.query [begin]: function = ${interaction.getFunction()}`); - - let endpoint = this.getEndpoint(interaction); - - this.checker.checkInteraction(interaction, endpoint); - - let query = interaction.buildQuery(); - let queryResponse = await this.provider.queryContract(query); - let bundle = this.parser.parseQueryResponse(queryResponse, endpoint); - - Logger.debug(`SmartContractController.query [end]: function = ${interaction.getFunction()}, return code = ${bundle.returnCode}`); - return bundle; - } - - private getEndpoint(interaction: Interaction) { - let func = interaction.getFunction(); - return this.abi.getEndpoint(func); - } -} - -export class DefaultSmartContractController extends SmartContractController { - constructor(abi: ISmartContractAbi, provider: IDeprecatedProvider) { - super(abi, new InteractionChecker(), new ResultsParser(), provider, new TransactionWatcher(provider)); - } -} - -export class NoCheckSmartContractController extends SmartContractController { - constructor(abi: ISmartContractAbi, provider: IDeprecatedProvider) { - super(abi, new NullInteractionChecker(), new ResultsParser(), provider, new TransactionWatcher(provider)); - } -} diff --git a/src/testutils/contractController.ts b/src/testutils/contractController.ts new file mode 100644 index 00000000..cae9e28c --- /dev/null +++ b/src/testutils/contractController.ts @@ -0,0 +1,56 @@ +import { Interaction } from "../smartcontracts/interaction"; +import { Transaction } from "../transaction"; +import { TypedOutcomeBundle, IResultsParser, UntypedOutcomeBundle } from "../smartcontracts/interface"; +import { ResultsParser } from "../smartcontracts/resultsParser"; +import { Logger } from "../logger"; +import { TransactionWatcher } from "../transactionWatcher"; +import { ITransactionOnNetwork } from "../interfaceOfNetwork"; +import { INetworkProvider } from "./networkProviders"; + +export class ContractController { + private readonly parser: IResultsParser; + private readonly provider: INetworkProvider; + private readonly transactionCompletionAwaiter: TransactionWatcher; + + constructor(provider: INetworkProvider) { + this.parser = new ResultsParser(); + this.provider = provider; + this.transactionCompletionAwaiter = new TransactionWatcher(provider); + } + + async deploy(transaction: Transaction): Promise<{ transactionOnNetwork: ITransactionOnNetwork, bundle: UntypedOutcomeBundle }> { + Logger.info(`ContractController.deploy [begin]: transaction = ${transaction.getHash()}`); + + await this.provider.sendTransaction(transaction); + let transactionOnNetwork = await this.transactionCompletionAwaiter.awaitCompleted(transaction); + let bundle = this.parser.parseUntypedOutcome(transactionOnNetwork); + + Logger.info(`ContractController.deploy [end]: transaction = ${transaction.getHash()}, return code = ${bundle.returnCode}`); + return { transactionOnNetwork, bundle }; + } + + async execute(interaction: Interaction, transaction: Transaction): Promise<{ transactionOnNetwork: ITransactionOnNetwork, bundle: TypedOutcomeBundle }> { + Logger.info(`ContractController.execute [begin]: function = ${interaction.getFunction()}, transaction = ${transaction.getHash()}`); + + interaction.check(); + + await this.provider.sendTransaction(transaction); + let transactionOnNetwork = await this.transactionCompletionAwaiter.awaitCompleted(transaction); + let bundle = this.parser.parseOutcome(transactionOnNetwork, interaction.getEndpoint()); + + Logger.info(`ContractController.execute [end]: function = ${interaction.getFunction()}, transaction = ${transaction.getHash()}, return code = ${bundle.returnCode}`); + return { transactionOnNetwork, bundle }; + } + + async query(interaction: Interaction): Promise { + Logger.debug(`ContractController.query [begin]: function = ${interaction.getFunction()}`); + + interaction.check(); + + let queryResponse = await this.provider.queryContract(interaction.buildQuery()); + let bundle = this.parser.parseQueryResponse(queryResponse, interaction.getEndpoint()); + + Logger.debug(`ContractController.query [end]: function = ${interaction.getFunction()}, return code = ${bundle.returnCode}`); + return bundle; + } +} diff --git a/src/transactionWatcher.ts b/src/transactionWatcher.ts index 56506d2d..95086a2f 100644 --- a/src/transactionWatcher.ts +++ b/src/transactionWatcher.ts @@ -46,12 +46,12 @@ export class TransactionWatcher { /** * Waits until the transaction reaches the "pending" status. */ - public async awaitPending(transaction: ITransaction): Promise { - let isPending = (status: ITransactionStatus) => status.isPending(); - let doFetch = async () => await this.fetcher.getTransactionStatus(transaction.getHash()); + public async awaitPending(transaction: ITransaction): Promise { + let isPending = (transaction: ITransactionOnNetwork) => transaction.status.isPending(); + let doFetch = async () => await this.fetcher.getTransaction(transaction.getHash()); let errorProvider = () => new ErrExpectedTransactionStatusNotReached(); - return this.awaitConditionally( + return this.awaitConditionally( isPending, doFetch, errorProvider @@ -61,7 +61,7 @@ export class TransactionWatcher { /** * Waits until the transaction is completely processed. */ - public async awaitCompleted(transaction: ITransaction): Promise { + public async awaitCompleted(transaction: ITransaction): Promise { let isCompleted = (transactionOnNetwork: ITransactionOnNetwork) => transactionOnNetwork.isCompleted(); let doFetch = async () => await this.fetcher.getTransaction(transaction.getHash(), undefined, true); let errorProvider = () => new ErrExpectedTransactionStatusNotReached(); @@ -73,7 +73,7 @@ export class TransactionWatcher { ); } - public async awaitAllEvents(transaction: ITransaction, events: string[]): Promise { + public async awaitAllEvents(transaction: ITransaction, events: string[]): Promise { let foundAllEvents = (transactionOnNetwork: ITransactionOnNetwork) => { let allEventIdentifiers = this.getAllTransactionEvents(transactionOnNetwork).map(event => event.identifier); let allAreFound = events.every(event => allEventIdentifiers.includes(event)); @@ -90,7 +90,7 @@ export class TransactionWatcher { ); } - public async awaitAnyEvent(transaction: ITransaction, events: string[]): Promise { + public async awaitAnyEvent(transaction: ITransaction, events: string[]): Promise { let foundAnyEvent = (transactionOnNetwork: ITransactionOnNetwork) => { let allEventIdentifiers = this.getAllTransactionEvents(transactionOnNetwork).map(event => event.identifier); let anyIsFound = events.find(event => allEventIdentifiers.includes(event)) != undefined; @@ -107,7 +107,7 @@ export class TransactionWatcher { ); } - public async awaitOnCondition(transaction: ITransaction, condition: (data: ITransactionOnNetwork) => boolean): Promise { + public async awaitOnCondition(transaction: ITransaction, condition: (data: ITransactionOnNetwork) => boolean): Promise { let doFetch = async () => await this.fetcher.getTransaction(transaction.getHash(), undefined, true); let errorProvider = () => new ErrExpectedTransactionStatusNotReached(); @@ -122,7 +122,7 @@ export class TransactionWatcher { isSatisfied: (data: TData) => boolean, doFetch: () => Promise, createError: () => Err - ): Promise { + ): Promise { let periodicTimer = new AsyncTimer("watcher:periodic"); let timeoutTimer = new AsyncTimer("watcher:timeout"); @@ -161,6 +161,8 @@ export class TransactionWatcher { let error = createError(); throw error; } + + return fetchedData; } private getAllTransactionEvents(transaction: ITransactionOnNetwork): ITransactionEvent[] { @@ -185,9 +187,4 @@ class TransactionFetcherWithTracing implements ITransactionFetcher { Logger.debug(`transactionWatcher, getTransaction(${txHash.toString()})`); return await this.fetcher.getTransaction(txHash, hintSender, withResults); } - - async getTransactionStatus(txHash: IHash): Promise { - Logger.debug(`transactionWatcher, getTransactionStatus(${txHash.toString()})`); - return await this.fetcher.getTransactionStatus(txHash); - } }