From b5cd4745fd859921c88fe239ea68b845e9b3fa9d Mon Sep 17 00:00:00 2001 From: Steven Liu Date: Thu, 10 Sep 2020 09:45:13 +0100 Subject: [PATCH] Fixed #659 - Added HashLockRepo and SecretLockRepo --- e2e/infrastructure/HashLockHttp.spec.ts | 242 ++++++++++++++++++ e2e/infrastructure/SecretLockHttp.spec.ts | 121 +++++++++ e2e/infrastructure/TransactionHttp.spec.ts | 2 +- package-lock.json | 6 +- package.json | 2 +- src/core/utils/LockHashUtils.ts | 2 +- src/infrastructure/HashLockHttp.ts | 96 +++++++ src/infrastructure/HashLockRepository.ts | 32 +++ src/infrastructure/RepositoryFactory.ts | 12 + src/infrastructure/RepositoryFactoryHttp.ts | 12 + src/infrastructure/SecretLockHttp.ts | 99 +++++++ src/infrastructure/SecretLockRepository.ts | 32 +++ src/infrastructure/infrastructure.ts | 8 + .../HashLockPaginationStreamer.ts | 34 +++ .../SecretLockPaginationStreamer.ts | 34 +++ .../searchCriteria/HashLockSearchCriteria.ts | 28 ++ .../SecretLockSearchCriteria.ts | 28 ++ src/model/lock/HashLockInfo.ts | 55 ++++ .../LockHashAlgorithm.ts | 0 src/model/lock/SecretLockInfo.ts | 68 +++++ src/model/model.ts | 6 +- .../transaction/SecretLockTransaction.ts | 2 +- .../transaction/SecretProofTransaction.ts | 2 +- test/core/utils/Hashes.spec.ts | 2 +- test/core/utils/TransactionMapping.spec.ts | 2 +- .../TransactionMappingWithSignatures.spec.ts | 2 +- test/infrastructure/AccountHttp.spec.ts | 18 ++ test/infrastructure/HashLockHttp.spec.ts | 91 +++++++ test/infrastructure/RepositoryFactory.spec.ts | 6 + test/infrastructure/SecretLockHttp.spec.ts | 104 ++++++++ .../SerializeTransactionToJSON.spec.ts | 2 +- .../HashLockPaginationStreamer.spec.ts | 60 +++++ .../SecretLockPaginationStreamer.spec.ts | 60 +++++ test/model/lock/HashLockInfo.spec.ts | 54 ++++ test/model/lock/SecretLockInfo.spec.ts | 63 +++++ .../HashTypeLengthValidator.spec.ts | 2 +- .../transaction/SecretLockTransaction.spec.ts | 2 +- .../SecretProofTransaction.spec.ts | 2 +- 38 files changed, 1377 insertions(+), 16 deletions(-) create mode 100644 e2e/infrastructure/HashLockHttp.spec.ts create mode 100644 e2e/infrastructure/SecretLockHttp.spec.ts create mode 100644 src/infrastructure/HashLockHttp.ts create mode 100644 src/infrastructure/HashLockRepository.ts create mode 100644 src/infrastructure/SecretLockHttp.ts create mode 100644 src/infrastructure/SecretLockRepository.ts create mode 100644 src/infrastructure/paginationStreamer/HashLockPaginationStreamer.ts create mode 100644 src/infrastructure/paginationStreamer/SecretLockPaginationStreamer.ts create mode 100644 src/infrastructure/searchCriteria/HashLockSearchCriteria.ts create mode 100644 src/infrastructure/searchCriteria/SecretLockSearchCriteria.ts create mode 100644 src/model/lock/HashLockInfo.ts rename src/model/{transaction => lock}/LockHashAlgorithm.ts (100%) create mode 100644 src/model/lock/SecretLockInfo.ts create mode 100644 test/infrastructure/HashLockHttp.spec.ts create mode 100644 test/infrastructure/SecretLockHttp.spec.ts create mode 100644 test/infrastructure/streamer/HashLockPaginationStreamer.spec.ts create mode 100644 test/infrastructure/streamer/SecretLockPaginationStreamer.spec.ts create mode 100644 test/model/lock/HashLockInfo.spec.ts create mode 100644 test/model/lock/SecretLockInfo.spec.ts diff --git a/e2e/infrastructure/HashLockHttp.spec.ts b/e2e/infrastructure/HashLockHttp.spec.ts new file mode 100644 index 0000000000..de4959042c --- /dev/null +++ b/e2e/infrastructure/HashLockHttp.spec.ts @@ -0,0 +1,242 @@ +/* + * Copyright 2018 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect } from 'chai'; +import { Account } from '../../src/model/account/Account'; +import { Address } from '../../src/model/account/Address'; +import { PlainMessage } from '../../src/model/message/PlainMessage'; +import { NetworkType } from '../../src/model/network/NetworkType'; +import { AggregateTransaction } from '../../src/model/transaction/AggregateTransaction'; +import { Deadline } from '../../src/model/transaction/Deadline'; +import { MultisigAccountModificationTransaction } from '../../src/model/transaction/MultisigAccountModificationTransaction'; +import { TransferTransaction } from '../../src/model/transaction/TransferTransaction'; +import { UInt64 } from '../../src/model/UInt64'; +import { IntegrationTestHelper } from './IntegrationTestHelper'; +import { toArray, take } from 'rxjs/operators'; +import { deepEqual } from 'assert'; +import { Order, HashLockPaginationStreamer } from '../../src/infrastructure/infrastructure'; +import { Mosaic } from '../../src/model/mosaic/Mosaic'; +import { LockFundsTransaction } from '../../src/model/transaction/LockFundsTransaction'; +import { ChronoUnit } from 'js-joda'; +import { SignedTransaction } from '../../src/model/transaction/SignedTransaction'; +import { UnresolvedMosaicId } from '../../src/model/mosaic/UnresolvedMosaicId'; +import { HashLockRepository } from '../../src/infrastructure/HashLockRepository'; + +describe('HashLockHttp', () => { + const helper = new IntegrationTestHelper(); + let account: Account; + let account2: Account; + let multisigAccount: Account; + let cosignAccount1: Account; + let cosignAccount2: Account; + let cosignAccount3: Account; + let hashLockRepo: HashLockRepository; + let hash: string; + let generationHash: string; + let networkType: NetworkType; + + before(() => { + return helper.start().then(() => { + account = helper.account; + account2 = helper.account2; + multisigAccount = helper.multisigAccount; + cosignAccount1 = helper.cosignAccount1; + cosignAccount2 = helper.cosignAccount2; + cosignAccount3 = helper.cosignAccount3; + generationHash = helper.generationHash; + networkType = helper.networkType; + hashLockRepo = helper.repositoryFactory.createHashLockRepository(); + }); + }); + before(() => { + return helper.listener.open(); + }); + + after(() => { + helper.listener.close(); + }); + + const createSignedAggregatedBondTransaction = (aggregatedTo: Account, signer: Account, recipient: Address): SignedTransaction => { + const transferTransaction = TransferTransaction.create( + Deadline.create(), + recipient, + [], + PlainMessage.create('test-message'), + networkType, + helper.maxFee, + ); + + const aggregateTransaction = AggregateTransaction.createBonded( + Deadline.create(2, ChronoUnit.MINUTES), + [transferTransaction.toAggregate(aggregatedTo.publicAccount)], + networkType, + [], + helper.maxFee, + ); + return signer.sign(aggregateTransaction, generationHash); + }; + + const createHashLockTransactionAndAnnounce = ( + signedAggregatedTransaction: SignedTransaction, + signer: Account, + mosaicId: UnresolvedMosaicId, + ): void => { + const lockFundsTransaction = LockFundsTransaction.create( + Deadline.create(), + new Mosaic(mosaicId, UInt64.fromUint(10 * Math.pow(10, helper.networkCurrencyDivisibility))), + UInt64.fromUint(1000), + signedAggregatedTransaction, + networkType, + helper.maxFee, + ); + const signedLockFundsTransaction = signer.sign(lockFundsTransaction, generationHash); + hash = signedLockFundsTransaction.hash; + helper.announce(signedLockFundsTransaction); + }; + + /** + * ========================= + * Setup test data + * ========================= + */ + + describe('Setup test multisig account', () => { + it('Announce MultisigAccountModificationTransaction', () => { + const modifyMultisigAccountTransaction = MultisigAccountModificationTransaction.create( + Deadline.create(), + 2, + 1, + [cosignAccount1.address, cosignAccount2.address, cosignAccount3.address], + [], + networkType, + helper.maxFee, + ); + + const aggregateTransaction = AggregateTransaction.createComplete( + Deadline.create(), + [modifyMultisigAccountTransaction.toAggregate(multisigAccount.publicAccount)], + networkType, + [], + helper.maxFee, + ); + const signedTransaction = aggregateTransaction.signTransactionWithCosignatories( + multisigAccount, + [cosignAccount1, cosignAccount2, cosignAccount3], + generationHash, + ); + + return helper.announce(signedTransaction); + }); + }); + + describe('Create a hash lock', () => { + it('Announce HashLockTransaction', () => { + const signedAggregatedTx = createSignedAggregatedBondTransaction(multisigAccount, account, account2.address); + return createHashLockTransactionAndAnnounce(signedAggregatedTx, account, helper.networkCurrencyNamespaceId); + }); + }); + + /** + * ========================= + * Tests + * ========================= + */ + + describe('getHashLock', () => { + it('should return hash lock info given hash', async () => { + const info = await hashLockRepo.getHashLock(hash).toPromise(); + expect(info.ownerAddress.plain()).to.be.equal(account.address.plain()); + expect(info.amount.toString()).to.be.equal('1000'); + }); + }); + + describe('searchHashLock', () => { + it('should return hash lock page info', async () => { + const info = await hashLockRepo.search({ address: account.address }).toPromise(); + expect(info.data.length).to.be.greaterThan(0); + }); + }); + + describe('searchHashLock with streamer', () => { + it('should return hash lock page info', async () => { + const streamer = new HashLockPaginationStreamer(hashLockRepo); + const infoStreamer = await streamer + .search({ address: account.address, pageSize: 20, order: Order.Asc }) + .pipe(take(20), toArray()) + .toPromise(); + const info = await hashLockRepo.search({ address: account.address, pageSize: 20, order: Order.Asc }).toPromise(); + expect(infoStreamer.length).to.be.greaterThan(0); + deepEqual(infoStreamer[0], info.data[0]); + }); + }); + + /** + * ========================= + * House Keeping + * ========================= + */ + + describe('Restore test multisig Accounts', () => { + it('Announce MultisigAccountModificationTransaction', () => { + const removeCosigner1 = MultisigAccountModificationTransaction.create( + Deadline.create(), + -1, + 0, + [], + [cosignAccount1.address], + networkType, + helper.maxFee, + ); + const removeCosigner2 = MultisigAccountModificationTransaction.create( + Deadline.create(), + 0, + 0, + [], + [cosignAccount2.address], + networkType, + helper.maxFee, + ); + + const removeCosigner3 = MultisigAccountModificationTransaction.create( + Deadline.create(), + -1, + -1, + [], + [cosignAccount3.address], + networkType, + helper.maxFee, + ); + + const aggregateTransaction = AggregateTransaction.createComplete( + Deadline.create(), + [ + removeCosigner1.toAggregate(multisigAccount.publicAccount), + removeCosigner2.toAggregate(multisigAccount.publicAccount), + removeCosigner3.toAggregate(multisigAccount.publicAccount), + ], + networkType, + [], + helper.maxFee, + ); + const signedTransaction = aggregateTransaction.signTransactionWithCosignatories( + cosignAccount1, + [cosignAccount2, cosignAccount3], + generationHash, + ); + return helper.announce(signedTransaction); + }); + }); +}); diff --git a/e2e/infrastructure/SecretLockHttp.spec.ts b/e2e/infrastructure/SecretLockHttp.spec.ts new file mode 100644 index 0000000000..15f86ce91c --- /dev/null +++ b/e2e/infrastructure/SecretLockHttp.spec.ts @@ -0,0 +1,121 @@ +/* + * Copyright 2018 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect } from 'chai'; +import { Account } from '../../src/model/account/Account'; +import { NetworkType } from '../../src/model/network/NetworkType'; +import { Deadline } from '../../src/model/transaction/Deadline'; +import { UInt64 } from '../../src/model/UInt64'; +import { IntegrationTestHelper } from './IntegrationTestHelper'; +import { toArray, take } from 'rxjs/operators'; +import { deepEqual } from 'assert'; +import { Order, SecretLockPaginationStreamer } from '../../src/infrastructure/infrastructure'; +import { SecretLockRepository } from '../../src/infrastructure/SecretLockRepository'; +import { SecretLockTransaction } from '../../src/model/transaction/SecretLockTransaction'; +import { LockHashAlgorithm } from '../../src/model/lock/LockHashAlgorithm'; +import { sha3_256 } from 'js-sha3'; +import { Crypto } from '../../src/core/crypto'; + +describe('SecretLockHttp', () => { + const helper = new IntegrationTestHelper(); + let account: Account; + let account2: Account; + let SecretLockRepo: SecretLockRepository; + let generationHash: string; + let networkType: NetworkType; + let secret: string; + + before(() => { + return helper.start().then(() => { + account = helper.account; + account2 = helper.account2; + networkType = helper.networkType; + SecretLockRepo = helper.repositoryFactory.createSecretLockRepository(); + secret = sha3_256.create().update(Crypto.randomBytes(20)).hex(); + }); + }); + before(() => { + return helper.listener.open(); + }); + + after(() => { + helper.listener.close(); + }); + + /** + * ========================= + * Setup test data + * ========================= + */ + + describe('Create a hash lock', () => { + it('Announce SecretLockTransaction', () => { + const secretLockTransaction = SecretLockTransaction.create( + Deadline.create(), + helper.createNetworkCurrency(10, false), + UInt64.fromUint(100), + LockHashAlgorithm.Op_Sha3_256, + secret, + account2.address, + networkType, + helper.maxFee, + ); + const signedTransaction = secretLockTransaction.signWith(account, generationHash); + return helper.announce(signedTransaction).then((transaction: SecretLockTransaction) => { + expect(transaction.mosaic, 'Mosaic').not.to.be.undefined; + expect(transaction.duration, 'Duration').not.to.be.undefined; + expect(transaction.hashAlgorithm, 'HashAlgorithm').not.to.be.undefined; + expect(transaction.secret, 'Secret').not.to.be.undefined; + expect(transaction.recipientAddress, 'RecipientAddress').not.to.be.undefined; + }); + }); + }); + + /** + * ========================= + * Tests + * ========================= + */ + + describe('getSecretLock', () => { + it('should return hash lock info given hash', async () => { + const info = await SecretLockRepo.getSecretLock(secret).toPromise(); + expect(info.ownerAddress.plain()).to.be.equal(account.address.plain()); + expect(info.recipientAddress.plain()).to.be.equal(account2.address.plain()); + expect(info.amount.toString()).to.be.equal('100'); + }); + }); + + describe('searchSecretLock', () => { + it('should return hash lock page info', async () => { + const info = await SecretLockRepo.search({ address: account.address }).toPromise(); + expect(info.data.length).to.be.greaterThan(0); + }); + }); + + describe('searchSecretLock with streamer', () => { + it('should return hash lock page info', async () => { + const streamer = new SecretLockPaginationStreamer(SecretLockRepo); + const infoStreamer = await streamer + .search({ address: account.address, pageSize: 20, order: Order.Asc }) + .pipe(take(20), toArray()) + .toPromise(); + const info = await SecretLockRepo.search({ address: account.address, pageSize: 20, order: Order.Asc }).toPromise(); + expect(infoStreamer.length).to.be.greaterThan(0); + deepEqual(infoStreamer[0], info.data[0]); + }); + }); +}); diff --git a/e2e/infrastructure/TransactionHttp.spec.ts b/e2e/infrastructure/TransactionHttp.spec.ts index 78c1200af9..608cd4e8fc 100644 --- a/e2e/infrastructure/TransactionHttp.spec.ts +++ b/e2e/infrastructure/TransactionHttp.spec.ts @@ -46,7 +46,7 @@ import { CosignatureSignedTransaction } from '../../src/model/transaction/Cosign import { CosignatureTransaction } from '../../src/model/transaction/CosignatureTransaction'; import { Deadline } from '../../src/model/transaction/Deadline'; import { HashLockTransaction } from '../../src/model/transaction/HashLockTransaction'; -import { LockHashAlgorithm } from '../../src/model/transaction/LockHashAlgorithm'; +import { LockHashAlgorithm } from '../../src/model/lock/LockHashAlgorithm'; import { LinkAction } from '../../src/model/transaction/LinkAction'; import { LockFundsTransaction } from '../../src/model/transaction/LockFundsTransaction'; import { MosaicAddressRestrictionTransaction } from '../../src/model/transaction/MosaicAddressRestrictionTransaction'; diff --git a/package-lock.json b/package-lock.json index 22fbe5c12e..f64864bbce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6611,9 +6611,9 @@ } }, "symbol-openapi-typescript-fetch-client": { - "version": "0.9.7-SNAPSHOT.202009041234", - "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-0.9.7-SNAPSHOT.202009041234.tgz", - "integrity": "sha512-r16MHZdPMQsYr6gVgcyDyQiSbu9KEhMeTx5zwly8jvV7lMjLbGdOKQt3y80P2fFPbvPZ5IhCFYJTu2saohLpkg==" + "version": "0.9.7-SNAPSHOT.202009100936", + "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-0.9.7-SNAPSHOT.202009100936.tgz", + "integrity": "sha512-C53mXJ9cegoIo26VzMtycx4lu7vzCQbN7Q4N9yM4GfK4CxLXgheCHFP9zUxBH4PS/j8WTgGmQP3mApSZeRY2wA==" }, "table": { "version": "5.4.6", diff --git a/package.json b/package.json index be6524aba2..bf89a898f6 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "ripemd160": "^2.0.2", "rxjs": "^6.5.3", "rxjs-compat": "^6.5.3", - "symbol-openapi-typescript-fetch-client": "0.9.7-SNAPSHOT.202009041234", + "symbol-openapi-typescript-fetch-client": "0.9.7-SNAPSHOT.202009100936", "tweetnacl": "^1.0.3", "utf8": "^3.0.0", "ws": "^7.2.3" diff --git a/src/core/utils/LockHashUtils.ts b/src/core/utils/LockHashUtils.ts index b424f3c8bd..d4a7baf23c 100644 --- a/src/core/utils/LockHashUtils.ts +++ b/src/core/utils/LockHashUtils.ts @@ -15,7 +15,7 @@ */ import { sha3_256 } from 'js-sha3'; -import { LockHashAlgorithm } from '../../model/transaction/LockHashAlgorithm'; +import { LockHashAlgorithm } from '../../model/lock/LockHashAlgorithm'; import * as ripemd160 from 'ripemd160'; import { sha256 } from 'js-sha256'; /** diff --git a/src/infrastructure/HashLockHttp.ts b/src/infrastructure/HashLockHttp.ts new file mode 100644 index 0000000000..e0e4af4343 --- /dev/null +++ b/src/infrastructure/HashLockHttp.ts @@ -0,0 +1,96 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Observable } from 'rxjs'; +import { HashLockRoutesApi, HashLockInfoDTO } from 'symbol-openapi-typescript-fetch-client'; +import { Address } from '../model/account/Address'; +import { MosaicId } from '../model/mosaic/MosaicId'; +import { UInt64 } from '../model/UInt64'; +import { Http } from './Http'; +import { DtoMapping } from '../core/utils/DtoMapping'; +import { Page } from './Page'; +import { HashLockRepository } from './HashLockRepository'; +import { HashLockInfo } from '../model/lock/HashLockInfo'; +import { HashLockSearchCriteria } from './searchCriteria/HashLockSearchCriteria'; + +/** + * Hashlock http repository. + * + * @since 1.0 + */ +export class HashLockHttp extends Http implements HashLockRepository { + /** + * @internal + * Symbol openapi typescript-node client account routes api + */ + private hashLockRoutesApi: HashLockRoutesApi; + + /** + * Constructor + * @param url Base catapult-rest url + * @param fetchApi fetch function to be used when performing rest requests. + */ + constructor(url: string, fetchApi?: any) { + super(url, fetchApi); + this.hashLockRoutesApi = new HashLockRoutesApi(this.config()); + } + + /** + * Get hash lock info for an account. + * @param hash Hashlock hash + * @returns Observable + */ + public getHashLock(hash: string): Observable { + return this.call(this.hashLockRoutesApi.getHashLock(hash), (body) => this.toHashLockInfo(body)); + } + + /** + * Gets an array of HashLockInfo. + * @param criteria - HashLock search criteria + * @returns Observable> + */ + public search(criteria: HashLockSearchCriteria): Observable> { + return this.call( + this.hashLockRoutesApi.searchHashLock( + criteria.address.plain(), + criteria.pageSize, + criteria.pageNumber, + criteria.offset, + DtoMapping.mapEnum(criteria.order), + ), + (body) => super.toPage(body.pagination, body.data, this.toHashLockInfo), + ); + } + + /** + * This method maps a HashLockInfoDTO from rest to the SDK's HashLockInfo model object. + * + * @internal + * @param {HashLockInfoDTO} dto HashLockInfoDTO the dto object from rest. + * @returns HashLockInfo model + */ + private toHashLockInfo(dto: HashLockInfoDTO): HashLockInfo { + return new HashLockInfo( + dto.id, + Address.createFromEncoded(dto.lock.ownerAddress), + new MosaicId(dto.lock.mosaicId), + UInt64.fromNumericString(dto.lock.amount), + UInt64.fromNumericString(dto.lock.endHeight), + dto.lock.status, + dto.lock.hash, + ); + } +} diff --git a/src/infrastructure/HashLockRepository.ts b/src/infrastructure/HashLockRepository.ts new file mode 100644 index 0000000000..eaf93cc8d0 --- /dev/null +++ b/src/infrastructure/HashLockRepository.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Observable } from 'rxjs'; +import { Searcher } from './paginationStreamer/Searcher'; +import { HashLockInfo } from '../model/lock/HashLockInfo'; +import { HashLockSearchCriteria } from './searchCriteria/HashLockSearchCriteria'; + +/** + * Hashlock interface repository. + */ +export interface HashLockRepository extends Searcher { + /** + * Get hash lock info for an account. + * @param hash Hashlock hash + * @returns Observable + */ + getHashLock(hash: string): Observable; +} diff --git a/src/infrastructure/RepositoryFactory.ts b/src/infrastructure/RepositoryFactory.ts index 4f6228f8a6..bda4dad7e7 100644 --- a/src/infrastructure/RepositoryFactory.ts +++ b/src/infrastructure/RepositoryFactory.ts @@ -31,6 +31,8 @@ import { RestrictionAccountRepository } from './RestrictionAccountRepository'; import { RestrictionMosaicRepository } from './RestrictionMosaicRepository'; import { TransactionRepository } from './TransactionRepository'; import { TransactionStatusRepository } from './TransactionStatusRepository'; +import { HashLockRepository } from './HashLockRepository'; +import { SecretLockRepository } from './SecretLockRepository'; /** * A repository factory allows clients to create repositories to access NEM Server without knowing @@ -120,6 +122,16 @@ export interface RepositoryFactory { */ createRestrictionMosaicRepository(): RestrictionMosaicRepository; + /** + * @returns a newly created {@link HashLockRepository} + */ + createHashLockRepository(): HashLockRepository; + + /** + * @returns a newly created {@link SecretLockRepository} + */ + createSecretLockRepository(): SecretLockRepository; + /** * @returns a newly created {@link IListener} */ diff --git a/src/infrastructure/RepositoryFactoryHttp.ts b/src/infrastructure/RepositoryFactoryHttp.ts index 5a8e470772..2982ae80ec 100644 --- a/src/infrastructure/RepositoryFactoryHttp.ts +++ b/src/infrastructure/RepositoryFactoryHttp.ts @@ -49,6 +49,10 @@ import { TransactionHttp } from './TransactionHttp'; import { TransactionRepository } from './TransactionRepository'; import { TransactionStatusHttp } from './TransactionStatusHttp'; import { TransactionStatusRepository } from './TransactionStatusRepository'; +import { HashLockRepository } from './HashLockRepository'; +import { SecretLockRepository } from './SecretLockRepository'; +import { SecretLockHttp } from './SecretLockHttp'; +import { HashLockHttp } from './HashLockHttp'; /** * Receipt http repository. * @@ -138,6 +142,14 @@ export class RepositoryFactoryHttp implements RepositoryFactory { return new TransactionStatusHttp(this.url, this.fetchApi); } + createHashLockRepository(): HashLockRepository { + return new HashLockHttp(this.url, this.fetchApi); + } + + createSecretLockRepository(): SecretLockRepository { + return new SecretLockHttp(this.url, this.fetchApi); + } + getGenerationHash(): Observable { return this.generationHash; } diff --git a/src/infrastructure/SecretLockHttp.ts b/src/infrastructure/SecretLockHttp.ts new file mode 100644 index 0000000000..ad6e0471a3 --- /dev/null +++ b/src/infrastructure/SecretLockHttp.ts @@ -0,0 +1,99 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Observable } from 'rxjs'; +import { SecretLockRoutesApi, SecretLockInfoDTO } from 'symbol-openapi-typescript-fetch-client'; +import { Address } from '../model/account/Address'; +import { MosaicId } from '../model/mosaic/MosaicId'; +import { UInt64 } from '../model/UInt64'; +import { Http } from './Http'; +import { DtoMapping } from '../core/utils/DtoMapping'; +import { Page } from './Page'; +import { SecretLockRepository } from './SecretLockRepository'; +import { SecretLockInfo } from '../model/lock/SecretLockInfo'; +import { SecretLockSearchCriteria } from './searchCriteria/SecretLockSearchCriteria'; + +/** + * SecretLock http repository. + * + * @since 1.0 + */ +export class SecretLockHttp extends Http implements SecretLockRepository { + /** + * @internal + * Symbol openapi typescript-node client account routes api + */ + private secretLockRoutesApi: SecretLockRoutesApi; + + /** + * Constructor + * @param url Base catapult-rest url + * @param fetchApi fetch function to be used when performing rest requests. + */ + constructor(url: string, fetchApi?: any) { + super(url, fetchApi); + this.secretLockRoutesApi = new SecretLockRoutesApi(this.config()); + } + + /** + * Get secret lock info for an account. + * @param secret SecretLock secret + * @returns Observable + */ + public getSecretLock(secret: string): Observable { + return this.call(this.secretLockRoutesApi.getSecretLock(secret), (body) => this.toSecretLockInfo(body)); + } + + /** + * Gets an array of SecretLockInfo. + * @param criteria - SecretLock search criteria + * @returns Observable> + */ + public search(criteria: SecretLockSearchCriteria): Observable> { + return this.call( + this.secretLockRoutesApi.searchSecretLock( + criteria.address.plain(), + criteria.pageSize, + criteria.pageNumber, + criteria.offset, + DtoMapping.mapEnum(criteria.order), + ), + (body) => super.toPage(body.pagination, body.data, this.toSecretLockInfo), + ); + } + + /** + * This method maps a SecretLockInfoDTO from rest to the SDK's SecretLockInfo model object. + * + * @internal + * @param {SecretLockInfoDTO} dto SecretLockInfoDTO the dto object from rest. + * @returns SecretLockInfo model + */ + private toSecretLockInfo(dto: SecretLockInfoDTO): SecretLockInfo { + return new SecretLockInfo( + dto.id, + Address.createFromEncoded(dto.lock.ownerAddress), + new MosaicId(dto.lock.mosaicId), + UInt64.fromNumericString(dto.lock.amount), + UInt64.fromNumericString(dto.lock.endHeight), + dto.lock.status, + dto.lock.hashAlgorithm.valueOf(), + dto.lock.secret, + Address.createFromEncoded(dto.lock.recipientAddress), + dto.lock.compositeHash, + ); + } +} diff --git a/src/infrastructure/SecretLockRepository.ts b/src/infrastructure/SecretLockRepository.ts new file mode 100644 index 0000000000..f063b97479 --- /dev/null +++ b/src/infrastructure/SecretLockRepository.ts @@ -0,0 +1,32 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Observable } from 'rxjs'; +import { Searcher } from './paginationStreamer/Searcher'; +import { SecretLockInfo } from '../model/lock/SecretLockInfo'; +import { SecretLockSearchCriteria } from './searchCriteria/SecretLockSearchCriteria'; + +/** + * Secretlock interface repository. + */ +export interface SecretLockRepository extends Searcher { + /** + * Get Secret lock info for an account. + * @param secret Secretlock Secret + * @returns Observable + */ + getSecretLock(secret: string): Observable; +} diff --git a/src/infrastructure/infrastructure.ts b/src/infrastructure/infrastructure.ts index 66732be4cf..484d9c6cf6 100644 --- a/src/infrastructure/infrastructure.ts +++ b/src/infrastructure/infrastructure.ts @@ -51,6 +51,10 @@ export * from './TransactionStatusRepository'; export * from './TransactionGroup'; export * from './RepositoryCallError'; export * from './MetadataRepository'; +export * from './HashLockRepository'; +export * from './HashLockHttp'; +export * from './SecretLockRepository'; +export * from './SecretLockHttp'; // Pagination export * from './Page'; @@ -64,6 +68,8 @@ export * from './searchCriteria/TransactionSearchCriteria'; export * from './searchCriteria/MetadataSearchCriteria'; export * from './searchCriteria/ResolutionStatementSearchCriteria'; export * from './searchCriteria/TransactionStatementSearchCriteria'; +export * from './searchCriteria/HashLockSearchCriteria'; +export * from './searchCriteria/SecretLockSearchCriteria'; export * from './paginationStreamer/BlockPaginationStreamer'; export * from './paginationStreamer/MosaicPaginationStreamer'; @@ -74,3 +80,5 @@ export * from './paginationStreamer/AccountPaginationStreamer'; export * from './paginationStreamer/NamespacePaginationStreamer'; export * from './paginationStreamer/MetadataPaginationStreamer'; export * from './paginationStreamer/ReceiptPaginationStreamer'; +export * from './paginationStreamer/HashLockPaginationStreamer'; +export * from './paginationStreamer/SecretLockPaginationStreamer'; diff --git a/src/infrastructure/paginationStreamer/HashLockPaginationStreamer.ts b/src/infrastructure/paginationStreamer/HashLockPaginationStreamer.ts new file mode 100644 index 0000000000..5ae90ec4f1 --- /dev/null +++ b/src/infrastructure/paginationStreamer/HashLockPaginationStreamer.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { PaginationStreamer } from './PaginationStreamer'; +import { Searcher } from './Searcher'; +import { HashLockInfo } from '../../model/lock/HashLockInfo'; +import { HashLockSearchCriteria } from '../searchCriteria/HashLockSearchCriteria'; + +/** + * A helper object that streams {@link HashLockInfo} using the search. + */ +export class HashLockPaginationStreamer extends PaginationStreamer { + /** + * Constructor + * + * @param searcher the hashLock repository that will perform the searches + */ + constructor(searcher: Searcher) { + super(searcher); + } +} diff --git a/src/infrastructure/paginationStreamer/SecretLockPaginationStreamer.ts b/src/infrastructure/paginationStreamer/SecretLockPaginationStreamer.ts new file mode 100644 index 0000000000..826c099ca0 --- /dev/null +++ b/src/infrastructure/paginationStreamer/SecretLockPaginationStreamer.ts @@ -0,0 +1,34 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { PaginationStreamer } from './PaginationStreamer'; +import { Searcher } from './Searcher'; +import { SecretLockInfo } from '../../model/lock/SecretLockInfo'; +import { SecretLockSearchCriteria } from '../searchCriteria/SecretLockSearchCriteria'; + +/** + * A helper object that streams {@link SecretLockInfo} using the search. + */ +export class SecretLockPaginationStreamer extends PaginationStreamer { + /** + * Constructor + * + * @param searcher the SecretLock repository that will perform the searches + */ + constructor(searcher: Searcher) { + super(searcher); + } +} diff --git a/src/infrastructure/searchCriteria/HashLockSearchCriteria.ts b/src/infrastructure/searchCriteria/HashLockSearchCriteria.ts new file mode 100644 index 0000000000..27339bfa32 --- /dev/null +++ b/src/infrastructure/searchCriteria/HashLockSearchCriteria.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SearchCriteria } from './SearchCriteria'; +import { Address } from '../../model/account/Address'; + +/** + * Defines the params used to search hash lock. With this criteria, you can sort and filter + */ +export interface HashLockSearchCriteria extends SearchCriteria { + /** + * The owner address. (required) + */ + address: Address; +} diff --git a/src/infrastructure/searchCriteria/SecretLockSearchCriteria.ts b/src/infrastructure/searchCriteria/SecretLockSearchCriteria.ts new file mode 100644 index 0000000000..cf7cabf811 --- /dev/null +++ b/src/infrastructure/searchCriteria/SecretLockSearchCriteria.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SearchCriteria } from './SearchCriteria'; +import { Address } from '../../model/account/Address'; + +/** + * Defines the params used to search secret lock. With this criteria, you can sort and filter + */ +export interface SecretLockSearchCriteria extends SearchCriteria { + /** + * The owner address. (required) + */ + address: Address; +} diff --git a/src/model/lock/HashLockInfo.ts b/src/model/lock/HashLockInfo.ts new file mode 100644 index 0000000000..dada73029e --- /dev/null +++ b/src/model/lock/HashLockInfo.ts @@ -0,0 +1,55 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"), + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Address } from '../account/Address'; +import { MosaicId } from '../mosaic/MosaicId'; +import { UInt64 } from '../UInt64'; + +/** + * Hash lock information + */ +export class HashLockInfo { + constructor( + /** + * The stored database id. + */ + public readonly recordId: string, + /** + * Owner's address. + */ + public readonly ownerAddress: Address, + /** + * Locked moasic id. + */ + public readonly mosaicId: MosaicId, + /** + * Locked fund amount. + */ + public readonly amount: UInt64, + /** + * Block height of the lock expires. + */ + public readonly endHeight: UInt64, + /** + * Current lock status. + */ + public readonly status: number, + /** + * Lock hash. + */ + public readonly hash: string, + ) {} +} diff --git a/src/model/transaction/LockHashAlgorithm.ts b/src/model/lock/LockHashAlgorithm.ts similarity index 100% rename from src/model/transaction/LockHashAlgorithm.ts rename to src/model/lock/LockHashAlgorithm.ts diff --git a/src/model/lock/SecretLockInfo.ts b/src/model/lock/SecretLockInfo.ts new file mode 100644 index 0000000000..ed41aa6081 --- /dev/null +++ b/src/model/lock/SecretLockInfo.ts @@ -0,0 +1,68 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"), + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Address } from '../account/Address'; +import { MosaicId } from '../mosaic/MosaicId'; +import { UInt64 } from '../UInt64'; +import { LockHashAlgorithm } from './LockHashAlgorithm'; + +/** + * Secret lock information + */ +export class SecretLockInfo { + constructor( + /** + * The stored database id. + */ + public readonly recordId: string, + /** + * Owner's address. + */ + public readonly ownerAddress: Address, + /** + * Locked moasic id. + */ + public readonly mosaicId: MosaicId, + /** + * Locked fund amount. + */ + public readonly amount: UInt64, + /** + * Block height of the lock expires. + */ + public readonly endHeight: UInt64, + /** + * Current lock status. + */ + public readonly status: number, + /** + * The lock hash algorithm. + */ + public readonly hashAlgorithm: LockHashAlgorithm, + /** + * The lock secret. + */ + public readonly secret: string, + /** + * The recipient's address. + */ + public readonly recipientAddress: Address, + /** + * The composite hash. + */ + public readonly compositeHash: string, + ) {} +} diff --git a/src/model/model.ts b/src/model/model.ts index 3fabef5fe4..9532ec9863 100644 --- a/src/model/model.ts +++ b/src/model/model.ts @@ -62,6 +62,10 @@ export * from './mosaic/MosaicNames'; export * from './mosaic/ResolvedMosaic'; export * from './mosaic/UnresolvedMosaicId'; +//lock +export * from './lock/HashLockInfo'; +export * from './lock/SecretLockInfo'; + // Mosaic export * from './metadata/Metadata'; export * from './metadata/MetadataEntry'; @@ -163,7 +167,7 @@ export * from './transaction/CosignatureTransaction'; export * from './transaction/Deadline'; export * from './transaction/PersistentDelegationRequestTransaction'; export * from './transaction/HashLockTransaction'; -export * from './transaction/LockHashAlgorithm'; +export * from './lock/LockHashAlgorithm'; export * from './transaction/InnerTransaction'; export * from './transaction/LinkAction'; export * from './transaction/LockFundsTransaction'; diff --git a/src/model/transaction/SecretLockTransaction.ts b/src/model/transaction/SecretLockTransaction.ts index 8a8bb7113a..1d1b4d9a64 100644 --- a/src/model/transaction/SecretLockTransaction.ts +++ b/src/model/transaction/SecretLockTransaction.ts @@ -39,7 +39,7 @@ import { NetworkType } from '../network/NetworkType'; import { Statement } from '../receipt/Statement'; import { UInt64 } from '../UInt64'; import { Deadline } from './Deadline'; -import { LockHashAlgorithmLengthValidator, LockHashAlgorithm } from './LockHashAlgorithm'; +import { LockHashAlgorithmLengthValidator, LockHashAlgorithm } from '../lock/LockHashAlgorithm'; import { InnerTransaction } from './InnerTransaction'; import { Transaction } from './Transaction'; import { TransactionInfo } from './TransactionInfo'; diff --git a/src/model/transaction/SecretProofTransaction.ts b/src/model/transaction/SecretProofTransaction.ts index ed87c20f35..0584e6ef81 100644 --- a/src/model/transaction/SecretProofTransaction.ts +++ b/src/model/transaction/SecretProofTransaction.ts @@ -36,7 +36,7 @@ import { NetworkType } from '../network/NetworkType'; import { Statement } from '../receipt/Statement'; import { UInt64 } from '../UInt64'; import { Deadline } from './Deadline'; -import { LockHashAlgorithmLengthValidator, LockHashAlgorithm } from './LockHashAlgorithm'; +import { LockHashAlgorithmLengthValidator, LockHashAlgorithm } from '../lock/LockHashAlgorithm'; import { InnerTransaction } from './InnerTransaction'; import { Transaction } from './Transaction'; import { TransactionInfo } from './TransactionInfo'; diff --git a/test/core/utils/Hashes.spec.ts b/test/core/utils/Hashes.spec.ts index 38e9976f7f..c168abe869 100644 --- a/test/core/utils/Hashes.spec.ts +++ b/test/core/utils/Hashes.spec.ts @@ -17,7 +17,7 @@ import { expect } from 'chai'; import { Crypto } from '../../../src/core/crypto'; import { sha3_256 } from 'js-sha3'; import { LockHashUtils } from '../../../src/core/utils/LockHashUtils'; -import { LockHashAlgorithm } from '../../../src/model/transaction/LockHashAlgorithm'; +import { LockHashAlgorithm } from '../../../src/model/lock/LockHashAlgorithm'; import { Convert } from '../../../src/core/format/Convert'; import * as ripemd160 from 'ripemd160'; import { sha256 } from 'js-sha256'; diff --git a/test/core/utils/TransactionMapping.spec.ts b/test/core/utils/TransactionMapping.spec.ts index 8304a30584..87553fe723 100644 --- a/test/core/utils/TransactionMapping.spec.ts +++ b/test/core/utils/TransactionMapping.spec.ts @@ -44,7 +44,7 @@ import { AccountRestrictionTransaction } from '../../../src/model/transaction/Ac import { AddressAliasTransaction } from '../../../src/model/transaction/AddressAliasTransaction'; import { AggregateTransaction } from '../../../src/model/transaction/AggregateTransaction'; import { Deadline } from '../../../src/model/transaction/Deadline'; -import { LockHashAlgorithm } from '../../../src/model/transaction/LockHashAlgorithm'; +import { LockHashAlgorithm } from '../../../src/model/lock/LockHashAlgorithm'; import { LinkAction } from '../../../src/model/transaction/LinkAction'; import { LockFundsTransaction } from '../../../src/model/transaction/LockFundsTransaction'; import { MosaicAddressRestrictionTransaction } from '../../../src/model/transaction/MosaicAddressRestrictionTransaction'; diff --git a/test/core/utils/TransactionMappingWithSignatures.spec.ts b/test/core/utils/TransactionMappingWithSignatures.spec.ts index a1bd933e13..b17c3396e2 100644 --- a/test/core/utils/TransactionMappingWithSignatures.spec.ts +++ b/test/core/utils/TransactionMappingWithSignatures.spec.ts @@ -41,7 +41,7 @@ import { AccountRestrictionTransaction } from '../../../src/model/transaction/Ac import { AddressAliasTransaction } from '../../../src/model/transaction/AddressAliasTransaction'; import { AggregateTransaction } from '../../../src/model/transaction/AggregateTransaction'; import { Deadline } from '../../../src/model/transaction/Deadline'; -import { LockHashAlgorithm } from '../../../src/model/transaction/LockHashAlgorithm'; +import { LockHashAlgorithm } from '../../../src/model/lock/LockHashAlgorithm'; import { LinkAction } from '../../../src/model/transaction/LinkAction'; import { LockFundsTransaction } from '../../../src/model/transaction/LockFundsTransaction'; import { MosaicAddressRestrictionTransaction } from '../../../src/model/transaction/MosaicAddressRestrictionTransaction'; diff --git a/test/infrastructure/AccountHttp.spec.ts b/test/infrastructure/AccountHttp.spec.ts index 64d291b20c..1f4c7d927a 100644 --- a/test/infrastructure/AccountHttp.spec.ts +++ b/test/infrastructure/AccountHttp.spec.ts @@ -139,4 +139,22 @@ describe('AccountHttp', () => { const infos = await accountRepository.search({ mosaicId: new MosaicId(mosaic.id) }).toPromise(); assertAccountInfo(infos.data[0]); }); + + it('getAccountInfo - Error', async () => { + when(accountRoutesApi.getAccountInfo(address.plain())).thenReject(new Error('Mocked Error')); + await accountRepository + .getAccountInfo(address) + .toPromise() + .catch((error) => expect(error).not.to.be.undefined); + }); + + it('getAccountsInfo - Error', async () => { + const accountIds = {} as AccountIds; + accountIds.addresses = [address.plain()]; + when(accountRoutesApi.getAccountsInfo(deepEqual(accountIds))).thenReject(new Error('Mocked Error')); + await accountRepository + .getAccountsInfo([address]) + .toPromise() + .catch((error) => expect(error).not.to.be.undefined); + }); }); diff --git a/test/infrastructure/HashLockHttp.spec.ts b/test/infrastructure/HashLockHttp.spec.ts new file mode 100644 index 0000000000..1f2e23ba2b --- /dev/null +++ b/test/infrastructure/HashLockHttp.spec.ts @@ -0,0 +1,91 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { expect } from 'chai'; +import * as http from 'http'; +import { Pagination, HashLockInfoDTO, HashLockEntryDTO, HashLockRoutesApi, HashLockPage } from 'symbol-openapi-typescript-fetch-client'; +import { instance, mock, reset, when } from 'ts-mockito'; +import { DtoMapping } from '../../src/core/utils/DtoMapping'; +import { HashLockHttp } from '../../src/infrastructure/HashLockHttp'; +import { HashLockRepository } from '../../src/infrastructure/HashLockRepository'; +import { Address } from '../../src/model/account/Address'; +import { HashLockInfo } from '../../src/model/lock/HashLockInfo'; + +describe('HashLockHttp', () => { + const address = Address.createFromRawAddress('SATNE7Q5BITMUTRRN6IB4I7FLSDRDWZA34I2PMQ'); + + const dto = {} as HashLockInfoDTO; + dto.id = '1'; + const lockDto = {} as HashLockEntryDTO; + lockDto.amount = '10'; + lockDto.endHeight = '122'; + lockDto.hash = 'AAA'; + lockDto.mosaicId = '941299B2B7E1291C'; + lockDto.ownerAddress = address.encoded(); + lockDto.status = 1; + dto.lock = lockDto; + + const url = 'http://someHost'; + const response: http.IncomingMessage = mock(); + const hashLockRoutesApi: HashLockRoutesApi = mock(); + const hashLockRepository: HashLockRepository = DtoMapping.assign(new HashLockHttp(url), { + hashLockRoutesApi: instance(hashLockRoutesApi), + }); + + before(() => { + reset(response); + reset(hashLockRoutesApi); + }); + + function assertHashInfo(info: HashLockInfo): void { + expect(info).to.be.not.null; + expect(info.amount.toString()).to.be.equal(lockDto.amount); + expect(info.recordId).to.be.equal(dto.id); + expect(info.endHeight.toString()).to.be.equal(lockDto.endHeight); + expect(info.ownerAddress.encoded()).to.be.equal(lockDto.ownerAddress); + expect(info.hash).to.be.equal(lockDto.hash); + expect(info.mosaicId.toHex()).to.be.equal(lockDto.mosaicId); + expect(info.status).to.be.equal(lockDto.status); + } + + it('getHashLockInfo', async () => { + when(hashLockRoutesApi.getHashLock(lockDto.hash)).thenReturn(Promise.resolve(dto)); + const hashInfo = await hashLockRepository.getHashLock(lockDto.hash).toPromise(); + assertHashInfo(hashInfo); + }); + + it('search', async () => { + const pagination = {} as Pagination; + pagination.pageNumber = 1; + pagination.pageSize = 1; + + const body = {} as HashLockPage; + body.data = [dto]; + body.pagination = pagination; + when(hashLockRoutesApi.searchHashLock(address.plain(), undefined, undefined, undefined, undefined)).thenReturn( + Promise.resolve(body), + ); + const infos = await hashLockRepository.search({ address }).toPromise(); + assertHashInfo(infos.data[0]); + }); + + it('getHashLockInfo - Error', async () => { + when(hashLockRoutesApi.getHashLock(lockDto.hash)).thenReject(new Error('Mocked Error')); + await hashLockRepository + .getHashLock(lockDto.hash) + .toPromise() + .catch((error) => expect(error).not.to.be.undefined); + }); +}); diff --git a/test/infrastructure/RepositoryFactory.spec.ts b/test/infrastructure/RepositoryFactory.spec.ts index 7cb716ded4..7ad1961486 100644 --- a/test/infrastructure/RepositoryFactory.spec.ts +++ b/test/infrastructure/RepositoryFactory.spec.ts @@ -38,6 +38,8 @@ import { TransactionHttp } from '../../src/infrastructure/TransactionHttp'; import { TransactionStatusHttp } from '../../src/infrastructure/TransactionStatusHttp'; import { NetworkType } from '../../src/model/network/NetworkType'; import { NodeInfo } from '../../src/model/node/NodeInfo'; +import { HashLockHttp } from '../../src/infrastructure/HashLockHttp'; +import { SecretLockHttp } from '../../src/infrastructure/SecretLockHttp'; describe('RepositoryFactory', () => { it('Should create repositories', () => { @@ -59,6 +61,8 @@ describe('RepositoryFactory', () => { expect(repositoryFactory.createRestrictionAccountRepository()).to.be.not.null; expect(repositoryFactory.createRestrictionMosaicRepository()).to.be.not.null; expect(repositoryFactory.createTransactionRepository()).to.be.not.null; + expect(repositoryFactory.createHashLockRepository()).to.be.not.null; + expect(repositoryFactory.createSecretLockRepository()).to.be.not.null; }); it('Should get GenerationHash from cache', (done) => { @@ -226,5 +230,7 @@ describe('RepositoryFactory', () => { expect(factory.createRestrictionMosaicRepository() instanceof RestrictionMosaicHttp).to.be.true; expect(factory.createTransactionRepository() instanceof TransactionHttp).to.be.true; expect(factory.createTransactionStatusRepository() instanceof TransactionStatusHttp).to.be.true; + expect(factory.createHashLockRepository() instanceof HashLockHttp).to.be.true; + expect(factory.createSecretLockRepository() instanceof SecretLockHttp).to.be.true; }); }); diff --git a/test/infrastructure/SecretLockHttp.spec.ts b/test/infrastructure/SecretLockHttp.spec.ts new file mode 100644 index 0000000000..2e0b1d1a27 --- /dev/null +++ b/test/infrastructure/SecretLockHttp.spec.ts @@ -0,0 +1,104 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { expect } from 'chai'; +import * as http from 'http'; +import { + Pagination, + SecretLockInfoDTO, + SecretLockEntryDTO, + SecretLockRoutesApi, + SecretLockPage, + LockHashAlgorithmEnum, +} from 'symbol-openapi-typescript-fetch-client'; +import { instance, mock, reset, when } from 'ts-mockito'; +import { DtoMapping } from '../../src/core/utils/DtoMapping'; +import { SecretLockHttp } from '../../src/infrastructure/SecretLockHttp'; +import { SecretLockRepository } from '../../src/infrastructure/SecretLockRepository'; +import { Address } from '../../src/model/account/Address'; +import { SecretLockInfo } from '../../src/model/lock/SecretLockInfo'; + +describe('SecretLockHttp', () => { + const address = Address.createFromRawAddress('SATNE7Q5BITMUTRRN6IB4I7FLSDRDWZA34I2PMQ'); + + const dto = {} as SecretLockInfoDTO; + dto.id = '1'; + const lockDto = {} as SecretLockEntryDTO; + lockDto.amount = '10'; + lockDto.endHeight = '122'; + lockDto.compositeHash = 'AAA'; + lockDto.mosaicId = '941299B2B7E1291C'; + lockDto.ownerAddress = address.encoded(); + lockDto.status = 1; + lockDto.hashAlgorithm = LockHashAlgorithmEnum.NUMBER_0; + lockDto.recipientAddress = address.encoded(); + lockDto.secret = 'secret'; + dto.lock = lockDto; + + const url = 'http://someHost'; + const response: http.IncomingMessage = mock(); + const secretLockRoutesApi: SecretLockRoutesApi = mock(); + const secretLockRepository: SecretLockRepository = DtoMapping.assign(new SecretLockHttp(url), { + secretLockRoutesApi: instance(secretLockRoutesApi), + }); + + before(() => { + reset(response); + reset(secretLockRoutesApi); + }); + + function assertHashInfo(info: SecretLockInfo): void { + expect(info).to.be.not.null; + expect(info.amount.toString()).to.be.equal(lockDto.amount); + expect(info.recordId).to.be.equal(dto.id); + expect(info.endHeight.toString()).to.be.equal(lockDto.endHeight); + expect(info.ownerAddress.encoded()).to.be.equal(lockDto.ownerAddress); + expect(info.compositeHash).to.be.equal(lockDto.compositeHash); + expect(info.secret).to.be.equal(lockDto.secret); + expect(info.hashAlgorithm.valueOf()).to.be.equal(lockDto.hashAlgorithm.valueOf()); + expect(info.recipientAddress.encoded()).to.be.equal(lockDto.recipientAddress); + expect(info.mosaicId.toHex()).to.be.equal(lockDto.mosaicId); + expect(info.status).to.be.equal(lockDto.status); + } + + it('getSecretLockInfo', async () => { + when(secretLockRoutesApi.getSecretLock(lockDto.secret)).thenReturn(Promise.resolve(dto)); + const hashInfo = await secretLockRepository.getSecretLock(lockDto.secret).toPromise(); + assertHashInfo(hashInfo); + }); + + it('search', async () => { + const pagination = {} as Pagination; + pagination.pageNumber = 1; + pagination.pageSize = 1; + + const body = {} as SecretLockPage; + body.data = [dto]; + body.pagination = pagination; + when(secretLockRoutesApi.searchSecretLock(address.plain(), undefined, undefined, undefined, undefined)).thenReturn( + Promise.resolve(body), + ); + const infos = await secretLockRepository.search({ address }).toPromise(); + assertHashInfo(infos.data[0]); + }); + + it('getSecretLockInfo - Error', async () => { + when(secretLockRoutesApi.getSecretLock(lockDto.secret)).thenReject(new Error('Mocked Error')); + await secretLockRepository + .getSecretLock(lockDto.secret) + .toPromise() + .catch((error) => expect(error).not.to.be.undefined); + }); +}); diff --git a/test/infrastructure/SerializeTransactionToJSON.spec.ts b/test/infrastructure/SerializeTransactionToJSON.spec.ts index 64efd8c330..4fabf142ec 100644 --- a/test/infrastructure/SerializeTransactionToJSON.spec.ts +++ b/test/infrastructure/SerializeTransactionToJSON.spec.ts @@ -39,7 +39,7 @@ import { AggregateTransaction } from '../../src/model/transaction/AggregateTrans import { Deadline } from '../../src/model/transaction/Deadline'; import { LinkAction } from '../../src/model/transaction/LinkAction'; import { LockFundsTransaction } from '../../src/model/transaction/LockFundsTransaction'; -import { LockHashAlgorithm } from '../../src/model/transaction/LockHashAlgorithm'; +import { LockHashAlgorithm } from '../../src/model/lock/LockHashAlgorithm'; import { MosaicAliasTransaction } from '../../src/model/transaction/MosaicAliasTransaction'; import { MosaicDefinitionTransaction } from '../../src/model/transaction/MosaicDefinitionTransaction'; import { MosaicSupplyChangeTransaction } from '../../src/model/transaction/MosaicSupplyChangeTransaction'; diff --git a/test/infrastructure/streamer/HashLockPaginationStreamer.spec.ts b/test/infrastructure/streamer/HashLockPaginationStreamer.spec.ts new file mode 100644 index 0000000000..141e85d29f --- /dev/null +++ b/test/infrastructure/streamer/HashLockPaginationStreamer.spec.ts @@ -0,0 +1,60 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { instance, mock } from 'ts-mockito'; +import { HashLockPaginationStreamer } from '../../../src/infrastructure/paginationStreamer/HashLockPaginationStreamer'; +import { PaginationStreamerTestHelper } from './PaginationStreamerTestHelper'; +import { HashLockRepository } from '../../../src/infrastructure/HashLockRepository'; +import { Address } from '../../../src/model/account/Address'; + +describe('HashLockPaginationStreamer', () => { + const address = Address.createFromRawAddress('SATNE7Q5BITMUTRRN6IB4I7FLSDRDWZA34I2PMQ'); + + it('basicMultiPageTest', () => { + const hashLockRepositoryMock: HashLockRepository = mock(); + const streamer = new HashLockPaginationStreamer(instance(hashLockRepositoryMock)); + const tester = new PaginationStreamerTestHelper(streamer, mock(), hashLockRepositoryMock, { address }); + return tester.basicMultiPageTest(); + }); + + it('basicSinglePageTest', () => { + const hashLockRepositoryMock: HashLockRepository = mock(); + const streamer = new HashLockPaginationStreamer(instance(hashLockRepositoryMock)); + const tester = new PaginationStreamerTestHelper(streamer, mock(), hashLockRepositoryMock, { address }); + return tester.basicSinglePageTest(); + }); + + it('limitToTwoPages', () => { + const hashLockRepositoryMock: HashLockRepository = mock(); + const streamer = new HashLockPaginationStreamer(instance(hashLockRepositoryMock)); + const tester = new PaginationStreamerTestHelper(streamer, mock(), hashLockRepositoryMock, { address }); + return tester.limitToTwoPages(); + }); + + it('multipageWithLimit', () => { + const hashLockRepositoryMock: HashLockRepository = mock(); + const streamer = new HashLockPaginationStreamer(instance(hashLockRepositoryMock)); + const tester = new PaginationStreamerTestHelper(streamer, mock(), hashLockRepositoryMock, { address }); + return tester.multipageWithLimit(); + }); + + it('limitToThreePages', () => { + const hashLockRepositoryMock: HashLockRepository = mock(); + const streamer = new HashLockPaginationStreamer(instance(hashLockRepositoryMock)); + const tester = new PaginationStreamerTestHelper(streamer, mock(), hashLockRepositoryMock, { address }); + return tester.limitToThreePages(); + }); +}); diff --git a/test/infrastructure/streamer/SecretLockPaginationStreamer.spec.ts b/test/infrastructure/streamer/SecretLockPaginationStreamer.spec.ts new file mode 100644 index 0000000000..d5fb806316 --- /dev/null +++ b/test/infrastructure/streamer/SecretLockPaginationStreamer.spec.ts @@ -0,0 +1,60 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { instance, mock } from 'ts-mockito'; +import { SecretLockPaginationStreamer } from '../../../src/infrastructure/paginationStreamer/SecretLockPaginationStreamer'; +import { PaginationStreamerTestHelper } from './PaginationStreamerTestHelper'; +import { SecretLockRepository } from '../../../src/infrastructure/SecretLockRepository'; +import { Address } from '../../../src/model/account/Address'; + +describe('SecretLockPaginationStreamer', () => { + const address = Address.createFromRawAddress('SATNE7Q5BITMUTRRN6IB4I7FLSDRDWZA34I2PMQ'); + + it('basicMultiPageTest', () => { + const SecretLockRepositoryMock: SecretLockRepository = mock(); + const streamer = new SecretLockPaginationStreamer(instance(SecretLockRepositoryMock)); + const tester = new PaginationStreamerTestHelper(streamer, mock(), SecretLockRepositoryMock, { address }); + return tester.basicMultiPageTest(); + }); + + it('basicSinglePageTest', () => { + const SecretLockRepositoryMock: SecretLockRepository = mock(); + const streamer = new SecretLockPaginationStreamer(instance(SecretLockRepositoryMock)); + const tester = new PaginationStreamerTestHelper(streamer, mock(), SecretLockRepositoryMock, { address }); + return tester.basicSinglePageTest(); + }); + + it('limitToTwoPages', () => { + const SecretLockRepositoryMock: SecretLockRepository = mock(); + const streamer = new SecretLockPaginationStreamer(instance(SecretLockRepositoryMock)); + const tester = new PaginationStreamerTestHelper(streamer, mock(), SecretLockRepositoryMock, { address }); + return tester.limitToTwoPages(); + }); + + it('multipageWithLimit', () => { + const SecretLockRepositoryMock: SecretLockRepository = mock(); + const streamer = new SecretLockPaginationStreamer(instance(SecretLockRepositoryMock)); + const tester = new PaginationStreamerTestHelper(streamer, mock(), SecretLockRepositoryMock, { address }); + return tester.multipageWithLimit(); + }); + + it('limitToThreePages', () => { + const SecretLockRepositoryMock: SecretLockRepository = mock(); + const streamer = new SecretLockPaginationStreamer(instance(SecretLockRepositoryMock)); + const tester = new PaginationStreamerTestHelper(streamer, mock(), SecretLockRepositoryMock, { address }); + return tester.limitToThreePages(); + }); +}); diff --git a/test/model/lock/HashLockInfo.spec.ts b/test/model/lock/HashLockInfo.spec.ts new file mode 100644 index 0000000000..08b4e2ae82 --- /dev/null +++ b/test/model/lock/HashLockInfo.spec.ts @@ -0,0 +1,54 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { deepEqual } from 'assert'; +import { UInt64 } from '../../../src/model/UInt64'; +import { HashLockInfoDTO, HashLockEntryDTO } from 'symbol-openapi-typescript-fetch-client'; +import { MosaicId } from '../../../src/model/mosaic/MosaicId'; +import { Address } from '../../../src/model/account/Address'; +import { HashLockInfo } from '../../../src/model/lock/HashLockInfo'; + +describe('HashLockInfo', () => { + it('should createComplete an HashLockInfo object', () => { + const dto = {} as HashLockInfoDTO; + dto.id = '1'; + const lockDto = {} as HashLockEntryDTO; + lockDto.amount = '10'; + lockDto.endHeight = '122'; + lockDto.hash = 'AAA'; + lockDto.mosaicId = new MosaicId([3294802500, 2243684972]).toHex(); + lockDto.ownerAddress = Address.createFromRawAddress('SATNE7Q5BITMUTRRN6IB4I7FLSDRDWZA34I2PMQ').plain(); + lockDto.status = 1; + dto.lock = lockDto; + const info = new HashLockInfo( + dto.id, + Address.createFromRawAddress(lockDto.ownerAddress), + new MosaicId(lockDto.mosaicId), + UInt64.fromNumericString(lockDto.amount), + UInt64.fromNumericString(lockDto.endHeight), + lockDto.status, + lockDto.hash, + ); + + deepEqual(info.amount.toString(), lockDto.amount); + deepEqual(info.recordId, dto.id); + deepEqual(info.endHeight.toString(), lockDto.endHeight); + deepEqual(info.ownerAddress.plain(), lockDto.ownerAddress); + deepEqual(info.hash, lockDto.hash); + deepEqual(info.mosaicId.toHex(), lockDto.mosaicId); + deepEqual(info.status, lockDto.status); + }); +}); diff --git a/test/model/lock/SecretLockInfo.spec.ts b/test/model/lock/SecretLockInfo.spec.ts new file mode 100644 index 0000000000..50306902d8 --- /dev/null +++ b/test/model/lock/SecretLockInfo.spec.ts @@ -0,0 +1,63 @@ +/* + * Copyright 2020 NEM + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { deepEqual } from 'assert'; +import { UInt64 } from '../../../src/model/UInt64'; +import { SecretLockInfoDTO, LockHashAlgorithmEnum, SecretLockEntryDTO } from 'symbol-openapi-typescript-fetch-client'; +import { MosaicId } from '../../../src/model/mosaic/MosaicId'; +import { Address } from '../../../src/model/account/Address'; +import { SecretLockInfo } from '../../../src/model/lock/SecretLockInfo'; + +describe('SecretLockInfo', () => { + it('should createComplete an SecretLockInfo object', () => { + const dto = {} as SecretLockInfoDTO; + const lockDto = {} as SecretLockEntryDTO; + dto.id = '1'; + lockDto.amount = '10'; + lockDto.endHeight = '122'; + lockDto.compositeHash = 'AAA'; + lockDto.secret = 'AAA'; + lockDto.mosaicId = new MosaicId([3294802500, 2243684972]).toHex(); + lockDto.ownerAddress = Address.createFromRawAddress('SATNE7Q5BITMUTRRN6IB4I7FLSDRDWZA34I2PMQ').plain(); + lockDto.recipientAddress = Address.createFromRawAddress('SATNE7Q5BITMUTRRN6IB4I7FLSDRDWZA34I2PMQ').plain(); + lockDto.status = 1; + lockDto.hashAlgorithm = LockHashAlgorithmEnum.NUMBER_0; + dto.lock = lockDto; + const info = new SecretLockInfo( + dto.id, + Address.createFromRawAddress(lockDto.ownerAddress), + new MosaicId(lockDto.mosaicId), + UInt64.fromNumericString(lockDto.amount), + UInt64.fromNumericString(lockDto.endHeight), + lockDto.status, + lockDto.hashAlgorithm.valueOf(), + lockDto.secret, + Address.createFromRawAddress(lockDto.recipientAddress), + lockDto.compositeHash, + ); + + deepEqual(info.amount.toString(), lockDto.amount); + deepEqual(info.recordId, dto.id); + deepEqual(info.endHeight.toString(), lockDto.endHeight); + deepEqual(info.ownerAddress.plain(), lockDto.ownerAddress); + deepEqual(info.recipientAddress.plain(), lockDto.ownerAddress); + deepEqual(info.compositeHash, lockDto.compositeHash); + deepEqual(info.mosaicId.toHex(), lockDto.mosaicId); + deepEqual(info.status, lockDto.status); + deepEqual(info.secret, lockDto.secret); + deepEqual(info.hashAlgorithm.valueOf(), lockDto.hashAlgorithm.valueOf()); + }); +}); diff --git a/test/model/transaction/HashTypeLengthValidator.spec.ts b/test/model/transaction/HashTypeLengthValidator.spec.ts index e05ec414f2..23bdaa9822 100644 --- a/test/model/transaction/HashTypeLengthValidator.spec.ts +++ b/test/model/transaction/HashTypeLengthValidator.spec.ts @@ -15,7 +15,7 @@ */ import { expect } from 'chai'; import { sha3_256, sha3_512 } from 'js-sha3'; -import { LockHashAlgorithm, LockHashAlgorithmLengthValidator } from '../../../src/model/transaction/LockHashAlgorithm'; +import { LockHashAlgorithm, LockHashAlgorithmLengthValidator } from '../../../src/model/lock/LockHashAlgorithm'; import * as CryptoJS from 'crypto-js'; describe('LockHashAlgorithmLengthValidator', () => { diff --git a/test/model/transaction/SecretLockTransaction.spec.ts b/test/model/transaction/SecretLockTransaction.spec.ts index 51321a6d36..c39ce7c891 100644 --- a/test/model/transaction/SecretLockTransaction.spec.ts +++ b/test/model/transaction/SecretLockTransaction.spec.ts @@ -30,7 +30,7 @@ import { ResolutionStatement } from '../../../src/model/receipt/ResolutionStatem import { ResolutionType } from '../../../src/model/receipt/ResolutionType'; import { Statement } from '../../../src/model/receipt/Statement'; import { Deadline } from '../../../src/model/transaction/Deadline'; -import { LockHashAlgorithm } from '../../../src/model/transaction/LockHashAlgorithm'; +import { LockHashAlgorithm } from '../../../src/model/lock/LockHashAlgorithm'; import { SecretLockTransaction } from '../../../src/model/transaction/SecretLockTransaction'; import { TransactionInfo } from '../../../src/model/transaction/TransactionInfo'; import { UInt64 } from '../../../src/model/UInt64'; diff --git a/test/model/transaction/SecretProofTransaction.spec.ts b/test/model/transaction/SecretProofTransaction.spec.ts index 26f45c2eec..c2838b385e 100644 --- a/test/model/transaction/SecretProofTransaction.spec.ts +++ b/test/model/transaction/SecretProofTransaction.spec.ts @@ -26,7 +26,7 @@ import { ResolutionStatement } from '../../../src/model/receipt/ResolutionStatem import { ResolutionType } from '../../../src/model/receipt/ResolutionType'; import { Statement } from '../../../src/model/receipt/Statement'; import { Deadline } from '../../../src/model/transaction/Deadline'; -import { LockHashAlgorithm } from '../../../src/model/transaction/LockHashAlgorithm'; +import { LockHashAlgorithm } from '../../../src/model/lock/LockHashAlgorithm'; import { SecretProofTransaction } from '../../../src/model/transaction/SecretProofTransaction'; import { TransactionInfo } from '../../../src/model/transaction/TransactionInfo'; import { UInt64 } from '../../../src/model/UInt64';