diff --git a/e2e/infrastructure/AccountHttp.spec.ts b/e2e/infrastructure/AccountHttp.spec.ts index ba9afe6c6f..778966167f 100644 --- a/e2e/infrastructure/AccountHttp.spec.ts +++ b/e2e/infrastructure/AccountHttp.spec.ts @@ -140,7 +140,7 @@ describe('AccountHttp', () => { UInt64.fromUint(9), NetworkType.MIJIN_TEST, ); - namespaceId = new NamespaceId(namespaceName); + namespaceId = new NamespaceId(namespaceName, NetworkType.MIJIN_TEST); const signedTransaction = registerNamespaceTransaction.signWith(account, generationHash); listener.confirmed(account.address).subscribe(() => { done(); diff --git a/e2e/infrastructure/Listener.spec.ts b/e2e/infrastructure/Listener.spec.ts index adf2e9f33d..5eb861179c 100644 --- a/e2e/infrastructure/Listener.spec.ts +++ b/e2e/infrastructure/Listener.spec.ts @@ -164,7 +164,7 @@ describe('Listener', () => { }); describe('Get network currency mosaic id', () => { it('get mosaicId', (done) => { - namespaceHttp.getLinkedMosaicId(new NamespaceId('cat.currency')).subscribe((networkMosaicId) => { + namespaceHttp.getLinkedMosaicId(new NamespaceId('cat.currency', NetworkType.MIJIN_TEST)).subscribe((networkMosaicId) => { networkCurrencyMosaicId = networkMosaicId; done(); }); diff --git a/e2e/infrastructure/MetadataHttp.spec.ts b/e2e/infrastructure/MetadataHttp.spec.ts index 06c4665614..4abb03a0be 100644 --- a/e2e/infrastructure/MetadataHttp.spec.ts +++ b/e2e/infrastructure/MetadataHttp.spec.ts @@ -95,7 +95,7 @@ describe('MetadataHttp', () => { }); it('standalone', (done) => { const nonce = MosaicNonce.createRandom(); - mosaicId = MosaicId.createFromNonce(nonce, account.publicAccount); + mosaicId = MosaicId.createFromNonce(nonce, account.publicAccount, NetworkType.MIJIN_TEST); const mosaicDefinitionTransaction = MosaicDefinitionTransaction.create( Deadline.create(), nonce, @@ -135,7 +135,7 @@ describe('MetadataHttp', () => { UInt64.fromUint(9), NetworkType.MIJIN_TEST, ); - namespaceId = new NamespaceId(namespaceName); + namespaceId = new NamespaceId(namespaceName, NetworkType.MIJIN_TEST); const signedTransaction = registerNamespaceTransaction.signWith(account, generationHash); listener.confirmed(account.address).subscribe(() => { done(); diff --git a/e2e/infrastructure/MosaicHttp.spec.ts b/e2e/infrastructure/MosaicHttp.spec.ts index 33afaecc6b..07a9a9b9e2 100644 --- a/e2e/infrastructure/MosaicHttp.spec.ts +++ b/e2e/infrastructure/MosaicHttp.spec.ts @@ -69,7 +69,7 @@ describe('MosaicHttp', () => { }); it('Announce MosaicDefinitionTransaction', (done) => { const nonce = MosaicNonce.createRandom(); - mosaicId = MosaicId.createFromNonce(nonce, account.publicAccount); + mosaicId = MosaicId.createFromNonce(nonce, account.publicAccount, NetworkType.MIJIN_TEST); const mosaicDefinitionTransaction = MosaicDefinitionTransaction.create( Deadline.create(), nonce, @@ -104,7 +104,7 @@ describe('MosaicHttp', () => { UInt64.fromUint(1000), NetworkType.MIJIN_TEST, ); - namespaceId = new NamespaceId(namespaceName); + namespaceId = new NamespaceId(namespaceName, NetworkType.MIJIN_TEST); const signedTransaction = registerNamespaceTransaction.signWith(account, generationHash); listener.confirmed(account.address).subscribe((transaction) => { done(); diff --git a/e2e/infrastructure/NamespaceHttp.spec.ts b/e2e/infrastructure/NamespaceHttp.spec.ts index f6e7e6898e..1bace22496 100644 --- a/e2e/infrastructure/NamespaceHttp.spec.ts +++ b/e2e/infrastructure/NamespaceHttp.spec.ts @@ -68,7 +68,7 @@ describe('NamespaceHttp', () => { UInt64.fromUint(1000), NetworkType.MIJIN_TEST, ); - namespaceId = new NamespaceId(namespaceName); + namespaceId = new NamespaceId(namespaceName, NetworkType.MIJIN_TEST); const signedTransaction = registerNamespaceTransaction.signWith(account, generationHash); listener.confirmed(account.address).subscribe((transaction) => { done(); diff --git a/e2e/infrastructure/RestrictionHttp.spec.ts b/e2e/infrastructure/RestrictionHttp.spec.ts index 3c0b796f9b..4c9d36c8c8 100644 --- a/e2e/infrastructure/RestrictionHttp.spec.ts +++ b/e2e/infrastructure/RestrictionHttp.spec.ts @@ -100,7 +100,7 @@ describe('RestrictionHttp', () => { }); it('standalone', (done) => { const nonce = MosaicNonce.createRandom(); - mosaicId = MosaicId.createFromNonce(nonce, account.publicAccount); + mosaicId = MosaicId.createFromNonce(nonce, account.publicAccount, NetworkType.MIJIN_TEST); const mosaicDefinitionTransaction = MosaicDefinitionTransaction.create( Deadline.create(), nonce, @@ -134,7 +134,7 @@ describe('RestrictionHttp', () => { }); it('standalone', (done) => { const nonce = MosaicNonce.createRandom(); - referenceMosaicId = MosaicId.createFromNonce(nonce, account.publicAccount); + referenceMosaicId = MosaicId.createFromNonce(nonce, account.publicAccount, NetworkType.MIJIN_TEST); const mosaicDefinitionTransaction = MosaicDefinitionTransaction.create( Deadline.create(), nonce, diff --git a/e2e/infrastructure/TransactionHttp.spec.ts b/e2e/infrastructure/TransactionHttp.spec.ts index fb8bfb8e10..b122bee2f6 100644 --- a/e2e/infrastructure/TransactionHttp.spec.ts +++ b/e2e/infrastructure/TransactionHttp.spec.ts @@ -138,7 +138,7 @@ describe('TransactionHttp', () => { }); it('standalone', (done) => { const nonce = MosaicNonce.createRandom(); - mosaicId = MosaicId.createFromNonce(nonce, account.publicAccount); + mosaicId = MosaicId.createFromNonce(nonce, account.publicAccount, NetworkType.MIJIN_TEST); const mosaicDefinitionTransaction = MosaicDefinitionTransaction.create( Deadline.create(), nonce, @@ -182,7 +182,7 @@ describe('TransactionHttp', () => { const mosaicDefinitionTransaction = MosaicDefinitionTransaction.create( Deadline.create(), nonce, - MosaicId.createFromNonce(nonce, account.publicAccount), + MosaicId.createFromNonce(nonce, account.publicAccount, NetworkType.MIJIN_TEST), MosaicFlags.create( true, true, true), 3, UInt64.fromUint(0), @@ -310,7 +310,7 @@ describe('TransactionHttp', () => { UInt64.fromUint(10), NetworkType.MIJIN_TEST, ); - namespaceId = new NamespaceId(namespaceName); + namespaceId = new NamespaceId(namespaceName, NetworkType.MIJIN_TEST); const signedTransaction = registerNamespaceTransaction.signWith(account, generationHash); listener.confirmed(account.address).subscribe((transaction: NamespaceRegistrationTransaction) => { expect(transaction.namespaceId, 'NamespaceId').not.to.be.undefined; @@ -1219,7 +1219,9 @@ describe('TransactionHttp', () => { ); const signedTransaction = account.sign(aggregateTransaction, generationHash); const hashLockTransaction = HashLockTransaction.create(Deadline.create(), - new Mosaic(new NamespaceId('cat.currency'), UInt64.fromUint(10 * Math.pow(10, NetworkCurrencyMosaic.DIVISIBILITY))), + new Mosaic( + new NamespaceId('cat.currency', NetworkType.MIJIN_TEST), + UInt64.fromUint(10 * Math.pow(10, NetworkCurrencyMosaic.DIVISIBILITY))), UInt64.fromUint(10000), signedTransaction, NetworkType.MIJIN_TEST); diff --git a/e2e/infrastructure/UnresolvedMapping.spec.ts b/e2e/infrastructure/UnresolvedMapping.spec.ts index fe5bddabf2..efcaf5057b 100644 --- a/e2e/infrastructure/UnresolvedMapping.spec.ts +++ b/e2e/infrastructure/UnresolvedMapping.spec.ts @@ -93,7 +93,7 @@ describe('TransactionHttp', () => { */ describe('Get network currency mosaic id', () => { it('get mosaicId', (done) => { - namespaceHttp.getLinkedMosaicId(new NamespaceId('cat.currency')).subscribe((networkMosaicId) => { + namespaceHttp.getLinkedMosaicId(new NamespaceId('cat.currency', NetworkType.MIJIN_TEST)).subscribe((networkMosaicId) => { networkCurrencyMosaicId = networkMosaicId; done(); }); @@ -111,7 +111,7 @@ describe('TransactionHttp', () => { }); it('standalone', (done) => { const nonce = MosaicNonce.createRandom(); - mosaicId = MosaicId.createFromNonce(nonce, account.publicAccount); + mosaicId = MosaicId.createFromNonce(nonce, account.publicAccount, NetworkType.MIJIN_TEST); const mosaicDefinitionTransaction = MosaicDefinitionTransaction.create( Deadline.create(), nonce, @@ -151,7 +151,7 @@ describe('TransactionHttp', () => { UInt64.fromUint(50), NetworkType.MIJIN_TEST, ); - namespaceIdMosaic = new NamespaceId(namespaceName); + namespaceIdMosaic = new NamespaceId(namespaceName, NetworkType.MIJIN_TEST); const signedTransaction = registerNamespaceTransaction.signWith(account, generationHash); listener.confirmed(account.address).subscribe(() => { done(); @@ -182,7 +182,7 @@ describe('TransactionHttp', () => { UInt64.fromUint(50), NetworkType.MIJIN_TEST, ); - namespaceIdAddress = new NamespaceId(namespaceName); + namespaceIdAddress = new NamespaceId(namespaceName, NetworkType.MIJIN_TEST); const signedTransaction = registerNamespaceTransaction.signWith(account, generationHash); listener.confirmed(account.address).subscribe(() => { done(); diff --git a/e2e/service/MetadataTransactionService.spec.ts b/e2e/service/MetadataTransactionService.spec.ts index 968b38f763..2221bf38bd 100644 --- a/e2e/service/MetadataTransactionService.spec.ts +++ b/e2e/service/MetadataTransactionService.spec.ts @@ -66,7 +66,7 @@ describe('MetadataTransactionService', () => { }); it('standalone', (done) => { const nonce = MosaicNonce.createRandom(); - mosaicId = MosaicId.createFromNonce(nonce, targetAccount.publicAccount); + mosaicId = MosaicId.createFromNonce(nonce, targetAccount.publicAccount, NetworkType.MIJIN_TEST); const mosaicDefinitionTransaction = MosaicDefinitionTransaction.create( Deadline.create(), nonce, @@ -105,7 +105,7 @@ describe('MetadataTransactionService', () => { UInt64.fromUint(9), NetworkType.MIJIN_TEST, ); - namespaceId = new NamespaceId(namespaceName); + namespaceId = new NamespaceId(namespaceName, NetworkType.MIJIN_TEST); const signedTransaction = registerNamespaceTransaction.signWith(targetAccount, generationHash); listener.confirmed(targetAccount.address).subscribe(() => { done(); diff --git a/e2e/service/MosaicRestrictionTransactionService.spec.ts b/e2e/service/MosaicRestrictionTransactionService.spec.ts index fbf830a3f2..452e218fea 100644 --- a/e2e/service/MosaicRestrictionTransactionService.spec.ts +++ b/e2e/service/MosaicRestrictionTransactionService.spec.ts @@ -63,7 +63,7 @@ describe('MosaicRestrictionTransactionService', () => { }); it('standalone', (done) => { const nonce = MosaicNonce.createRandom(); - mosaicId = MosaicId.createFromNonce(nonce, account.publicAccount); + mosaicId = MosaicId.createFromNonce(nonce, account.publicAccount, NetworkType.MIJIN_TEST); const mosaicDefinitionTransaction = MosaicDefinitionTransaction.create( Deadline.create(), nonce, diff --git a/src/core/crypto/Utilities.ts b/src/core/crypto/Utilities.ts index 69132811d0..e0483e2bb7 100644 --- a/src/core/crypto/Utilities.ts +++ b/src/core/crypto/Utilities.ts @@ -14,11 +14,11 @@ * limitations under the License. */ +const CryptoJS = require('crypto-js'); import { RawArray as array } from '../format'; import * as nacl from './nacl_catapult'; import { SHA3Hasher as sha3Hasher } from './SHA3Hasher'; import { SignSchema } from './SignSchema'; -export const CryptoJS = require('crypto-js'); export const Key_Size = 32; export const Signature_Size = 64; export const Half_Signature_Size = Signature_Size / 2; @@ -68,7 +68,7 @@ export const catapult_hash = { }; // custom catapult crypto functions -export const catapult_crypto = (function() { +export const catapult_crypto = (() => { function clamp(d) { d[0] &= 248; d[31] &= 127; @@ -82,7 +82,7 @@ export const catapult_crypto = (function() { return d; } - const encodedSChecker = (function() { + const encodedSChecker = (() => { const Is_Reduced = 1; const Is_Zero = 2; diff --git a/src/core/format/IdGenerator.ts b/src/core/format/IdGenerator.ts index e0ab0967b3..a91735220e 100644 --- a/src/core/format/IdGenerator.ts +++ b/src/core/format/IdGenerator.ts @@ -13,40 +13,80 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import {sha3_256} from 'js-sha3'; +import {NetworkType} from '../../model/blockchain/NetworkType'; +import {SHA3Hasher} from '../crypto/SHA3Hasher'; import * as utilities from './Utilities'; export class IdGenerator { /** * Generates a mosaic id given a nonce and a public id. - * @param {object} nonce The mosaic nonce. - * @param {object} ownerPublicId The public id. + * @param {object} nonce The mosaic nonce. + * @param {object} ownerPublicId The public id. + * @param {NetworkType} networkType The network type for hash algorithm resolution * @returns {module:coders/uint64~uint64} The mosaic id. */ - public static generateMosaicId = (nonce, ownerPublicId) => { - const hash = sha3_256.create(); + public static generateMosaicId = ( + nonce, + ownerPublicId, + networkType: NetworkType, + ) => { + const signSchema = SHA3Hasher.resolveSignSchema(networkType); + const hash = SHA3Hasher.getHasher(32, signSchema).create(); hash.update(nonce); hash.update(ownerPublicId); const result = new Uint32Array(hash.arrayBuffer()); return [result[0], result[1] & 0x7FFFFFFF]; } + /** + * Generates a namespace id given a parent id and name. + * @param {object} parentId The parent namespace id. + * @param {object} name The namespace name. + * @param {NetworkType} networkType The network type for hash algorithm resolution + * @returns {module:coders/uint64~uint64} The namespace id. + */ + public static generateNamespaceId = ( + parentId, + name: string, + networkType: NetworkType, + ) => { + const signSchema = SHA3Hasher.resolveSignSchema(networkType); + const hash = SHA3Hasher.getHasher(32, signSchema).create(); + hash.update(Uint32Array.from(parentId).buffer as any); + hash.update(name); + const result = new Uint32Array(hash.arrayBuffer()); + // right zero-filling required to keep unsigned number representation + return [result[0], (result[1] | 0x80000000) >>> 0]; + } + /** * Parses a unified namespace name into a path. - * @param {string} name The unified namespace name. + * @param {string} name The unified namespace name. + * @param {NetworkType} networkType The network type for hash algorithm resolution * @returns {array} The namespace path. */ - public static generateNamespacePath = (name: string) => { + public static generateNamespacePath = ( + name: string, + networkType: NetworkType, + ) => { if (0 >= name.length) { utilities.throwInvalidFqn('having zero length', name); } let namespaceId = utilities.idGeneratorConst.namespace_base_id; const path = []; const start = utilities.split(name, (substringStart, size) => { - namespaceId = utilities.generateNamespaceId(namespaceId, utilities.extractPartName(name, substringStart, size)); + namespaceId = IdGenerator.generateNamespaceId( + namespaceId, + utilities.extractPartName(name, substringStart, size), + networkType, + ); utilities.append(path, namespaceId, name); }); - namespaceId = utilities.generateNamespaceId(namespaceId, utilities.extractPartName(name, start, name.length - start)); + namespaceId = IdGenerator.generateNamespaceId( + namespaceId, + utilities.extractPartName(name, start, name.length - start), + networkType, + ); utilities.append(path, namespaceId, name); return path; } diff --git a/src/core/format/Utilities.ts b/src/core/format/Utilities.ts index b1e04b2fba..f1e230707c 100644 --- a/src/core/format/Utilities.ts +++ b/src/core/format/Utilities.ts @@ -131,15 +131,6 @@ export const split = (name, processor) => { return start; }; -export const generateNamespaceId = (parentId, name) => { - const hash = sha3_256.create(); - hash.update(Uint32Array.from(parentId).buffer as any); - hash.update(name); - const result = new Uint32Array(hash.arrayBuffer()); - // right zero-filling required to keep unsigned number representation - return [result[0], (result[1] | 0x80000000) >>> 0]; -}; - export const encodeBlock = (input, inputOffset, output, outputOffset) => { output[outputOffset + 0] = Alphabet[input[inputOffset + 0] >> 3]; output[outputOffset + 1] = Alphabet[((input[inputOffset + 0] & 0x07) << 2) | (input[inputOffset + 1] >> 6)]; diff --git a/src/infrastructure/AccountHttp.ts b/src/infrastructure/AccountHttp.ts index 467eca76c2..540cef356d 100644 --- a/src/infrastructure/AccountHttp.ts +++ b/src/infrastructure/AccountHttp.ts @@ -76,50 +76,11 @@ export class AccountHttp extends Http implements AccountRepository { * @returns Observable */ public getAccountInfo(address: Address): Observable { - return observableFrom(this.accountRoutesApi.getAccountInfo(address.plain())).pipe( - map((response: { response: ClientResponse; body: AccountInfoDTO; }) => { - const accountInfoDTO = response.body; - return new AccountInfo( - Address.createFromEncoded(accountInfoDTO.account.address), - UInt64.fromNumericString(accountInfoDTO.account.addressHeight), - accountInfoDTO.account.publicKey, - UInt64.fromNumericString(accountInfoDTO.account.publicKeyHeight), - accountInfoDTO.account.accountType.valueOf(), - accountInfoDTO.account.linkedAccountKey, - accountInfoDTO.account.activityBuckets.map((bucket) => { - return new ActivityBucket( - bucket.startHeight, - bucket.totalFeesPaid, - bucket.beneficiaryCount, - bucket.rawScore, - ); - }), - accountInfoDTO.account.mosaics.map((mosaicDTO) => new Mosaic( - new MosaicId(mosaicDTO.id), - UInt64.fromNumericString(mosaicDTO.amount), - )), - UInt64.fromNumericString(accountInfoDTO.account.importance), - UInt64.fromNumericString(accountInfoDTO.account.importanceHeight), - ); - }), - catchError((error) => throwError(this.errorHandling(error))), - ); - } - - /** - * Gets AccountsInfo for different accounts. - * @param addresses List of Address - * @returns Observable - */ - public getAccountsInfo(addresses: Address[]): Observable { - const accountIdsBody = { - addresses: addresses.map((address) => address.plain()), - }; - return observableFrom( - this.accountRoutesApi.getAccountsInfo(accountIdsBody)).pipe( - map((response: { response: ClientResponse; body: AccountInfoDTO[]; }) => { - const accountsInfoMetaDataDTO = response.body; - return accountsInfoMetaDataDTO.map((accountInfoDTO: AccountInfoDTO) => { + return this.getNetworkTypeObservable().pipe( + mergeMap((networkType) => observableFrom( + this.accountRoutesApi.getAccountInfo(address.plain())) + .pipe(map((response: { response: ClientResponse; body: AccountInfoDTO; }) => { + const accountInfoDTO = response.body; return new AccountInfo( Address.createFromEncoded(accountInfoDTO.account.address), UInt64.fromNumericString(accountInfoDTO.account.addressHeight), @@ -142,32 +103,75 @@ export class AccountHttp extends Http implements AccountRepository { UInt64.fromNumericString(accountInfoDTO.account.importance), UInt64.fromNumericString(accountInfoDTO.account.importanceHeight), ); + }), + catchError((error) => throwError(this.errorHandling(error)))), + )); + } - }); - }), - catchError((error) => throwError(this.errorHandling(error))), - ); + /** + * Gets AccountsInfo for different accounts. + * @param addresses List of Address + * @returns Observable + */ + public getAccountsInfo(addresses: Address[]): Observable { + const accountIdsBody = { + addresses: addresses.map((address) => address.plain()), + }; + return this.getNetworkTypeObservable().pipe( + mergeMap((networkType) => observableFrom( + this.accountRoutesApi.getAccountsInfo(accountIdsBody)).pipe( + map((response: { response: ClientResponse; body: AccountInfoDTO[]; }) => { + const accountsInfoMetaDataDTO = response.body; + return accountsInfoMetaDataDTO.map((accountInfoDTO: AccountInfoDTO) => { + return new AccountInfo( + Address.createFromEncoded(accountInfoDTO.account.address), + UInt64.fromNumericString(accountInfoDTO.account.addressHeight), + accountInfoDTO.account.publicKey, + UInt64.fromNumericString(accountInfoDTO.account.publicKeyHeight), + accountInfoDTO.account.accountType.valueOf(), + accountInfoDTO.account.linkedAccountKey, + accountInfoDTO.account.activityBuckets.map((bucket) => { + return new ActivityBucket( + bucket.startHeight, + bucket.totalFeesPaid, + bucket.beneficiaryCount, + bucket.rawScore, + ); + }), + accountInfoDTO.account.mosaics.map((mosaicDTO) => new Mosaic( + new MosaicId(mosaicDTO.id), + UInt64.fromNumericString(mosaicDTO.amount), + )), + UInt64.fromNumericString(accountInfoDTO.account.importance), + UInt64.fromNumericString(accountInfoDTO.account.importanceHeight), + ); + + }); + }), + catchError((error) => throwError(this.errorHandling(error)))), + )); } public getAccountsNames(addresses: Address[]): Observable { const accountIdsBody = { addresses: addresses.map((address) => address.plain()), }; - return observableFrom( - this.accountRoutesApi.getAccountsNames(accountIdsBody)).pipe( - map((response: { response: ClientResponse; body: any; }) => { - const accountNames = response.body.accountNames; - return accountNames.map((accountName) => { - return new AccountNames( - Address.createFromEncoded(accountName.address), - accountName.names.map((name) => { - return new NamespaceName(new NamespaceId(name), name); - }), - ); - }); - }), - catchError((error) => throwError(this.errorHandling(error))), - ); + return this.getNetworkTypeObservable().pipe( + mergeMap((networkType) => observableFrom( + this.accountRoutesApi.getAccountsNames(accountIdsBody)).pipe( + map((response: { response: ClientResponse; body: any; }) => { + const accountNames = response.body.accountNames; + return accountNames.map((accountName) => { + return new AccountNames( + Address.createFromEncoded(accountName.address), + accountName.names.map((name) => { + return new NamespaceName(new NamespaceId(name, networkType), name); + }), + ); + }); + }), + catchError((error) => throwError(this.errorHandling(error)))), + )); } /** * Gets a MultisigAccountInfo for an account. diff --git a/src/infrastructure/transaction/NamespaceMosaicIdGenerator.ts b/src/infrastructure/transaction/NamespaceMosaicIdGenerator.ts index 5f7a57aea1..006c844db9 100644 --- a/src/infrastructure/transaction/NamespaceMosaicIdGenerator.ts +++ b/src/infrastructure/transaction/NamespaceMosaicIdGenerator.ts @@ -15,14 +15,21 @@ */ import {Crypto} from '../../core/crypto'; -import { IdGenerator } from '../../core/format'; +import {IdGenerator} from '../../core/format'; +import {NetworkType} from '../../model/blockchain/NetworkType'; export class NamespaceMosaicIdGenerator { /** + * @param nonce {object} Uint8Array of bytes for nonce OR array with uint8 integer + * @param networkType {NetworkType} The network type for hash algorithm resolution * @returns mosaic Id */ - public static mosaicId = (nonce, ownerPublicId) => { - return IdGenerator.generateMosaicId(nonce, ownerPublicId); + public static mosaicId = ( + nonce, + ownerPublicId, + networkType: NetworkType, + ) => { + return IdGenerator.generateMosaicId(nonce, ownerPublicId, networkType); } /** @@ -33,30 +40,45 @@ export class NamespaceMosaicIdGenerator { } /** - * @param {string} namespaceName - The namespace name + * @param {string} namespaceName The namespace name + * @param {NetworkType} networkType The network type for hash algorithm resolution * @returns sub namespace id */ - public static namespaceId = (namespaceName) => { - const path = IdGenerator.generateNamespacePath(namespaceName); - return path.length ? IdGenerator.generateNamespacePath(namespaceName)[path.length - 1] : []; + public static namespaceId = ( + namespaceName, + networkType: NetworkType, + ) => { + const path = IdGenerator.generateNamespacePath(namespaceName, networkType); + return path.length ? IdGenerator.generateNamespacePath(namespaceName, networkType)[path.length - 1] : []; } + /** - * @param {string} parentNamespaceName - The parent namespace name - * @param {string} namespaceName - The namespace name + * @param {string} parentNamespaceName The parent namespace name + * @param {string} namespaceName The namespace name + * @param {NetworkType} networkType The network type for hash algorithm resolution * @returns sub namespace parent id */ - public static subnamespaceParentId = (parentNamespaceName: string, namespaceName: string) => { - const path = IdGenerator.generateNamespacePath(`${parentNamespaceName}.${namespaceName}`); - return IdGenerator.generateNamespacePath(parentNamespaceName)[path.length - 2]; + public static subnamespaceParentId = ( + parentNamespaceName: string, + namespaceName: string, + networkType: NetworkType, + ) => { + const path = IdGenerator.generateNamespacePath(`${parentNamespaceName}.${namespaceName}`, networkType); + return IdGenerator.generateNamespacePath(parentNamespaceName, networkType)[path.length - 2]; } /** - * @param {string} parentNamespaceName - The parent namespace name - * @param {string} namespaceName - The namespace name + * @param {string} parentNamespaceName The parent namespace name + * @param {string} namespaceName The namespace name + * @param {NetworkType} networkType The network type for hash algorithm resolution * @returns sub namespace id */ - public static subnamespaceNamespaceId = (parentNamespaceName, namespaceName) => { - const path = IdGenerator.generateNamespacePath(`${parentNamespaceName}.${namespaceName}`); + public static subnamespaceNamespaceId = ( + parentNamespaceName: string, + namespaceName: string, + networkType: NetworkType, + ) => { + const path = IdGenerator.generateNamespacePath(`${parentNamespaceName}.${namespaceName}`, networkType); return path[path.length - 1]; } diff --git a/src/model/mosaic/MosaicId.ts b/src/model/mosaic/MosaicId.ts index bb2019ddcf..f216dd5c46 100644 --- a/src/model/mosaic/MosaicId.ts +++ b/src/model/mosaic/MosaicId.ts @@ -16,6 +16,7 @@ import { Convert as convert, RawUInt64 as uint64_t } from '../../core/format'; import {NamespaceMosaicIdGenerator} from '../../infrastructure/transaction/NamespaceMosaicIdGenerator'; import {PublicAccount} from '../account/PublicAccount'; +import {NetworkType} from '../blockchain/NetworkType'; import {Id} from '../Id'; import {MosaicNonce} from '../mosaic/MosaicNonce'; @@ -34,12 +35,17 @@ export class MosaicId { /** * Create a MosaicId for given `nonce` MosaicNonce and `owner` PublicAccount. * - * @param nonce {MosaicNonce} - * @param owner {Account} + * @param {MosaicNonce} nonce The mosaic nonce + * @param {PublicAccount} owner The mosaic owner public account + * @param {NetworkType} networkType The network type for hash algorithm resolution * @return {MosaicId} */ - public static createFromNonce(nonce: MosaicNonce, owner: PublicAccount): MosaicId { - const mosaicId = NamespaceMosaicIdGenerator.mosaicId(nonce.nonce, convert.hexToUint8(owner.publicKey)); + public static createFromNonce( + nonce: MosaicNonce, + owner: PublicAccount, + networkType: NetworkType, + ): MosaicId { + const mosaicId = NamespaceMosaicIdGenerator.mosaicId(nonce.nonce, convert.hexToUint8(owner.publicKey), networkType); return new MosaicId(mosaicId); } diff --git a/src/model/namespace/NamespaceId.ts b/src/model/namespace/NamespaceId.ts index 7f4e019077..714084307c 100644 --- a/src/model/namespace/NamespaceId.ts +++ b/src/model/namespace/NamespaceId.ts @@ -13,8 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { SignSchema } from '../../core/crypto/SignSchema'; import {Convert as convert} from '../../core/format'; import {NamespaceMosaicIdGenerator} from '../../infrastructure/transaction/NamespaceMosaicIdGenerator'; +import {NetworkType} from '../blockchain/NetworkType'; import {Id} from '../Id'; /** @@ -38,23 +40,31 @@ export class NamespaceId { * Create NamespaceId from namespace string name (ex: nem or domain.subdom.subdome) * or id in form of array number (ex: [929036875, 2226345261]) * - * @param id + * @param {string|number[]} id The namespace id (string or uint64 array) + * @param {NetworkType} networkType The network type for hash algorithm resolution */ - constructor(id: string | number[]) { + constructor( + id: string | number[], + networkType?: NetworkType, + ) { if (id instanceof Array) { this.id = new Id(id); } else if (typeof id === 'string') { this.fullName = id; - this.id = new Id(NamespaceMosaicIdGenerator.namespaceId(id)); + this.id = new Id(NamespaceMosaicIdGenerator.namespaceId(id, networkType!)); } } /** * Create a NamespaceId object from its encoded hexadecimal notation. - * @param encoded + * + * @param {string} encoded Hexadecimal notation of namespace id + * @param {NetworkType} networkType The network type for hash algorithm resolution * @returns {NamespaceId} */ - public static createFromEncoded(encoded: string): NamespaceId { + public static createFromEncoded( + encoded: string, + ): NamespaceId { const uint = convert.hexToUint8(encoded); const hex = convert.uint8ToHex(uint); const namespace = new NamespaceId(Id.fromHex(hex).toDTO()); diff --git a/src/model/transaction/NamespaceRegistrationTransaction.ts b/src/model/transaction/NamespaceRegistrationTransaction.ts index b10a46714d..51920371c8 100644 --- a/src/model/transaction/NamespaceRegistrationTransaction.ts +++ b/src/model/transaction/NamespaceRegistrationTransaction.ts @@ -64,7 +64,7 @@ export class NamespaceRegistrationTransaction extends Transaction { maxFee, NamespaceRegistrationType.RootNamespace, namespaceName, - new NamespaceId(namespaceName), + new NamespaceId(namespaceName, networkType), duration, ); } @@ -85,7 +85,7 @@ export class NamespaceRegistrationTransaction extends Transaction { maxFee: UInt64 = new UInt64([0, 0])): NamespaceRegistrationTransaction { let parentId: NamespaceId; if (typeof parentNamespace === 'string') { - parentId = new NamespaceId(NamespaceMosaicIdGenerator.subnamespaceParentId(parentNamespace, namespaceName)); + parentId = new NamespaceId(NamespaceMosaicIdGenerator.subnamespaceParentId(parentNamespace, namespaceName, networkType)); } else { parentId = parentNamespace; } @@ -96,8 +96,8 @@ export class NamespaceRegistrationTransaction extends Transaction { NamespaceRegistrationType.SubNamespace, namespaceName, typeof parentNamespace === 'string' ? - new NamespaceId(NamespaceMosaicIdGenerator.subnamespaceNamespaceId(parentNamespace, namespaceName)) : - new NamespaceId(NamespaceMosaicIdGenerator.namespaceId(namespaceName)), + new NamespaceId(NamespaceMosaicIdGenerator.subnamespaceNamespaceId(parentNamespace, namespaceName, networkType)) : + new NamespaceId(NamespaceMosaicIdGenerator.namespaceId(namespaceName, networkType)), undefined, parentId, ); diff --git a/test/core/format/IdGenerator.spec.ts b/test/core/format/IdGenerator.spec.ts index f81cbc14c4..c4f2543bce 100644 --- a/test/core/format/IdGenerator.spec.ts +++ b/test/core/format/IdGenerator.spec.ts @@ -20,11 +20,22 @@ import { IdGenerator as idGenerator, RawUInt64 as uint64, } from '../../../src/core/format'; +import {NetworkType} from '../../../src/model/blockchain/NetworkType'; const constants = { - nem_id: [0x375FFA4B, 0x84B3552D], - xem_id: [0xD95FCF29, 0xD525AD41], + nem_id: [0x375FFA4B, 0x84B3552D], // 84B3552D375FFA4B + xem_id: [0xD95FCF29, 0xD525AD41], // D525AD41D95FCF29 namespace_base_id: [0, 0], + cat_id: [0xBA651B4F, 0xB1497F5F], // B1497F5FBA651B4F + currency_id: [0xC462B244, 0x85BBEA6C], // 85BBEA6CC462B244 +}; + +const keccak_constants = { + nem_id: [0x12A2C7B8, 0xA912FDE5], // A912FDE512A2C7B8 + xem_id: [0x125CB3C7, 0xB5557B0C], // B5557B0C125CB3C7 + namespace_base_id: [0, 0], + cat_id: [0x8E9B1690, 0xBEFDD715], // BEFDD7158E9B1690 + currency_id: [0x710AD7DF, 0xF50E70E4], // F50E70E4710AD7DF }; const basicMosaicInfo = { @@ -34,6 +45,7 @@ const basicMosaicInfo = { 0xCB, 0x6C, 0x80, 0xDE, 0x62, 0xCD, 0x92, 0xF7, 0xF9, 0xAE, 0xDB, 0x70, 0x64, 0xA3, 0xDE, 0x62, ], id: [0xC0AFC518, 0x3AD842A8], + keccak_id: [0xEDE4A3B5, 0x5BE12991], }; const mosaicTestVector = { @@ -41,120 +53,149 @@ const mosaicTestVector = { publicKey: '4AFF7B4BA8C1C26A7917575993346627CB6C80DE62CD92F7F9AEDB7064A3DE62', nonce: 'B76FE378', expectedMosaicId: '3AD842A8C0AFC518', + expectedMosaicId_keccak: '5BE12991EDE4A3B5', }, { publicKey: '3811EDF245F1D30171FF1474B24C4366FECA365A8457AAFA084F3DE4AEA0BA60', nonce: '21832A2A', expectedMosaicId: '24C54740A9F3893F', + expectedMosaicId_keccak: '2BE164F9A75DF7E3', }, { publicKey: '3104D468D20491EC12C988C50CAD9282256052907415359201C46CBD7A0BCD75', nonce: '2ADBB332', expectedMosaicId: '43908F2DEEA04245', + expectedMosaicId_keccak: '150E9D162C201699', }, { publicKey: '6648E16513F351E9907B0EA34377E25F579BE640D4698B28E06585A21E94CFE2', nonce: 'B9175E0F', expectedMosaicId: '183172772BD29E78', + expectedMosaicId_keccak: '0B2EC34268F9E738', }, { publicKey: '1C05C40D38463FE725CF0584A3A69E3B0D6B780196A88C50624E49B921EE1404', nonce: 'F6077DDD', expectedMosaicId: '423DB0B12F787422', + expectedMosaicId_keccak: '79D9511DB0820357', }, { publicKey: '37926B3509987093C776C8EA3E7F978E3A78142B5C96B9434C3376177DC65EFD', nonce: '08190C6D', expectedMosaicId: '1F07D26B6CD352D5', + expectedMosaicId_keccak: '3600A75CB6BAC564', }, { publicKey: 'FDC6B0D415D90536263431F05C46AC492D0BD9B3CFA1B79D5A35E0F371655C0C', nonce: '81662AA5', expectedMosaicId: '74511F54940729CB', + expectedMosaicId_keccak: '148207CC42F848F5', }, { publicKey: '2D4EA99965477AEB3BC162C09C24C8DA4DABE408956C2F69642554EA48AAE1B2', nonce: 'EA16BF58', expectedMosaicId: '4C55843B6EB4A5BD', + expectedMosaicId_keccak: '242117E483E89C97', }, { publicKey: '68EB2F91E74D005A7C22D6132926AEF9BFD90A3ACA3C7F989E579A93EFF24D51', nonce: 'E5F87A8B', expectedMosaicId: '4D89DE2B6967666A', + expectedMosaicId_keccak: '02F85234BB69DE96', }, { publicKey: '3B082C0074F65D1E205643CDE72C6B0A3D0579C7ACC4D6A7E23A6EC46363B90F', nonce: '1E6BB49F', expectedMosaicId: '0A96B3A44615B62F', + expectedMosaicId_keccak: '6540ADD2F5553B1C', }, { publicKey: '81245CA233B729FAD1752662EADFD73C5033E3B918CE854E01F6EB51E98CD9F1', nonce: 'B82965E3', expectedMosaicId: '1D6D8E655A77C4E6', + expectedMosaicId_keccak: '0428FF2C77E73627', }, { publicKey: 'D3A2C1BFD5D48239001174BFF62A83A52BC9A535B8CDBDF289203146661D8AC4', nonce: 'F37FB460', expectedMosaicId: '268A3CC23ADCDA2D', + expectedMosaicId_keccak: '256E43F770A82286', }, { publicKey: '4C4CA89B7A31C42A7AB963B8AB9D85628BBB94735C999B2BD462001A002DBDF3', nonce: 'FF6323B0', expectedMosaicId: '51202B5C51F6A5A9', + expectedMosaicId_keccak: '1B919D2A45478B06', }, { publicKey: '2F95D9DCD4F18206A54FA95BD138DA1C038CA82546525A8FCC330185DA0647DC', nonce: '99674492', expectedMosaicId: '5CE4E38B09F1423D', + expectedMosaicId_keccak: '6DD76C9AA0126E9B', }, { publicKey: 'A7892491F714B8A7469F763F695BDB0B3BF28D1CC6831D17E91F550A2D48BD12', nonce: '55141880', expectedMosaicId: '5EFD001B3350C9CB', + expectedMosaicId_keccak: '0D3FBC12110B84DF', }, { publicKey: '68BBDDF5C08F54278DA516F0E4A5CCF795C10E2DE26CAF127FF4357DA7ACF686', nonce: '11FA5BAF', expectedMosaicId: '179F0CDD6D2CCA7B', + expectedMosaicId_keccak: '50B75F5CC92102F2', }, { publicKey: '014F6EF90792F814F6830D64017107534F5B718E2DD43C25ACAABBE347DEC81E', nonce: '6CFBF7B3', expectedMosaicId: '53095813DEB3D108', + expectedMosaicId_keccak: '60C553D950B6F874', }, { publicKey: '95A6344597E0412C51B3559F58F564F9C2DE3101E5CC1DD8B115A93CE7040A71', nonce: '905EADFE', expectedMosaicId: '3551C4B12DDF067D', + expectedMosaicId_keccak: '2CA716F0461A5441', }, { publicKey: '0D7DDFEB652E8B65915EA734420A1233A233119BF1B0D41E1D5118CDD44447EE', nonce: '61F5B671', expectedMosaicId: '696E2FB0682D3199', + expectedMosaicId_keccak: '4A9E186E4841F27C', }, { publicKey: 'FFD781A20B01D0C999AABC337B8BAE82D1E7929A9DD77CC1A71E4B99C0749684', nonce: 'D8542F1A', expectedMosaicId: '6C55E05D11D19FBD', + expectedMosaicId_keccak: '38928F01C609BBCD', }, ], }; describe('id generator', () => { - function generateNamespaceId(parentId, name) { - const hash = sha3_256.create(); - hash.update(Uint32Array.from(parentId).buffer as any); - hash.update(name); - const result = new Uint32Array(hash.arrayBuffer()); - // right zero-filling required to keep unsigned number representation - return [result[0], (result[1] | 0x80000000) >>> 0]; - } function addBasicTests(generator) { it('produces different results for different names', () => { // Assert: ['bloodyrookie.alice', 'nem.mex', 'bloodyrookie.xem', 'bloody_rookie.xem'].forEach((name) => - expect(generator(name), `nem.xem vs ${name}`).to.not.equal(generator('nem.xem'))); + expect(() => generator(name), `nem.xem vs ${name}`).to.not.equal(generator('nem.xem'))); + }); + + it('uses SignSchema.SHA3 as default signature schema', () => { + const sha3_xem = generator('nem.xem', NetworkType.MIJIN_TEST); + const xem = generator('nem.xem'); + + expect(xem, `DEFAULT nem.xem vs SHA3 nem.xem`).to.deep.equal(sha3_xem); + }); + + it('produces different results for different signature schema', () => { + // Assert: + ['bloodyrookie.alice', 'nem.mex', 'bloodyrookie.xem', 'bloody_rookie.xem'].forEach((name) => { + const sha3_ns = generator(name, NetworkType.MIJIN_TEST); + const keccak_ns = generator(name, NetworkType.TEST_NET); + + expect(() => keccak_ns, `KECCAK ${name} vs SHA3 ${name}`).to.not.equal(sha3_ns); + }); }); it('rejects names with uppercase characters', () => { @@ -184,16 +225,22 @@ describe('id generator', () => { describe('generate mosaic id', () => { it('generates correct well known id', () => { // Assert: - expect(idGenerator.generateMosaicId(basicMosaicInfo.nonce, basicMosaicInfo.publicId)) + expect(idGenerator.generateMosaicId(basicMosaicInfo.nonce, basicMosaicInfo.publicId, NetworkType.MIJIN_TEST)) .to.deep.equal(basicMosaicInfo.id); }); + it('generates correct well known id with KECCAK given NetworkType.TEST_NET', () => { + // Assert: + expect(idGenerator.generateMosaicId(basicMosaicInfo.nonce, basicMosaicInfo.publicId, NetworkType.TEST_NET)) + .to.deep.equal(basicMosaicInfo.keccak_id); + }); + // @dataProvider mosaicTestVector it('generates correct mosaicId given nonce and public key', () => { mosaicTestVector.rows.map((row, i) => { const pubKey = convert.hexToUint8(row.publicKey); const nonce = convert.hexToUint8(row.nonce).reverse(); // Little-Endianness! - const mosaicId = idGenerator.generateMosaicId(nonce, pubKey); + const mosaicId = idGenerator.generateMosaicId(nonce, pubKey, NetworkType.MIJIN_TEST); const expectedId = uint64.fromHex(row.expectedMosaicId); // Assert: @@ -201,49 +248,112 @@ describe('id generator', () => { .to.deep.equal(expectedId); }); }); + + // @dataProvider mosaicTestVector + it('generates correct mosaicId given nonce and public key with KECCAK given NetworkType.(TEST_NET|MAIN_NET)', () => { + mosaicTestVector.rows.map((row, i) => { + const pubKey = convert.hexToUint8(row.publicKey); + const nonce = convert.hexToUint8(row.nonce).reverse(); // Little-Endianness! + const mosaicId_publicTest = idGenerator.generateMosaicId(nonce, pubKey, NetworkType.TEST_NET); + const mosaicId_public = idGenerator.generateMosaicId(nonce, pubKey, NetworkType.MAIN_NET); + const expectedId = uint64.fromHex(row.expectedMosaicId_keccak); + + // Assert: + expect(mosaicId_publicTest) + .to.deep.equal(expectedId); + + expect(mosaicId_public) + .to.deep.equal(expectedId); + }); + }); }); describe('generate namespace paths', () => { it('generates correct well known root path', () => { // Act: - const path = idGenerator.generateNamespacePath('nem'); + const path = idGenerator.generateNamespacePath('nem', NetworkType.MIJIN_TEST); + const catPath = idGenerator.generateNamespacePath('cat', NetworkType.MIJIN_TEST); // Assert: expect(path.length).to.equal(1); + expect(catPath.length).to.equal(1); expect(path[0]).to.deep.equal(constants.nem_id); + expect(catPath[0]).to.deep.equal(constants.cat_id); + }); + + it('generates correct well known root path with KECCAK given NetworkType.TEST_NET', () => { + // Act: + const path = idGenerator.generateNamespacePath('nem', NetworkType.TEST_NET); + const catPath = idGenerator.generateNamespacePath('cat', NetworkType.TEST_NET); + + // Assert: + expect(path.length).to.equal(1); + expect(catPath.length).to.equal(1); + expect(path[0]).to.deep.equal(keccak_constants.nem_id); + expect(catPath[0]).to.deep.equal(keccak_constants.cat_id); }); it('generates correct well known child path', () => { // Act: - const path = idGenerator.generateNamespacePath('nem.xem'); + const path = idGenerator.generateNamespacePath('nem.xem', NetworkType.MIJIN_TEST); + const catPath = idGenerator.generateNamespacePath('cat.currency', NetworkType.MIJIN_TEST); // Assert: expect(path.length).to.equal(2); + expect(catPath.length).to.equal(2); expect(path[0]).to.deep.equal(constants.nem_id); expect(path[1]).to.deep.equal(constants.xem_id); + expect(catPath[0]).to.deep.equal(constants.cat_id); + expect(catPath[1]).to.deep.equal(constants.currency_id); + }); + + it('generates correct well known child path with KECCAK given NetworkType.TEST_NET', () => { + // Act: + const path = idGenerator.generateNamespacePath('nem.xem', NetworkType.TEST_NET); + const catPath = idGenerator.generateNamespacePath('cat.currency', NetworkType.TEST_NET); + + // Assert: + expect(path.length).to.equal(2); + expect(catPath.length).to.equal(2); + expect(path[0]).to.deep.equal(keccak_constants.nem_id); + expect(path[1]).to.deep.equal(keccak_constants.xem_id); + expect(catPath[0]).to.deep.equal(keccak_constants.cat_id); + expect(catPath[1]).to.deep.equal(keccak_constants.currency_id); }); it('supports multi level namespaces', () => { // Arrange: const expected: any = []; - expected.push(generateNamespaceId(constants.namespace_base_id, 'foo')); - expected.push(generateNamespaceId(expected[0], 'bar')); - expected.push(generateNamespaceId(expected[1], 'baz')); + expected.push(idGenerator.generateNamespaceId(constants.namespace_base_id, 'foo', NetworkType.MIJIN_TEST)); + expected.push(idGenerator.generateNamespaceId(expected[0], 'bar', NetworkType.MIJIN_TEST)); + expected.push(idGenerator.generateNamespaceId(expected[1], 'baz', NetworkType.MIJIN_TEST)); + + // Assert: + expect(idGenerator.generateNamespacePath('foo.bar.baz', NetworkType.MIJIN_TEST)).to.deep.equal(expected); + }); + + it('supports multi level namespaces with KECCAK given NetworkType.TEST_NET', () => { + // Arrange: + const expected: any = []; + expected.push(idGenerator.generateNamespaceId(constants.namespace_base_id, 'foo', NetworkType.TEST_NET)); + expected.push(idGenerator.generateNamespaceId(expected[0], 'bar', NetworkType.TEST_NET)); + expected.push(idGenerator.generateNamespaceId(expected[1], 'baz', NetworkType.TEST_NET)); // Assert: - expect(idGenerator.generateNamespacePath('foo.bar.baz')).to.deep.equal(expected); + expect(idGenerator.generateNamespacePath('foo.bar.baz', NetworkType.TEST_NET)).to.deep.equal(expected); }); it('rejects names with too many parts', () => { // Assert: ['a.b.c.d', 'a.b.c.d.e'].forEach((name) => - expect(() => idGenerator.generateNamespacePath(name), `name ${name}`).to.throw('too many parts')); + expect(() => idGenerator.generateNamespacePath(name, NetworkType.MIJIN_TEST), `name ${name}`).to.throw('too many parts')); }); it('rejects improper qualified names', () => { // Assert: ['a:b:c', 'a::b'].forEach((name) => - expect(() => idGenerator.generateNamespacePath(name), `name ${name}`).to.throw('invalid part name')); + expect(() => idGenerator.generateNamespacePath(name, NetworkType.MIJIN_TEST), `name ${name}`) + .to.throw('invalid part name')); }); addBasicTests(idGenerator.generateNamespacePath); diff --git a/test/model/mosaic/MosaicId.spec.ts b/test/model/mosaic/MosaicId.spec.ts index 256f44ec69..38c93c52a3 100644 --- a/test/model/mosaic/MosaicId.spec.ts +++ b/test/model/mosaic/MosaicId.spec.ts @@ -37,7 +37,7 @@ describe('MosaicId', () => { it('should create id given nonce and owner', () => { const owner = PublicAccount.createFromPublicKey(publicKey, NetworkType.MIJIN_TEST); const bytes = new Uint8Array([0x0, 0x0, 0x0, 0x0]); - const id = MosaicId.createFromNonce(new MosaicNonce(bytes), owner); + const id = MosaicId.createFromNonce(new MosaicNonce(bytes), owner, NetworkType.MIJIN_TEST); deepEqual(id.id, new Id([481110499, 231112638])); }); @@ -45,8 +45,8 @@ describe('MosaicId', () => { it('should create id twice the same given nonce and owner', () => { const owner = PublicAccount.createFromPublicKey(publicKey, NetworkType.MIJIN_TEST); const bytes = new Uint8Array([0x0, 0x0, 0x0, 0x0]); - const id1 = MosaicId.createFromNonce(new MosaicNonce(bytes), owner); - const id2 = MosaicId.createFromNonce(new MosaicNonce(bytes), owner); + const id1 = MosaicId.createFromNonce(new MosaicNonce(bytes), owner, NetworkType.MIJIN_TEST); + const id2 = MosaicId.createFromNonce(new MosaicNonce(bytes), owner, NetworkType.MIJIN_TEST); deepEqual(id1.id, id2.id); });