diff --git a/CHANGELOG.md b/CHANGELOG.md index 013f6ab645..ec9ef386e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,15 @@ The changelog format is based on [Keep a Changelog](https://keepachangelog.com/e ---|---|--- SDK Core| v0.21.1 | [symbol-sdk](https://www.npmjs.com/package/symbol-sdk) Catbuffer | v0.0.22 | [catbuffer-typescript](https://www.npmjs.com/package/catbuffer-typescript) -Client Library | v0.10.0-3 | [symbol-openapi-typescript-fetch-client](https://www.npmjs.com/package/symbol-openapi-typescript-fetch-client) +Client Library | v0.10.1 | [symbol-openapi-typescript-fetch-client](https://www.npmjs.com/package/symbol-openapi-typescript-fetch-client) - **[BREAKING CHANGE]** `Deadline.create` requires the configurable `epochAdjustment` from the network properties. - **[BREAKING CHANGE]** `NetworkCurrency` subclasses replaced with `Currency` objects. +- **[BREAKING CHANGE]** `SecreatLockRepository.getSecretLock` has been removed. You can now search by secret by using the search criteria. +- Added `FinalizationRepository`. +- Added `transferMosaicId`, `fromTransferAmount`, `toTransferAmount` to transaction searches. - Added `CurrencyService` to allow loading Network and custom `Currency` objects from the rest service. +- Added `UnlockedAccount` endpoint in `NodeRepository` for checking delegated harvesting status. ## [0.21.0] - 25-Sep-2020 diff --git a/e2e/e2e-preset.yml b/e2e/e2e-preset.yml index 4dea8b63ef..80f38803d2 100644 --- a/e2e/e2e-preset.yml +++ b/e2e/e2e-preset.yml @@ -1,3 +1,4 @@ nemesis: mosaics: - accounts: 10 +symbolRestImage: symbolplatform/symbol-rest:2.1.1-alpha diff --git a/e2e/infrastructure/FinalizationHttp.spec.ts b/e2e/infrastructure/FinalizationHttp.spec.ts new file mode 100644 index 0000000000..1076bcd08b --- /dev/null +++ b/e2e/infrastructure/FinalizationHttp.spec.ts @@ -0,0 +1,58 @@ +/* + * 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 { FinalizationRepository } from '../../src/infrastructure/FinalizationRepository'; +import { UInt64 } from '../../src/model/UInt64'; +import { IntegrationTestHelper } from './IntegrationTestHelper'; + +describe('FinalizationHttp', () => { + let finalizationRepository: FinalizationRepository; + const helper = new IntegrationTestHelper(); + + before(() => { + return helper.start({ openListener: false }).then(() => { + finalizationRepository = helper.repositoryFactory.createFinalizationRepository(); + }); + }); + + after(() => { + return helper.close(); + }); + + describe('getFinalizationProofAtEpoch', () => { + it('should return finalization proof at epoch', async () => { + const dto = await finalizationRepository.getFinalizationProofAtEpoch(1).toPromise(); + expect(dto).not.to.be.null; + expect(dto.height).to.deep.eq(UInt64.fromUint(1)); + expect(dto.version).to.eq(1); + expect(dto.finalizationEpoch).to.eq(1); + expect(dto.finalizationPoint).to.eq(1); + expect(dto.hash).not.to.be.null; + }); + }); + + describe('getNetworkName', () => { + it('should return finalization proof at height', async () => { + const dto = await finalizationRepository.getFinalizationProofAtHeight(UInt64.fromUint(1)).toPromise(); + expect(dto).not.to.be.null; + expect(dto.height).to.deep.eq(UInt64.fromUint(1)); + expect(dto.version).to.eq(1); + expect(dto.finalizationEpoch).to.eq(1); + expect(dto.finalizationPoint).to.eq(1); + expect(dto.hash).not.to.be.null; + }); + }); +}); diff --git a/e2e/infrastructure/NodeHttp.spec.ts b/e2e/infrastructure/NodeHttp.spec.ts index cf485831d7..04cfc39dd8 100644 --- a/e2e/infrastructure/NodeHttp.spec.ts +++ b/e2e/infrastructure/NodeHttp.spec.ts @@ -90,4 +90,12 @@ describe('NodeHttp', () => { expect(health.db).not.to.be.null; }); }); + + describe('getUnlockedAccount', () => { + it('should return unlocked account', async () => { + const unlockedAccount = await nodeRepository.getUnlockedAccount().toPromise(); + expect(unlockedAccount).not.to.be.null; + expect(unlockedAccount.length).greaterThan(0); + }); + }); }); diff --git a/e2e/infrastructure/SecretLockHttp.spec.ts b/e2e/infrastructure/SecretLockHttp.spec.ts index 3c5e5889fd..4e5d70c1c1 100644 --- a/e2e/infrastructure/SecretLockHttp.spec.ts +++ b/e2e/infrastructure/SecretLockHttp.spec.ts @@ -82,10 +82,15 @@ describe('SecretLockHttp', () => { * ========================= */ - describe('getSecretLock', () => { + describe('searchSecretLock using secret', () => { it('should return hash lock info given hash', async () => { await new Promise((resolve) => setTimeout(resolve, 3000)); - const info = await SecretLockRepo.getSecretLock(secret).toPromise(); + + const page = await SecretLockRepo.search({ address: account.address, secret }).toPromise(); + expect(page.data.length).eq(1); + expect(page.pageNumber).eq(1); + + const info = page.data[0]; 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('10'); @@ -106,7 +111,12 @@ describe('SecretLockHttp', () => { .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(); + const info = await SecretLockRepo.search({ + address: account.address, + secret: undefined, + pageSize: 20, + order: Order.Asc, + }).toPromise(); expect(infoStreamer.length).to.be.greaterThan(0); deepEqual(infoStreamer[0], info.data[0]); }); diff --git a/e2e/infrastructure/TransactionSearch.spec.ts b/e2e/infrastructure/TransactionSearch.spec.ts new file mode 100644 index 0000000000..c76463f220 --- /dev/null +++ b/e2e/infrastructure/TransactionSearch.spec.ts @@ -0,0 +1,229 @@ +/* + * 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 { expect } from 'chai'; +import { first, take, toArray } from 'rxjs/operators'; +import { TransactionPaginationStreamer } from '../../src/infrastructure/paginationStreamer/TransactionPaginationStreamer'; +import { TransactionSearchCriteria } from '../../src/infrastructure/searchCriteria/TransactionSearchCriteria'; +import { TransactionGroup } from '../../src/infrastructure/TransactionGroup'; +import { TransactionType } from '../../src/model/transaction/TransactionType'; +import { TransferTransaction } from '../../src/model/transaction/TransferTransaction'; +import { UInt64 } from '../../src/model/UInt64'; +import { IntegrationTestHelper } from './IntegrationTestHelper'; + +describe('TransactionSearch', () => { + const helper = new IntegrationTestHelper(); + + before(() => { + return helper.start({ openListener: false }); + }); + + after(() => { + return helper.close(); + }); + + describe('searchTransactions', () => { + it('should return transaction info given address', async () => { + const transactionRepository = helper.repositoryFactory.createTransactionRepository(); + const account = helper.account; + const transactions = await transactionRepository + .search({ group: TransactionGroup.Confirmed, address: account.address } as TransactionSearchCriteria) + .toPromise(); + expect(transactions.data.length).to.be.greaterThan(0); + }); + it('should return transaction info given height all types', async () => { + const transactionRepository = helper.repositoryFactory.createTransactionRepository(); + const transactions = await transactionRepository + .search({ group: TransactionGroup.Confirmed, height: UInt64.fromUint(1) } as TransactionSearchCriteria) + .toPromise(); + + const mosaicDefinitions = transactions.data.filter((t) => t.type == TransactionType.MOSAIC_DEFINITION).length; + const namespaceRegistration = transactions.data.filter((t) => t.type == TransactionType.NAMESPACE_REGISTRATION).length; + const others = transactions.data.filter( + (t) => t.type !== TransactionType.NAMESPACE_REGISTRATION && t.type !== TransactionType.MOSAIC_DEFINITION, + ).length; + expect(mosaicDefinitions).to.be.greaterThan(0); + expect(namespaceRegistration).to.be.greaterThan(0); + expect(others).to.be.greaterThan(0); + }); + + it('should return transaction info given height and namesapce, mosaic types', async () => { + const transactionRepository = helper.repositoryFactory.createTransactionRepository(); + const transactions = await transactionRepository + .search({ + group: TransactionGroup.Confirmed, + height: UInt64.fromUint(1), + type: [TransactionType.MOSAIC_DEFINITION, TransactionType.NAMESPACE_REGISTRATION], + } as TransactionSearchCriteria) + .toPromise(); + const mosaicDefinitions = transactions.data.filter((t) => t.type == TransactionType.MOSAIC_DEFINITION).length; + const namespaceRegistration = transactions.data.filter((t) => t.type == TransactionType.NAMESPACE_REGISTRATION).length; + const others = transactions.data.filter( + (t) => t.type !== TransactionType.NAMESPACE_REGISTRATION && t.type !== TransactionType.MOSAIC_DEFINITION, + ).length; + expect(mosaicDefinitions).to.be.greaterThan(0); + expect(namespaceRegistration).to.be.greaterThan(0); + expect(others).to.eq(0); + }); + }); + + describe('searchTransactions using steamer', () => { + it('should return transaction info given address', async () => { + const transactionRepository = helper.repositoryFactory.createTransactionRepository(); + const streamer = new TransactionPaginationStreamer(transactionRepository); + const account = helper.account; + const transactionsNoStreamer = await transactionRepository + .search({ group: TransactionGroup.Confirmed, address: account.address, pageSize: 10 } as TransactionSearchCriteria) + .toPromise(); + const transactions = await streamer + .search({ group: TransactionGroup.Confirmed, address: account.address, pageSize: 10 }) + .pipe(take(10), toArray()) + .toPromise(); + expect(transactions.length).to.be.greaterThan(0); + deepEqual(transactionsNoStreamer.data, transactions); + }); + + it('should return transaction info given mosaic id', async () => { + const transactionRepository = helper.repositoryFactory.createTransactionRepository(); + const streamer = new TransactionPaginationStreamer(transactionRepository); + + const transferTransaction = (await streamer + .search({ + embedded: true, + group: TransactionGroup.Confirmed, + type: [TransactionType.TRANSFER], + }) + .pipe(first()) + .toPromise()) as TransferTransaction; + const mosaicId = transferTransaction.mosaics[0].id; + + const criteria: TransactionSearchCriteria = { + group: TransactionGroup.Confirmed, + pageSize: 10, + embedded: true, + transferMosaicId: mosaicId, + }; + + const transactions = await streamer.search(criteria).pipe(toArray()).toPromise(); + expect(transactions.length).to.be.greaterThan(0); + + transactions.forEach((t) => { + const mosaicIds = (t as TransferTransaction).mosaics.map((m) => m.id.toHex()); + expect(mosaicIds.indexOf(mosaicId.toHex())).to.be.greaterThan(-1); + }); + }); + + it('should return transaction info given mosaic id and from/to amount', async () => { + const transactionRepository = helper.repositoryFactory.createTransactionRepository(); + const streamer = new TransactionPaginationStreamer(transactionRepository); + + const transferTransaction = (await streamer + .search({ + embedded: true, + group: TransactionGroup.Confirmed, + type: [TransactionType.TRANSFER], + }) + .pipe(first()) + .toPromise()) as TransferTransaction; + const mosaic = transferTransaction.mosaics[0]; + const mosaicId = mosaic.id; + + const criteria: TransactionSearchCriteria = { + group: TransactionGroup.Confirmed, + fromTransferAmount: mosaic.amount, + toTransferAmount: mosaic.amount, + pageSize: 10, + embedded: true, + transferMosaicId: mosaicId, + }; + + const transactions = await streamer.search(criteria).pipe(toArray()).toPromise(); + expect(transactions.length).to.be.greaterThan(0); + + transactions.forEach((t) => { + const thisTransactionMosaic = (t as TransferTransaction).mosaics.filter((m) => m.id.equals(mosaicId))[0]; + expect(thisTransactionMosaic.id).deep.eq(mosaicId); + expect(thisTransactionMosaic.amount).deep.eq(mosaic.amount); + }); + }); + + it('should return transaction info given mosaic id and from amount', async () => { + const transactionRepository = helper.repositoryFactory.createTransactionRepository(); + const streamer = new TransactionPaginationStreamer(transactionRepository); + + const transferTransaction = (await streamer + .search({ + embedded: true, + group: TransactionGroup.Confirmed, + type: [TransactionType.TRANSFER], + }) + .pipe(first()) + .toPromise()) as TransferTransaction; + const mosaic = transferTransaction.mosaics[0]; + const mosaicId = mosaic.id; + + const criteria: TransactionSearchCriteria = { + group: TransactionGroup.Confirmed, + fromTransferAmount: mosaic.amount, + pageSize: 10, + embedded: true, + transferMosaicId: mosaicId, + }; + + const transactions = await streamer.search(criteria).pipe(toArray()).toPromise(); + expect(transactions.length).to.be.greaterThan(0); + + transactions.forEach((t) => { + const thisTransactionMosaic = (t as TransferTransaction).mosaics.filter((m) => m.id.equals(mosaicId))[0]; + expect(thisTransactionMosaic.id).deep.eq(mosaicId); + expect(thisTransactionMosaic.amount.compare(mosaic.amount)).to.be.greaterThan(-1); + }); + }); + + it('should return transaction info given mosaic id and to amount', async () => { + const transactionRepository = helper.repositoryFactory.createTransactionRepository(); + const streamer = new TransactionPaginationStreamer(transactionRepository); + + const transferTransaction = (await streamer + .search({ + embedded: true, + group: TransactionGroup.Confirmed, + type: [TransactionType.TRANSFER], + }) + .pipe(first()) + .toPromise()) as TransferTransaction; + const mosaic = transferTransaction.mosaics[0]; + const mosaicId = mosaic.id; + + const criteria: TransactionSearchCriteria = { + group: TransactionGroup.Confirmed, + toTransferAmount: mosaic.amount, + pageSize: 10, + embedded: true, + transferMosaicId: mosaicId, + }; + + const transactions = await streamer.search(criteria).pipe(toArray()).toPromise(); + expect(transactions.length).to.be.greaterThan(0); + + transactions.forEach((t) => { + const thisTransactionMosaic = (t as TransferTransaction).mosaics.filter((m) => m.id.equals(mosaicId))[0]; + expect(thisTransactionMosaic.id).deep.eq(mosaicId); + expect(thisTransactionMosaic.amount.compare(mosaic.amount)).to.be.lessThan(1); + }); + }); + }); +}); diff --git a/package-lock.json b/package-lock.json index 4c8b0c1042..088665e790 100644 --- a/package-lock.json +++ b/package-lock.json @@ -395,6 +395,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, "requires": { "@nodelib/fs.stat": "2.0.3", "run-parallel": "^1.1.9" @@ -403,12 +404,14 @@ "@nodelib/fs.stat": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==" + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true }, "@nodelib/fs.walk": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.3", "fastq": "^1.6.0" @@ -694,15 +697,6 @@ "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", "dev": true }, - "@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, "@types/json-schema": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", @@ -721,11 +715,6 @@ "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", "dev": true }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" - }, "@types/mocha": { "version": "2.2.48", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.48.tgz", @@ -735,7 +724,8 @@ "@types/node": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.0.tgz", - "integrity": "sha512-h3YZbOq2+ZoDFI1z8Zx0Ck/xRWkOESVaLdgLdd/c25mMQ1Y2CAkILu9ny5A15S5f32gGcQdaUIZ2jzYr8D7IFg==" + "integrity": "sha512-h3YZbOq2+ZoDFI1z8Zx0Ck/xRWkOESVaLdgLdd/c25mMQ1Y2CAkILu9ny5A15S5f32gGcQdaUIZ2jzYr8D7IFg==", + "dev": true }, "@types/ripemd160": { "version": "2.0.0", @@ -932,6 +922,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -1096,7 +1087,8 @@ "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true }, "array-unique": { "version": "0.3.2", @@ -1247,7 +1239,8 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "base": { "version": "0.11.2", @@ -1336,6 +1329,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1635,6 +1629,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, "requires": { "color-name": "^1.1.1" } @@ -1642,7 +1637,8 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "color-string": { "version": "1.5.4", @@ -1706,7 +1702,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "concat-stream": { "version": "1.6.2", @@ -2031,7 +2028,8 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true }, "decode-uri-component": { "version": "0.2.0", @@ -2170,6 +2168,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, "requires": { "path-type": "^4.0.0" }, @@ -2177,7 +2176,8 @@ "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true } } }, @@ -2851,6 +2851,7 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -2864,6 +2865,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -2872,6 +2874,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -2880,6 +2883,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -2887,12 +2891,14 @@ "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" @@ -2902,6 +2908,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "requires": { "is-number": "^7.0.0" } @@ -2930,6 +2937,7 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, "requires": { "reusify": "^1.0.4" } @@ -3204,7 +3212,8 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "fsevents": { "version": "1.2.9", @@ -3822,11 +3831,6 @@ "assert-plus": "^1.0.0" } }, - "gitignore-to-glob": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/gitignore-to-glob/-/gitignore-to-glob-0.3.0.tgz", - "integrity": "sha1-WfMqs9m2bOUCmcPtJMsO9CoJTOs=" - }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", @@ -4281,6 +4285,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -4535,7 +4540,8 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", @@ -4550,6 +4556,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -5027,201 +5034,6 @@ "type-check": "~0.3.2" } }, - "license-check-and-add": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/license-check-and-add/-/license-check-and-add-3.0.4.tgz", - "integrity": "sha512-j3dotPJECxJRdvfkXxxDJqlKoRyKoR0G1woG1TiuqHAHG2/EjByRQZNcaDZ0GCY6/zBhrkoPC/gZHz0vsQtAsQ==", - "requires": { - "fs-extra": "^8.1.0", - "gitignore-to-glob": "^0.3.0", - "globby": "^10.0.1", - "ignore": "^5.1.2", - "yargs": "^13.3.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - } - } - }, "liftoff": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", @@ -5503,7 +5315,8 @@ "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true }, "merkle-lib": { "version": "2.0.10", @@ -5580,6 +5393,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -6345,7 +6159,7 @@ }, "which-module": { "version": "2.0.0", - "resolved": false, + "resolved": "", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, @@ -6516,6 +6330,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } @@ -6586,6 +6401,7 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, "requires": { "p-try": "^2.0.0" } @@ -6611,7 +6427,8 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true }, "package-hash": { "version": "4.0.0", @@ -6690,7 +6507,8 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-key": { "version": "3.1.1", @@ -6745,7 +6563,8 @@ "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true }, "pify": { "version": "2.3.0", @@ -7172,7 +6991,8 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true }, "require-main-filename": { "version": "1.0.1", @@ -7239,7 +7059,8 @@ "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true }, "rimraf": { "version": "3.0.2", @@ -7287,7 +7108,8 @@ "run-parallel": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==" + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true }, "rxjs": { "version": "6.6.3", @@ -7355,7 +7177,8 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true }, "set-value": { "version": "2.0.1", @@ -7443,7 +7266,8 @@ "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true }, "slice-ansi": { "version": "2.1.0", @@ -7901,6 +7725,12 @@ "esprima": "^4.0.0" } }, + "node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "dev": true + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -7910,9 +7740,9 @@ } }, "symbol-openapi-typescript-fetch-client": { - "version": "0.10.0-3", - "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-0.10.0-3.tgz", - "integrity": "sha512-cdRz7Nc/m2i7CC8wHtj//z5RxOKEKhS4l+fFQvh7YUlYcUPaHbgcq4RMXSZPmMJ4PnzocnqWpVKjMj5cTYgrPA==" + "version": "0.10.1-SNAPSHOT.202011061706", + "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-0.10.1-SNAPSHOT.202011061706.tgz", + "integrity": "sha512-nYIlHgjbkLGBEPuLrQlT/NFVmZ4ByAM7RIP1c48hs815tB0ecwwXSBDn3fX/BR03AGVV+y7hbQooLEiKVFMh9g==" }, "symbol-sdk": { "version": "0.21.0", @@ -7971,6 +7801,12 @@ } } }, + "symbol-openapi-typescript-fetch-client": { + "version": "0.10.0-3", + "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-0.10.0-3.tgz", + "integrity": "sha512-cdRz7Nc/m2i7CC8wHtj//z5RxOKEKhS4l+fFQvh7YUlYcUPaHbgcq4RMXSZPmMJ4PnzocnqWpVKjMj5cTYgrPA==", + "dev": true + }, "utf8": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", @@ -8760,7 +8596,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "write": { "version": "1.0.3", @@ -8838,22 +8675,6 @@ } } }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - } - } - }, "yargs-unparser": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.1.tgz", diff --git a/package.json b/package.json index a85e04e2c2..1629d909d9 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "create-index-files": "cti create ./src -b -n", "doc": "typedoc --out \"ts-docs/$(npm run version --silent)\" src", "bootstrap-clean": "symbol-bootstrap clean -t target/bootstrap-test", - "bootstrap-start-detached": "symbol-bootstrap start -r -c ./e2e/e2e-preset.yml -t target/bootstrap-test -d --healthCheck", - "bootstrap-start": "symbol-bootstrap start -r -c ./e2e/e2e-preset.yml -t target/bootstrap-test", + "bootstrap-start-detached": "symbol-bootstrap start -r -c ./e2e/e2e-preset.yml -t target/bootstrap-test --timeout 120000 -d --healthCheck", + "bootstrap-start": "symbol-bootstrap start -r -c ./e2e/e2e-preset.yml --timeout 120000 -t target/bootstrap-test", "bootstrap-stop": "symbol-bootstrap stop -t target/bootstrap-test", "bootstrap-run": "symbol-bootstrap run -t target/bootstrap-test", "bootstrap-compose": "symbol-bootstrap compose -t target/bootstrap-test", @@ -111,7 +111,7 @@ "ripemd160": "^2.0.2", "rxjs": "^6.6.3", "rxjs-compat": "^6.6.3", - "symbol-openapi-typescript-fetch-client": "0.10.0-3", + "symbol-openapi-typescript-fetch-client": "0.10.1-SNAPSHOT.202011061706", "tweetnacl": "^1.0.3", "ws": "^7.3.1" }, diff --git a/src/infrastructure/FinalizationHttp.ts b/src/infrastructure/FinalizationHttp.ts new file mode 100644 index 0000000000..da9768dc7e --- /dev/null +++ b/src/infrastructure/FinalizationHttp.ts @@ -0,0 +1,101 @@ +/* + * Copyright 2019 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 { FinalizationProofDTO, FinalizationRoutesApi } from 'symbol-openapi-typescript-fetch-client'; +import { FinalizationProof } from '../model/finalization/FinalizationProof'; +import { UInt64 } from '../model/UInt64'; +import { FinalizationRepository } from './FinalizationRepository'; +import { Http } from './Http'; +import { MessageGroup } from '../model/finalization/MessageGroup'; +import { BmTreeSignature } from '../model/finalization/BmTreeSignature'; +import { ParentPublicKeySignaturePair } from '../model/finalization/ParentPublicKeySignaturePair'; + +/** + * Chian http repository. + * + * @since 1.0 + */ +export class FinalizationHttp extends Http implements FinalizationRepository { + /** + * @internal + * Symbol openapi typescript-node client Finalization routes api + */ + private finalizationRoutesApi: FinalizationRoutesApi; + + /** + * 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.finalizationRoutesApi = new FinalizationRoutesApi(this.config()); + } + + /** + * Gets finalization proof for the greatest height associated with the given epoch. + * @param epoch Finalization epoch + * @returns Observable + */ + public getFinalizationProofAtEpoch(epoch: number): Observable { + return this.call(this.finalizationRoutesApi.getFinalizationProofAtEpoch(epoch), (body) => this.toFinalizationProof(body)); + } + + /** + * Gets finalization proof at the given height. + * @param height Block height + * @returns Observable + */ + public getFinalizationProofAtHeight(height: UInt64): Observable { + return this.call(this.finalizationRoutesApi.getFinalizationProofAtHeight(height.toString()), (body) => + this.toFinalizationProof(body), + ); + } + + /** + * This method maps a FinalizationProofDTO from rest to the SDK's FinalizationProof model object. + * + * @internal + * @param {FinalizationProofDTO} dto FinalizationProofDTO the dto object from rest. + * @returns FinalizationProof model + */ + private toFinalizationProof(dto: FinalizationProofDTO): FinalizationProof { + return new FinalizationProof( + dto.version, + dto.finalizationEpoch, + dto.finalizationPoint, + UInt64.fromNumericString(dto.height), + dto.hash, + dto.messageGroups.map( + (mg) => + new MessageGroup( + mg.stage.valueOf(), + UInt64.fromNumericString(mg.height), + mg.hashes, + mg.signatures.map( + (s) => + new BmTreeSignature( + new ParentPublicKeySignaturePair(s.root.parentPublicKey, s.root.signature), + new ParentPublicKeySignaturePair(s.top.parentPublicKey, s.top.signature), + new ParentPublicKeySignaturePair(s.bottom.parentPublicKey, s.bottom.signature), + ), + ), + ), + ), + ); + } +} diff --git a/src/infrastructure/FinalizationRepository.ts b/src/infrastructure/FinalizationRepository.ts new file mode 100644 index 0000000000..41a044c3b6 --- /dev/null +++ b/src/infrastructure/FinalizationRepository.ts @@ -0,0 +1,40 @@ +/* + * Copyright 2019 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 { FinalizationProof } from '../model/finalization/FinalizationProof'; +import { UInt64 } from '../model/UInt64'; + +/** + * Finalization interface repository. + * + * @since 1.0 + */ +export interface FinalizationRepository { + /** + * Gets finalization proof for the greatest height associated with the given epoch. + * @param epoch Finalization epoch + * @returns Observable + */ + getFinalizationProofAtEpoch(epoch: number): Observable; + + /** + * Gets finalization proof at the given height. + * @param height Block height + * @returns Observable + */ + getFinalizationProofAtHeight(height: UInt64): Observable; +} diff --git a/src/infrastructure/NamespaceHttp.ts b/src/infrastructure/NamespaceHttp.ts index 6f44b72936..60672af5e8 100644 --- a/src/infrastructure/NamespaceHttp.ts +++ b/src/infrastructure/NamespaceHttp.ts @@ -227,7 +227,7 @@ export class NamespaceHttp extends Http implements NamespaceRepository { return new NamespaceInfo( dto.meta.active, dto.meta.index, - dto.meta.id, + dto.id, dto.namespace.registrationType as number, dto.namespace.depth, NamespaceHttp.extractLevels(dto.namespace), diff --git a/src/infrastructure/NodeHttp.ts b/src/infrastructure/NodeHttp.ts index 80ebc7aa29..55f26a248b 100644 --- a/src/infrastructure/NodeHttp.ts +++ b/src/infrastructure/NodeHttp.ts @@ -111,6 +111,14 @@ export class NodeHttp extends Http implements NodeRepository { return this.call(this.nodeRoutesApi.getNodeHealth(), (body) => new NodeHealth(body.status.apiNode, body.status.db)); } + /** + * Return unlocked harvesting account from node. + * @returns Observable + */ + getUnlockedAccount(): Observable { + return this.call(this.nodeRoutesApi.getUnlockedAccount(), (body) => body); + } + /** * It maps NodeInfoDTO to NodeInfo * diff --git a/src/infrastructure/NodeRepository.ts b/src/infrastructure/NodeRepository.ts index b39ffeb705..35ec537441 100644 --- a/src/infrastructure/NodeRepository.ts +++ b/src/infrastructure/NodeRepository.ts @@ -63,4 +63,10 @@ export interface NodeRepository { * @returns Observable */ getServerInfo(): Observable; + + /** + * Return unlocked harvesting account from node. + * @returns Observable + */ + getUnlockedAccount(): Observable; } diff --git a/src/infrastructure/RepositoryFactory.ts b/src/infrastructure/RepositoryFactory.ts index 7a936d7311..d3dcc09736 100644 --- a/src/infrastructure/RepositoryFactory.ts +++ b/src/infrastructure/RepositoryFactory.ts @@ -34,6 +34,7 @@ import { TransactionRepository } from './TransactionRepository'; import { TransactionStatusRepository } from './TransactionStatusRepository'; import { HashLockRepository } from './HashLockRepository'; import { SecretLockRepository } from './SecretLockRepository'; +import { FinalizationRepository } from './FinalizationRepository'; /** * A repository factory allows clients to create repositories to access NEM Server without knowing @@ -133,6 +134,11 @@ export interface RepositoryFactory { */ createSecretLockRepository(): SecretLockRepository; + /** + * @returns a newly created {@link FinalizationRepository} + */ + createFinalizationRepository(): FinalizationRepository; + /** * @returns a newly created {@link IListener} */ diff --git a/src/infrastructure/RepositoryFactoryHttp.ts b/src/infrastructure/RepositoryFactoryHttp.ts index ab4f215ef3..fa8e7d2e1f 100644 --- a/src/infrastructure/RepositoryFactoryHttp.ts +++ b/src/infrastructure/RepositoryFactoryHttp.ts @@ -57,6 +57,8 @@ import { SecretLockRepository } from './SecretLockRepository'; import { SecretLockHttp } from './SecretLockHttp'; import { HashLockHttp } from './HashLockHttp'; import { DtoMapping } from '../core/utils/DtoMapping'; +import { FinalizationHttp } from './FinalizationHttp'; +import { FinalizationRepository } from './FinalizationRepository'; /** * Receipt http repository. * @@ -173,6 +175,10 @@ export class RepositoryFactoryHttp implements RepositoryFactory { return new SecretLockHttp(this.url, this.fetchApi); } + createFinalizationRepository(): FinalizationRepository { + return new FinalizationHttp(this.url, this.fetchApi); + } + getGenerationHash(): Observable { return this.generationHash; } diff --git a/src/infrastructure/SecretLockHttp.ts b/src/infrastructure/SecretLockHttp.ts index ad6e0471a3..1498f5d446 100644 --- a/src/infrastructure/SecretLockHttp.ts +++ b/src/infrastructure/SecretLockHttp.ts @@ -48,15 +48,6 @@ export class SecretLockHttp extends Http implements SecretLockRepository { 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 @@ -66,6 +57,7 @@ export class SecretLockHttp extends Http implements SecretLockRepository { return this.call( this.secretLockRoutesApi.searchSecretLock( criteria.address.plain(), + criteria.secret, criteria.pageSize, criteria.pageNumber, criteria.offset, diff --git a/src/infrastructure/SecretLockRepository.ts b/src/infrastructure/SecretLockRepository.ts index f063b97479..578dff6233 100644 --- a/src/infrastructure/SecretLockRepository.ts +++ b/src/infrastructure/SecretLockRepository.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { Observable } from 'rxjs'; import { Searcher } from './paginationStreamer/Searcher'; import { SecretLockInfo } from '../model/lock/SecretLockInfo'; import { SecretLockSearchCriteria } from './searchCriteria/SecretLockSearchCriteria'; @@ -22,11 +21,4 @@ import { SecretLockSearchCriteria } from './searchCriteria/SecretLockSearchCrite /** * 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; -} +export type SecretLockRepository = Searcher; diff --git a/src/infrastructure/TransactionHttp.ts b/src/infrastructure/TransactionHttp.ts index 66027a47f5..e928819593 100644 --- a/src/infrastructure/TransactionHttp.ts +++ b/src/infrastructure/TransactionHttp.ts @@ -226,8 +226,11 @@ export class TransactionHttp extends Http implements TransactionRepository { criteria.height?.toString(), criteria.fromHeight?.toString(), criteria.toHeight?.toString(), + criteria.fromTransferAmount?.toString(), + criteria.toTransferAmount?.toString(), criteria.type?.map((type) => type.valueOf()), criteria.embedded, + criteria.transferMosaicId?.toHex(), criteria.pageSize, criteria.pageNumber, criteria.offset, @@ -241,8 +244,11 @@ export class TransactionHttp extends Http implements TransactionRepository { criteria.height?.toString(), criteria.fromHeight?.toString(), criteria.toHeight?.toString(), + criteria.fromTransferAmount?.toString(), + criteria.toTransferAmount?.toString(), criteria.type?.map((type) => type.valueOf()), criteria.embedded, + criteria.transferMosaicId?.toHex(), criteria.pageSize, criteria.pageNumber, criteria.offset, @@ -256,8 +262,11 @@ export class TransactionHttp extends Http implements TransactionRepository { criteria.height?.toString(), criteria.fromHeight?.toString(), criteria.toHeight?.toString(), + criteria.fromTransferAmount?.toString(), + criteria.toTransferAmount?.toString(), criteria.type?.map((type) => type.valueOf()), criteria.embedded, + criteria.transferMosaicId?.toHex(), criteria.pageSize, criteria.pageNumber, criteria.offset, diff --git a/src/infrastructure/paginationStreamer/PaginationStreamer.ts b/src/infrastructure/paginationStreamer/PaginationStreamer.ts index 0e6745b863..c5d0ddc3ac 100644 --- a/src/infrastructure/paginationStreamer/PaginationStreamer.ts +++ b/src/infrastructure/paginationStreamer/PaginationStreamer.ts @@ -18,7 +18,7 @@ import { concat } from 'rxjs'; import { Observable } from 'rxjs/internal/Observable'; import { defer } from 'rxjs/internal/observable/defer'; import { from } from 'rxjs/internal/observable/from'; -import { flatMap } from 'rxjs/operators'; +import { mergeMap } from 'rxjs/operators'; import { SearchCriteria } from '../searchCriteria/SearchCriteria'; import { Searcher } from './Searcher'; @@ -55,7 +55,7 @@ export class PaginationStreamer { return defer(() => { const observable = this.searcher.search(criteria); return observable.pipe( - flatMap((page) => { + mergeMap((page) => { if (page.isLastPage) { return from(page.data); } else { diff --git a/src/infrastructure/searchCriteria/SecretLockSearchCriteria.ts b/src/infrastructure/searchCriteria/SecretLockSearchCriteria.ts index cf7cabf811..20e401cc41 100644 --- a/src/infrastructure/searchCriteria/SecretLockSearchCriteria.ts +++ b/src/infrastructure/searchCriteria/SecretLockSearchCriteria.ts @@ -25,4 +25,9 @@ export interface SecretLockSearchCriteria extends SearchCriteria { * The owner address. (required) */ address: Address; + + /** + * Optional to search by secret. + */ + secret?: string; } diff --git a/src/infrastructure/searchCriteria/TransactionSearchCriteria.ts b/src/infrastructure/searchCriteria/TransactionSearchCriteria.ts index 80f2f77a5a..b112c94df8 100644 --- a/src/infrastructure/searchCriteria/TransactionSearchCriteria.ts +++ b/src/infrastructure/searchCriteria/TransactionSearchCriteria.ts @@ -15,6 +15,7 @@ */ import { Address } from '../../model/account/Address'; +import { MosaicId } from '../../model/mosaic/MosaicId'; import { TransactionType } from '../../model/transaction/TransactionType'; import { UInt64 } from '../../model/UInt64'; import { TransactionGroup } from '../TransactionGroup'; @@ -68,13 +69,29 @@ export interface TransactionSearchCriteria extends SearchCriteria { */ embedded?: boolean; - /* + /** * Only blocks with height greater or equal than this one are returned. */ fromHeight?: UInt64; - /* + /** * Only blocks with height smaller or equal than this one are returned. */ toHeight?: UInt64; + + /** + * Filters transactions involving a specific `mosaicId` hex. + */ + transferMosaicId?: MosaicId; + + /** + * Requires providing the `transferMosaicId` filter. + * Only transfer transactions with a transfer amount of the provided mosaic id, greater or equal than this amount are returned. + */ + fromTransferAmount?: UInt64; + + /** + * Requires providing the `transferMosaicId` filter. Only transfer transactions with a transfer amount of the provided mosaic id, lesser or equal than this amount are returned. + */ + toTransferAmount?: UInt64; } diff --git a/src/model/finalization/BmTreeSignature.ts b/src/model/finalization/BmTreeSignature.ts new file mode 100644 index 0000000000..eefd7cffdb --- /dev/null +++ b/src/model/finalization/BmTreeSignature.ts @@ -0,0 +1,37 @@ +/* + * 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 { ParentPublicKeySignaturePair } from './ParentPublicKeySignaturePair'; + +/** + * BM Tree signature + */ +export class BmTreeSignature { + constructor( + /** + * Root. + */ + public readonly root: ParentPublicKeySignaturePair, + /** + * Top. + */ + public readonly top: ParentPublicKeySignaturePair, + /** + * Bottom. + */ + public readonly bottom: ParentPublicKeySignaturePair, + ) {} +} diff --git a/src/model/finalization/FinalizationProof.ts b/src/model/finalization/FinalizationProof.ts new file mode 100644 index 0000000000..4d37146b93 --- /dev/null +++ b/src/model/finalization/FinalizationProof.ts @@ -0,0 +1,50 @@ +/* + * 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 { UInt64 } from '../UInt64'; +import { MessageGroup } from './MessageGroup'; + +/** + * Finalization proof + */ +export class FinalizationProof { + constructor( + /** + * Version. + */ + public readonly version: number, + /** + * Finalization epoch. + */ + public readonly finalizationEpoch: number, + /** + * Finalization point. + */ + public readonly finalizationPoint: number, + /** + * Finalization height. + */ + public readonly height: UInt64, + /** + * Hash. + */ + public readonly hash: string, + /** + * Message groups. + */ + public readonly messageGroups: MessageGroup[], + ) {} +} diff --git a/src/model/finalization/MessageGroup.ts b/src/model/finalization/MessageGroup.ts new file mode 100644 index 0000000000..b1edf20e85 --- /dev/null +++ b/src/model/finalization/MessageGroup.ts @@ -0,0 +1,42 @@ +/* + * 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 { UInt64 } from '../UInt64'; +import { BmTreeSignature } from './BmTreeSignature'; + +/** + * Finalization message group + */ +export class MessageGroup { + constructor( + /** + * Stage. + */ + public readonly stage: number, + /** + * Height. + */ + public readonly height: UInt64, + /** + * Hashes. + */ + public readonly hashes: string[], + /** + * Signatures. + */ + public readonly signatures: BmTreeSignature[], + ) {} +} diff --git a/src/model/finalization/ParentPublicKeySignaturePair.ts b/src/model/finalization/ParentPublicKeySignaturePair.ts new file mode 100644 index 0000000000..c3cd2452b5 --- /dev/null +++ b/src/model/finalization/ParentPublicKeySignaturePair.ts @@ -0,0 +1,31 @@ +/* + * 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. + */ + +/** + * Parent publickey signature pair + */ +export class ParentPublicKeySignaturePair { + constructor( + /** + * Parent public key. + */ + public readonly parentPublicKey: string, + /** + * Signature. + */ + public readonly signature: string, + ) {} +} diff --git a/src/model/finalization/Stage.ts b/src/model/finalization/Stage.ts new file mode 100644 index 0000000000..fd435d1845 --- /dev/null +++ b/src/model/finalization/Stage.ts @@ -0,0 +1,25 @@ +/* + * 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. + */ + +/** + * Message group stage enum + */ + +export enum Stage { + Prevote = 0, + Precommit = 1, + Count = 2, +} diff --git a/test/infrastructure/FinalizationHttp.spec.ts b/test/infrastructure/FinalizationHttp.spec.ts new file mode 100644 index 0000000000..9a302b4584 --- /dev/null +++ b/test/infrastructure/FinalizationHttp.spec.ts @@ -0,0 +1,109 @@ +/* + * 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 { + FinalizationRoutesApi, + MessageGroup, + StageEnum, + ParentPublicKeySignaturePair, + BmTreeSignature, +} from 'symbol-openapi-typescript-fetch-client'; +import { instance, mock, reset, when } from 'ts-mockito'; +import { DtoMapping } from '../../src/core/utils/DtoMapping'; +import { FinalizationProofDTO } from 'symbol-openapi-typescript-fetch-client'; +import { FinalizationProof } from '../../src/model/finalization/FinalizationProof'; +import { deepEqual } from 'assert'; +import { FinalizationHttp } from '../../src/infrastructure/FinalizationHttp'; +import { UInt64 } from '../../src/model/UInt64'; + +describe('FinalizationHttp', () => { + const url = 'http://someHost'; + const response: http.IncomingMessage = mock(); + const finalizationRoutesApi: FinalizationRoutesApi = mock(); + const finalizationRepository = DtoMapping.assign(new FinalizationHttp(url), { finalizationRoutesApi: instance(finalizationRoutesApi) }); + + const dto = {} as FinalizationProofDTO; + dto.finalizationEpoch = 1; + dto.finalizationPoint = 1; + dto.hash = 'proofhash'; + dto.height = '1'; + dto.version = 1; + + const mg = {} as MessageGroup; + mg.hashes = ['mghash']; + mg.height = '1'; + mg.stage = StageEnum.NUMBER_0; + + const ps = {} as ParentPublicKeySignaturePair; + ps.parentPublicKey = 'pubKey'; + ps.signature = 'signature'; + + const tree = {} as BmTreeSignature; + tree.bottom = ps; + tree.top = ps; + tree.root = ps; + + mg.signatures = [tree]; + dto.messageGroups = [mg]; + + before(() => { + reset(response); + reset(finalizationRoutesApi); + }); + + const assertDto = (model: FinalizationProof): void => { + expect(model).to.be.not.null; + expect(model.version).to.be.equals(dto.version); + expect(model.finalizationEpoch).to.be.equals(dto.finalizationEpoch); + expect(model.finalizationPoint).to.be.equals(dto.finalizationPoint); + expect(model.hash).to.be.equals(dto.hash); + expect(model.height.toString()).to.be.equals(dto.height); + + expect(model.messageGroups[0].height.toString()).to.be.equals(dto.messageGroups[0].height); + expect(model.messageGroups[0].stage.valueOf()).to.be.equals(dto.messageGroups[0].stage.valueOf()); + expect(model.messageGroups[0].hashes[0]).to.be.equals(dto.messageGroups[0].hashes[0]); + deepEqual(model.messageGroups[0].signatures, dto.messageGroups[0].signatures); + }; + + it('getFinalizationProofAtEpoch', async () => { + when(finalizationRoutesApi.getFinalizationProofAtEpoch(1)).thenReturn(Promise.resolve(dto)); + const model = await finalizationRepository.getFinalizationProofAtEpoch(1).toPromise(); + assertDto(model); + }); + + it('getFinalizationProofAtHeight', async () => { + when(finalizationRoutesApi.getFinalizationProofAtHeight('1')).thenReturn(Promise.resolve(dto)); + const model = await finalizationRepository.getFinalizationProofAtHeight(UInt64.fromUint(1)).toPromise(); + assertDto(model); + }); + + it('getFinalizationProofAtEpoch - Error', async () => { + when(finalizationRoutesApi.getFinalizationProofAtEpoch(1)).thenReject(new Error('Mocked Error')); + await finalizationRepository + .getFinalizationProofAtEpoch(1) + .toPromise() + .catch((error) => expect(error).not.to.be.undefined); + }); + + it('getFinalizationProofAtHeight - Error', async () => { + when(finalizationRoutesApi.getFinalizationProofAtHeight('1')).thenReject(new Error('Mocked Error')); + await finalizationRepository + .getFinalizationProofAtHeight(UInt64.fromUint(1)) + .toPromise() + .catch((error) => expect(error).not.to.be.undefined); + }); +}); diff --git a/test/infrastructure/NamespaceHttp.spec.ts b/test/infrastructure/NamespaceHttp.spec.ts index 1ca3dc909c..23bacba22f 100644 --- a/test/infrastructure/NamespaceHttp.spec.ts +++ b/test/infrastructure/NamespaceHttp.spec.ts @@ -50,7 +50,6 @@ describe('NamespaceHttp', () => { const namespaceId = new NamespaceId('testnamespace'); const namespaceMetaDto = {} as NamespaceMetaDTO; namespaceMetaDto.active = true; - namespaceMetaDto.id = '1'; namespaceMetaDto.index = 0; const namespaceDto = {} as NamespaceDTO; @@ -70,6 +69,7 @@ describe('NamespaceHttp', () => { const namespaceInfoDto = {} as NamespaceInfoDTO; namespaceInfoDto.meta = namespaceMetaDto; namespaceInfoDto.namespace = namespaceDto; + namespaceInfoDto.id = '1'; const aliasDtoMosaic = {} as AliasDTO; aliasDtoMosaic.mosaicId = mosaicId.toHex(); diff --git a/test/infrastructure/NodeHttp.spec.ts b/test/infrastructure/NodeHttp.spec.ts index 6b58e9c594..83acef4eb1 100644 --- a/test/infrastructure/NodeHttp.spec.ts +++ b/test/infrastructure/NodeHttp.spec.ts @@ -200,6 +200,17 @@ describe('NodeHttp', () => { } }); + it('getUnlockedAccount', async () => { + const body = ['key1', 'key2']; + + when(nodeRoutesApi.getUnlockedAccount()).thenReturn(Promise.resolve(body)); + + const unlockedAccount = await nodeRepository.getUnlockedAccount().toPromise(); + expect(unlockedAccount).to.be.not.null; + expect(unlockedAccount[0]).to.be.equal('key1'); + expect(unlockedAccount[1]).to.be.equal('key2'); + }); + it('getStorageInfo', async () => { const body = {} as StorageInfoDTO; body.numAccounts = 1; diff --git a/test/infrastructure/RepositoryFactory.spec.ts b/test/infrastructure/RepositoryFactory.spec.ts index faace837ce..f41a2ae290 100644 --- a/test/infrastructure/RepositoryFactory.spec.ts +++ b/test/infrastructure/RepositoryFactory.spec.ts @@ -42,6 +42,7 @@ 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'; +import { FinalizationHttp } from '../../src/infrastructure/FinalizationHttp'; import { NetworkConfigurationDTO } from 'symbol-openapi-typescript-fetch-client'; describe('RepositoryFactory', () => { @@ -66,6 +67,7 @@ describe('RepositoryFactory', () => { expect(repositoryFactory.createTransactionRepository()).to.be.not.null; expect(repositoryFactory.createHashLockRepository()).to.be.not.null; expect(repositoryFactory.createSecretLockRepository()).to.be.not.null; + expect(repositoryFactory.createFinalizationRepository()).to.be.not.null; }); it('Should get GenerationHash from cache', (done) => { @@ -329,6 +331,7 @@ describe('RepositoryFactory', () => { expect(factory.createTransactionStatusRepository() instanceof TransactionStatusHttp).to.be.true; expect(factory.createHashLockRepository() instanceof HashLockHttp).to.be.true; expect(factory.createSecretLockRepository() instanceof SecretLockHttp).to.be.true; + expect(factory.createFinalizationRepository() instanceof FinalizationHttp).to.be.true; }); it('Fail remote call ', async () => { diff --git a/test/infrastructure/SecretLockHttp.spec.ts b/test/infrastructure/SecretLockHttp.spec.ts index cf652decd2..bd419c0c7e 100644 --- a/test/infrastructure/SecretLockHttp.spec.ts +++ b/test/infrastructure/SecretLockHttp.spec.ts @@ -73,12 +73,6 @@ describe('SecretLockHttp', () => { 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; @@ -87,18 +81,10 @@ describe('SecretLockHttp', () => { const body = {} as SecretLockPage; body.data = [dto]; body.pagination = pagination; - when(secretLockRoutesApi.searchSecretLock(address.plain(), undefined, undefined, undefined, undefined)).thenReturn( + when(secretLockRoutesApi.searchSecretLock(address.plain(), lockDto.secret, undefined, undefined, undefined, undefined)).thenReturn( Promise.resolve(body), ); - const infos = await secretLockRepository.search({ address }).toPromise(); + const infos = await secretLockRepository.search({ address, secret: lockDto.secret }).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/TransactionHttp.spec.ts b/test/infrastructure/TransactionHttp.spec.ts index e62ecb68c4..6b211afb78 100644 --- a/test/infrastructure/TransactionHttp.spec.ts +++ b/test/infrastructure/TransactionHttp.spec.ts @@ -133,6 +133,9 @@ describe('TransactionHttp', () => { undefined, undefined, undefined, + undefined, + undefined, + undefined, ), ).thenReturn(Promise.resolve(page)); @@ -150,6 +153,9 @@ describe('TransactionHttp', () => { undefined, undefined, undefined, + undefined, + undefined, + undefined, ), ).thenReturn(Promise.resolve(page)); @@ -167,6 +173,9 @@ describe('TransactionHttp', () => { undefined, undefined, undefined, + undefined, + undefined, + undefined, ), ).thenReturn(Promise.resolve(page)); diff --git a/test/model/transaction/Deadline.spec.ts b/test/model/transaction/Deadline.spec.ts index 4db22e766d..eb01ad88a4 100644 --- a/test/model/transaction/Deadline.spec.ts +++ b/test/model/transaction/Deadline.spec.ts @@ -67,6 +67,7 @@ describe('Deadline', () => { const deadline = Deadline.createFromDTO('1'); const datetime = deadline.toLocalDateTime(epochAdjustment); const datetimeSystemZone = deadline.toLocalDateTimeGivenTimeZone(epochAdjustment, ZoneId.SYSTEM); + expect(datetime.month().value()).to.be.equal(11); expect(datetime).to.be.deep.eq(datetimeSystemZone); });