diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e86297bea..64eb58ed23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,10 @@ Package | Version | Link ---|---|--- SDK Core| v1.0.3 | [symbol-sdk](https://www.npmjs.com/package/symbol-sdk) Catbuffer | v1.0.1 | [catbuffer-typescript](https://www.npmjs.com/package/catbuffer-typescript) -Client Library | v1.0.2 | [symbol-openapi-typescript-fetch-client](https://www.npmjs.com/package/symbol-openapi-typescript-fetch-client) +Client Library | v1.0.3 | [symbol-openapi-typescript-fetch-client](https://www.npmjs.com/package/symbol-openapi-typescript-fetch-client) - fix: replaced `instanceof` statements. These statements are problematic when npm installs the dependency in multiples modules. +- feat: added mosaic revocation support. ## [1.0.2] - 25-Oct-2021 @@ -21,7 +22,7 @@ Client Library | v1.0.2 | [symbol-openapi-typescript-fetch-client](https://www. Package | Version | Link ---|---|--- SDK Core| v1.0.2 | [symbol-sdk](https://www.npmjs.com/package/symbol-sdk) -Catbuffer | v1.0.1 | [catbuffer-typescript](https://www.npmjs.com/package/catbuffer-typescript) +Catbuffer | v1.0.0 | [catbuffer-typescript](https://www.npmjs.com/package/catbuffer-typescript) Client Library | v1.0.2 | [symbol-openapi-typescript-fetch-client](https://www.npmjs.com/package/symbol-openapi-typescript-fetch-client) - feat: Multisig multilevel subscription in web listener. diff --git a/package-lock.json b/package-lock.json index 2ceeed139b..af254183c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@js-joda/core": "^3.2.0", - "catbuffer-typescript": "^1.0.1-alpha-202111091444", + "catbuffer-typescript": "^1.0.1", "crypto-js": "^4.0.0", "futoin-hkdf": "^1.3.2", "js-sha256": "^0.9.0", @@ -22,7 +22,7 @@ "ripemd160": "^2.0.2", "rxjs": "^6.6.7", "rxjs-compat": "^6.6.3", - "symbol-openapi-typescript-fetch-client": "^1.0.2", + "symbol-openapi-typescript-fetch-client": "^1.0.3", "tweetnacl": "^1.0.3", "utf8": "^2.1.2", "ws": "^7.3.1" @@ -1380,9 +1380,9 @@ "dev": true }, "node_modules/catbuffer-typescript": { - "version": "1.0.1-alpha-202111091444", - "resolved": "https://registry.npmjs.org/catbuffer-typescript/-/catbuffer-typescript-1.0.1-alpha-202111091444.tgz", - "integrity": "sha512-moGTO5sX8a4sP57RuhTUzktbjmX5weZp6F50cWMPFzR4In1SqaNWgPTR98HnHTDEeXAb/o/mog1UMZj5MvHOzQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/catbuffer-typescript/-/catbuffer-typescript-1.0.1.tgz", + "integrity": "sha512-IyC2bmBEMRY96/NMsAer+qMTSa6yAwKfGIbpYPDPnlSb4UguNOlSabbCFH0CDQfhWuO6wqH97xGCuB4qY3OCwA==" }, "node_modules/chai": { "version": "4.2.0", @@ -5728,9 +5728,9 @@ "dev": true }, "node_modules/symbol-openapi-typescript-fetch-client": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-1.0.2.tgz", - "integrity": "sha512-eFfDSr8RHqYaVYdviX30gsfd1VUP3VQV5DLB9kc3yPoFLCOHNO+4rtwItS9rF9xGmICBMB9iR8GDCa6YCTU+WA==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-1.0.3.tgz", + "integrity": "sha512-Md3/wkYLWTeJ/o99kXajW5dDs7Ok7AWfGRGDThb2bpC53KVxwnMl2ho/KUPT2Y+CeuIB62+Hgp9NtJLvgXYzHw==" }, "node_modules/symbol-sdk": { "version": "1.0.1", @@ -7661,9 +7661,9 @@ "dev": true }, "catbuffer-typescript": { - "version": "1.0.1-alpha-202111091444", - "resolved": "https://registry.npmjs.org/catbuffer-typescript/-/catbuffer-typescript-1.0.1-alpha-202111091444.tgz", - "integrity": "sha512-moGTO5sX8a4sP57RuhTUzktbjmX5weZp6F50cWMPFzR4In1SqaNWgPTR98HnHTDEeXAb/o/mog1UMZj5MvHOzQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/catbuffer-typescript/-/catbuffer-typescript-1.0.1.tgz", + "integrity": "sha512-IyC2bmBEMRY96/NMsAer+qMTSa6yAwKfGIbpYPDPnlSb4UguNOlSabbCFH0CDQfhWuO6wqH97xGCuB4qY3OCwA==" }, "chai": { "version": "4.2.0", @@ -11115,9 +11115,9 @@ } }, "symbol-openapi-typescript-fetch-client": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-1.0.2.tgz", - "integrity": "sha512-eFfDSr8RHqYaVYdviX30gsfd1VUP3VQV5DLB9kc3yPoFLCOHNO+4rtwItS9rF9xGmICBMB9iR8GDCa6YCTU+WA==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-1.0.3.tgz", + "integrity": "sha512-Md3/wkYLWTeJ/o99kXajW5dDs7Ok7AWfGRGDThb2bpC53KVxwnMl2ho/KUPT2Y+CeuIB62+Hgp9NtJLvgXYzHw==" }, "symbol-sdk": { "version": "1.0.1", diff --git a/package.json b/package.json index ed232bbf18..a09588666d 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ }, "dependencies": { "@js-joda/core": "^3.2.0", - "catbuffer-typescript": "^1.0.1-alpha-202111091444", + "catbuffer-typescript": "^1.0.1", "crypto-js": "^4.0.0", "futoin-hkdf": "^1.3.2", "js-sha256": "^0.9.0", @@ -106,7 +106,7 @@ "ripemd160": "^2.0.2", "rxjs": "^6.6.7", "rxjs-compat": "^6.6.3", - "symbol-openapi-typescript-fetch-client": "^1.0.2", + "symbol-openapi-typescript-fetch-client": "^1.0.3", "tweetnacl": "^1.0.3", "utf8": "^2.1.2", "ws": "^7.3.1" diff --git a/src/infrastructure/transaction/CreateTransactionFromDTO.ts b/src/infrastructure/transaction/CreateTransactionFromDTO.ts index 36a51b14ef..d40b6ee725 100644 --- a/src/infrastructure/transaction/CreateTransactionFromDTO.ts +++ b/src/infrastructure/transaction/CreateTransactionFromDTO.ts @@ -15,7 +15,7 @@ */ import { Convert as convert } from '../../core/format'; import { UnresolvedMapping } from '../../core/utils'; -import { MessageFactory, TransactionVersion, UInt64 } from '../../model'; +import { MessageFactory, MosaicSupplyRevocationTransaction, UInt64 } from '../../model'; import { Address, PublicAccount } from '../../model/account'; import { Mosaic, MosaicFlags, MosaicId, MosaicNonce } from '../../model/mosaic'; import { NamespaceId } from '../../model/namespace'; @@ -131,366 +131,345 @@ const extractTransactionMeta = (meta: any, id: string): TransactionInfo | Aggreg * @constructor */ const CreateStandaloneTransactionFromDTO = (transactionDTO, transactionInfo, isEmbedded: boolean): Transaction => { - const type: number = transactionDTO.type; + const type: TransactionType = transactionDTO.type; const version: number = transactionDTO.version; const signature = Transaction.resolveSignature(transactionDTO.signature, false); const maxFee = UInt64.fromNumericString(transactionDTO.maxFee || '0'); const deadline = extractDeadline(transactionDTO.deadline); - if (type === TransactionType.TRANSFER) { - return new TransferTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - extractRecipient(transactionDTO.recipientAddress), - extractMosaics(transactionDTO.mosaics), - MessageFactory.createMessageFromHex(transactionDTO.message), - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.NAMESPACE_REGISTRATION) { - return new NamespaceRegistrationTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - transactionDTO.registrationType, - transactionDTO.name, - NamespaceId.createFromEncoded(transactionDTO.id), - transactionDTO.registrationType === 0 ? UInt64.fromNumericString(transactionDTO.duration) : undefined, - transactionDTO.registrationType === 1 ? NamespaceId.createFromEncoded(transactionDTO.parentId) : undefined, - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.MOSAIC_DEFINITION) { - return new MosaicDefinitionTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - MosaicNonce.createFromNumber(transactionDTO.nonce), - new MosaicId(transactionDTO.id), - new MosaicFlags(transactionDTO.flags), - transactionDTO.divisibility, - UInt64.fromNumericString(transactionDTO.duration), - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.MOSAIC_SUPPLY_CHANGE) { - return new MosaicSupplyChangeTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - UnresolvedMapping.toUnresolvedMosaic(transactionDTO.mosaicId), - transactionDTO.action, - UInt64.fromNumericString(transactionDTO.delta), - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.MULTISIG_ACCOUNT_MODIFICATION) { - return new MultisigAccountModificationTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - transactionDTO.minApprovalDelta, - transactionDTO.minRemovalDelta, - transactionDTO.addressAdditions ? transactionDTO.addressAdditions.map((addition) => extractRecipient(addition)) : [], - transactionDTO.addressDeletions ? transactionDTO.addressDeletions.map((deletion) => extractRecipient(deletion)) : [], - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.HASH_LOCK) { - const networkType = transactionDTO.network; - return new LockFundsTransaction( - networkType, - version, - deadline, - maxFee, - new Mosaic(new MosaicId(transactionDTO.mosaicId), UInt64.fromNumericString(transactionDTO.amount)), - UInt64.fromNumericString(transactionDTO.duration), - new SignedTransaction('', transactionDTO.hash, '', TransactionType.AGGREGATE_BONDED, networkType), - signature, - transactionDTO.signerPublicKey ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, networkType) : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.SECRET_LOCK) { - const recipientAddress = transactionDTO.recipientAddress; - const mosaicId = UnresolvedMapping.toUnresolvedMosaic(transactionDTO.mosaicId); - return new SecretLockTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - new Mosaic(mosaicId, UInt64.fromNumericString(transactionDTO.amount)), - UInt64.fromNumericString(transactionDTO.duration), - transactionDTO.hashAlgorithm, - transactionDTO.secret, - extractRecipient(recipientAddress), - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.SECRET_PROOF) { - const recipientAddress = transactionDTO.recipientAddress; - return new SecretProofTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - transactionDTO.hashAlgorithm, - transactionDTO.secret, - extractRecipient(recipientAddress), - transactionDTO.proof, - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.MOSAIC_ALIAS) { - return new MosaicAliasTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - transactionDTO.aliasAction, - NamespaceId.createFromEncoded(transactionDTO.namespaceId), - new MosaicId(transactionDTO.mosaicId), - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.ADDRESS_ALIAS) { - return new AddressAliasTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - transactionDTO.aliasAction, - NamespaceId.createFromEncoded(transactionDTO.namespaceId), - extractRecipient(transactionDTO.address) as Address, - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.ACCOUNT_ADDRESS_RESTRICTION) { - return new AccountAddressRestrictionTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - transactionDTO.restrictionFlags, - transactionDTO.restrictionAdditions ? transactionDTO.restrictionAdditions.map((addition) => extractRecipient(addition)) : [], - transactionDTO.restrictionDeletions ? transactionDTO.restrictionDeletions.map((deletion) => extractRecipient(deletion)) : [], - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.ACCOUNT_OPERATION_RESTRICTION) { - return new AccountOperationRestrictionTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - transactionDTO.restrictionFlags, - transactionDTO.restrictionAdditions ? transactionDTO.restrictionAdditions : [], - transactionDTO.restrictionDeletions ? transactionDTO.restrictionDeletions : [], - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.ACCOUNT_MOSAIC_RESTRICTION) { - return new AccountMosaicRestrictionTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - transactionDTO.restrictionFlags, - transactionDTO.restrictionAdditions - ? transactionDTO.restrictionAdditions.map((addition) => UnresolvedMapping.toUnresolvedMosaic(addition)) - : [], - transactionDTO.restrictionDeletions - ? transactionDTO.restrictionDeletions.map((deletion) => UnresolvedMapping.toUnresolvedMosaic(deletion)) - : [], - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.ACCOUNT_KEY_LINK) { - return new AccountKeyLinkTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - transactionDTO.linkedPublicKey, - transactionDTO.linkAction, - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.MOSAIC_GLOBAL_RESTRICTION) { - return new MosaicGlobalRestrictionTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - UnresolvedMapping.toUnresolvedMosaic(transactionDTO.mosaicId), - UnresolvedMapping.toUnresolvedMosaic(transactionDTO.referenceMosaicId), - UInt64.fromHex(transactionDTO.restrictionKey), - UInt64.fromNumericString(transactionDTO.previousRestrictionValue), - transactionDTO.previousRestrictionType, - UInt64.fromNumericString(transactionDTO.newRestrictionValue), - transactionDTO.newRestrictionType, - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.MOSAIC_ADDRESS_RESTRICTION) { - return new MosaicAddressRestrictionTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - UnresolvedMapping.toUnresolvedMosaic(transactionDTO.mosaicId), - UInt64.fromHex(transactionDTO.restrictionKey), - extractRecipient(transactionDTO.targetAddress), - UInt64.fromNumericString(transactionDTO.previousRestrictionValue), - UInt64.fromNumericString(transactionDTO.newRestrictionValue), - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.ACCOUNT_METADATA) { - return new AccountMetadataTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - extractRecipient(transactionDTO.targetAddress), - UInt64.fromHex(transactionDTO.scopedMetadataKey), - transactionDTO.valueSizeDelta, - convert.decodeHex(transactionDTO.value), - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.MOSAIC_METADATA) { - return new MosaicMetadataTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - extractRecipient(transactionDTO.targetAddress), - UInt64.fromHex(transactionDTO.scopedMetadataKey), - UnresolvedMapping.toUnresolvedMosaic(transactionDTO.targetMosaicId), - transactionDTO.valueSizeDelta, - convert.decodeHex(transactionDTO.value), - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.NAMESPACE_METADATA) { - return new NamespaceMetadataTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - extractRecipient(transactionDTO.targetAddress), - UInt64.fromHex(transactionDTO.scopedMetadataKey), - NamespaceId.createFromEncoded(transactionDTO.targetNamespaceId), - transactionDTO.valueSizeDelta, - convert.decodeHex(transactionDTO.value), - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.VRF_KEY_LINK) { - return new VrfKeyLinkTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - transactionDTO.linkedPublicKey, - transactionDTO.linkAction, - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.NODE_KEY_LINK) { - return new NodeKeyLinkTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - transactionDTO.linkedPublicKey, - transactionDTO.linkAction, - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); - } else if (type === TransactionType.VOTING_KEY_LINK && version == TransactionVersion.VOTING_KEY_LINK) { - return new VotingKeyLinkTransaction( - transactionDTO.network, - version, - deadline, - maxFee, - transactionDTO.linkedPublicKey, - transactionDTO.startEpoch, - transactionDTO.endEpoch, - transactionDTO.linkAction, - signature, - transactionDTO.signerPublicKey - ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, transactionDTO.network) - : undefined, - transactionInfo, - ).setPayloadSize(transactionDTO.size); + const networkType = transactionDTO.network; + const signer = transactionDTO.signerPublicKey + ? PublicAccount.createFromPublicKey(transactionDTO.signerPublicKey, networkType) + : undefined; + switch (type) { + case TransactionType.TRANSFER: + return new TransferTransaction( + networkType, + version, + deadline, + maxFee, + extractRecipient(transactionDTO.recipientAddress), + extractMosaics(transactionDTO.mosaics), + MessageFactory.createMessageFromHex(transactionDTO.message), + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + + case TransactionType.NAMESPACE_REGISTRATION: + return new NamespaceRegistrationTransaction( + networkType, + version, + deadline, + maxFee, + transactionDTO.registrationType, + transactionDTO.name, + NamespaceId.createFromEncoded(transactionDTO.id), + transactionDTO.registrationType === 0 ? UInt64.fromNumericString(transactionDTO.duration) : undefined, + transactionDTO.registrationType === 1 ? NamespaceId.createFromEncoded(transactionDTO.parentId) : undefined, + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.MOSAIC_DEFINITION: + return new MosaicDefinitionTransaction( + networkType, + version, + deadline, + maxFee, + MosaicNonce.createFromNumber(transactionDTO.nonce), + new MosaicId(transactionDTO.id), + new MosaicFlags(transactionDTO.flags), + transactionDTO.divisibility, + UInt64.fromNumericString(transactionDTO.duration), + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.MOSAIC_SUPPLY_CHANGE: + return new MosaicSupplyChangeTransaction( + networkType, + version, + deadline, + maxFee, + UnresolvedMapping.toUnresolvedMosaic(transactionDTO.mosaicId), + transactionDTO.action, + UInt64.fromNumericString(transactionDTO.delta), + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.MOSAIC_SUPPLY_REVOCATION: + return new MosaicSupplyRevocationTransaction( + networkType, + version, + deadline, + maxFee, + extractRecipient(transactionDTO.sourceAddress), + new Mosaic(new MosaicId(transactionDTO.mosaicId), UInt64.fromNumericString(transactionDTO.amount)), + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.MULTISIG_ACCOUNT_MODIFICATION: + return new MultisigAccountModificationTransaction( + networkType, + version, + deadline, + maxFee, + transactionDTO.minApprovalDelta, + transactionDTO.minRemovalDelta, + transactionDTO.addressAdditions ? transactionDTO.addressAdditions.map((addition) => extractRecipient(addition)) : [], + transactionDTO.addressDeletions ? transactionDTO.addressDeletions.map((deletion) => extractRecipient(deletion)) : [], + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.HASH_LOCK: + return new LockFundsTransaction( + networkType, + version, + deadline, + maxFee, + new Mosaic(new MosaicId(transactionDTO.mosaicId), UInt64.fromNumericString(transactionDTO.amount)), + UInt64.fromNumericString(transactionDTO.duration), + new SignedTransaction('', transactionDTO.hash, '', TransactionType.AGGREGATE_BONDED, networkType), + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.SECRET_LOCK: + const recipientAddress = transactionDTO.recipientAddress; + const mosaicId = UnresolvedMapping.toUnresolvedMosaic(transactionDTO.mosaicId); + return new SecretLockTransaction( + networkType, + version, + deadline, + maxFee, + new Mosaic(mosaicId, UInt64.fromNumericString(transactionDTO.amount)), + UInt64.fromNumericString(transactionDTO.duration), + transactionDTO.hashAlgorithm, + transactionDTO.secret, + extractRecipient(recipientAddress), + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.SECRET_PROOF: + return new SecretProofTransaction( + networkType, + version, + deadline, + maxFee, + transactionDTO.hashAlgorithm, + transactionDTO.secret, + extractRecipient(transactionDTO.recipientAddress), + transactionDTO.proof, + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.MOSAIC_ALIAS: + return new MosaicAliasTransaction( + networkType, + version, + deadline, + maxFee, + transactionDTO.aliasAction, + NamespaceId.createFromEncoded(transactionDTO.namespaceId), + new MosaicId(transactionDTO.mosaicId), + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.ADDRESS_ALIAS: + return new AddressAliasTransaction( + networkType, + version, + deadline, + maxFee, + transactionDTO.aliasAction, + NamespaceId.createFromEncoded(transactionDTO.namespaceId), + extractRecipient(transactionDTO.address) as Address, + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.ACCOUNT_ADDRESS_RESTRICTION: + return new AccountAddressRestrictionTransaction( + networkType, + version, + deadline, + maxFee, + transactionDTO.restrictionFlags, + transactionDTO.restrictionAdditions + ? transactionDTO.restrictionAdditions.map((addition) => extractRecipient(addition)) + : [], + transactionDTO.restrictionDeletions + ? transactionDTO.restrictionDeletions.map((deletion) => extractRecipient(deletion)) + : [], + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.ACCOUNT_OPERATION_RESTRICTION: + return new AccountOperationRestrictionTransaction( + networkType, + version, + deadline, + maxFee, + transactionDTO.restrictionFlags, + transactionDTO.restrictionAdditions ? transactionDTO.restrictionAdditions : [], + transactionDTO.restrictionDeletions ? transactionDTO.restrictionDeletions : [], + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.ACCOUNT_MOSAIC_RESTRICTION: + return new AccountMosaicRestrictionTransaction( + networkType, + version, + deadline, + maxFee, + transactionDTO.restrictionFlags, + transactionDTO.restrictionAdditions + ? transactionDTO.restrictionAdditions.map((addition) => UnresolvedMapping.toUnresolvedMosaic(addition)) + : [], + transactionDTO.restrictionDeletions + ? transactionDTO.restrictionDeletions.map((deletion) => UnresolvedMapping.toUnresolvedMosaic(deletion)) + : [], + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.ACCOUNT_KEY_LINK: + return new AccountKeyLinkTransaction( + networkType, + version, + deadline, + maxFee, + transactionDTO.linkedPublicKey, + transactionDTO.linkAction, + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.MOSAIC_GLOBAL_RESTRICTION: + return new MosaicGlobalRestrictionTransaction( + networkType, + version, + deadline, + maxFee, + UnresolvedMapping.toUnresolvedMosaic(transactionDTO.mosaicId), + UnresolvedMapping.toUnresolvedMosaic(transactionDTO.referenceMosaicId), + UInt64.fromHex(transactionDTO.restrictionKey), + UInt64.fromNumericString(transactionDTO.previousRestrictionValue), + transactionDTO.previousRestrictionType, + UInt64.fromNumericString(transactionDTO.newRestrictionValue), + transactionDTO.newRestrictionType, + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.MOSAIC_ADDRESS_RESTRICTION: + return new MosaicAddressRestrictionTransaction( + networkType, + version, + deadline, + maxFee, + UnresolvedMapping.toUnresolvedMosaic(transactionDTO.mosaicId), + UInt64.fromHex(transactionDTO.restrictionKey), + extractRecipient(transactionDTO.targetAddress), + UInt64.fromNumericString(transactionDTO.previousRestrictionValue), + UInt64.fromNumericString(transactionDTO.newRestrictionValue), + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.ACCOUNT_METADATA: + return new AccountMetadataTransaction( + networkType, + version, + deadline, + maxFee, + extractRecipient(transactionDTO.targetAddress), + UInt64.fromHex(transactionDTO.scopedMetadataKey), + transactionDTO.valueSizeDelta, + convert.decodeHex(transactionDTO.value), + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.MOSAIC_METADATA: + return new MosaicMetadataTransaction( + networkType, + version, + deadline, + maxFee, + extractRecipient(transactionDTO.targetAddress), + UInt64.fromHex(transactionDTO.scopedMetadataKey), + UnresolvedMapping.toUnresolvedMosaic(transactionDTO.targetMosaicId), + transactionDTO.valueSizeDelta, + convert.decodeHex(transactionDTO.value), + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.NAMESPACE_METADATA: + return new NamespaceMetadataTransaction( + networkType, + version, + deadline, + maxFee, + extractRecipient(transactionDTO.targetAddress), + UInt64.fromHex(transactionDTO.scopedMetadataKey), + NamespaceId.createFromEncoded(transactionDTO.targetNamespaceId), + transactionDTO.valueSizeDelta, + convert.decodeHex(transactionDTO.value), + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.VRF_KEY_LINK: + return new VrfKeyLinkTransaction( + networkType, + version, + deadline, + maxFee, + transactionDTO.linkedPublicKey, + transactionDTO.linkAction, + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.NODE_KEY_LINK: + return new NodeKeyLinkTransaction( + networkType, + version, + deadline, + maxFee, + transactionDTO.linkedPublicKey, + transactionDTO.linkAction, + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + case TransactionType.VOTING_KEY_LINK: + return new VotingKeyLinkTransaction( + networkType, + version, + deadline, + maxFee, + transactionDTO.linkedPublicKey, + transactionDTO.startEpoch, + transactionDTO.endEpoch, + transactionDTO.linkAction, + signature, + signer, + transactionInfo, + ).setPayloadSize(transactionDTO.size); + default: + throw new Error(`Unimplemented transaction with type ${type} for version ${version}`); } - throw new Error(`Unimplemented transaction with type ${type} for version ${version}`); }; /** diff --git a/src/infrastructure/transaction/CreateTransactionFromPayload.ts b/src/infrastructure/transaction/CreateTransactionFromPayload.ts index 0c5a41aea5..ca2506ede3 100644 --- a/src/infrastructure/transaction/CreateTransactionFromPayload.ts +++ b/src/infrastructure/transaction/CreateTransactionFromPayload.ts @@ -32,6 +32,7 @@ import { MosaicGlobalRestrictionTransaction, MosaicMetadataTransaction, MosaicSupplyChangeTransaction, + MosaicSupplyRevocationTransaction, MultisigAccountModificationTransaction, NamespaceMetadataTransaction, NamespaceRegistrationTransaction, @@ -99,6 +100,8 @@ export const CreateTransactionFromPayload = (payload: string, isEmbedded = false return NamespaceMetadataTransaction.createFromPayload(payload, isEmbedded); } else if (type === TransactionType.VRF_KEY_LINK) { return VrfKeyLinkTransaction.createFromPayload(payload, isEmbedded); + } else if (type === TransactionType.MOSAIC_SUPPLY_REVOCATION) { + return MosaicSupplyRevocationTransaction.createFromPayload(payload, isEmbedded); } else if (type === TransactionType.NODE_KEY_LINK) { return NodeKeyLinkTransaction.createFromPayload(payload, isEmbedded); } else if (type === TransactionType.VOTING_KEY_LINK && version == TransactionVersion.VOTING_KEY_LINK) { diff --git a/src/infrastructure/transaction/SerializeTransactionToJSON.ts b/src/infrastructure/transaction/SerializeTransactionToJSON.ts index 142c548f3a..a727702b48 100644 --- a/src/infrastructure/transaction/SerializeTransactionToJSON.ts +++ b/src/infrastructure/transaction/SerializeTransactionToJSON.ts @@ -30,6 +30,7 @@ import { MosaicGlobalRestrictionTransaction, MosaicMetadataTransaction, MosaicSupplyChangeTransaction, + MosaicSupplyRevocationTransaction, MultisigAccountModificationTransaction, NamespaceMetadataTransaction, NamespaceRegistrationTransaction, @@ -157,6 +158,13 @@ export const SerializeTransactionToJSON = (transaction: Transaction): any => { action: mosaicSupplyTx.action, delta: mosaicSupplyTx.delta.toString(), }; + } else if (transaction.type === TransactionType.MOSAIC_SUPPLY_REVOCATION) { + const mosaicSupplyTx = transaction as MosaicSupplyRevocationTransaction; + return { + sourceAddress: mosaicSupplyTx.sourceAddress.toDTO(), + mosaicId: mosaicSupplyTx.mosaic.id.toHex(), + amount: mosaicSupplyTx.mosaic.amount.toString(), + }; } else if (transaction.type === TransactionType.NAMESPACE_REGISTRATION) { const namespaceTx = transaction as NamespaceRegistrationTransaction; const registerNamespaceDuration = namespaceTx.duration; diff --git a/src/model/mosaic/MosaicFlags.ts b/src/model/mosaic/MosaicFlags.ts index 26c526be59..0f41365eb8 100644 --- a/src/model/mosaic/MosaicFlags.ts +++ b/src/model/mosaic/MosaicFlags.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import { MosaicFlagsDto } from 'catbuffer-typescript'; + /** * Mosaic flags model */ @@ -39,17 +41,20 @@ export class MosaicFlags { * property appears disabled by default, as it is undesirable for autonomous tokens like the public network currency. */ public readonly restrictable: boolean; + + /** + * The creator can choose if he can revoke tokens after a transfer. + */ + public readonly revokable: boolean; + /** * @param flags - * @param divisibility - * @param duration */ constructor(flags: number) { - let binaryFlags = '00' + (flags >>> 0).toString(2); - binaryFlags = binaryFlags.substr(binaryFlags.length - 3, 3); - this.supplyMutable = binaryFlags[2] === '1'; - this.transferable = binaryFlags[1] === '1'; - this.restrictable = binaryFlags[0] === '1'; + this.supplyMutable = (flags & MosaicFlagsDto.SUPPLY_MUTABLE) !== 0; + this.transferable = (flags & MosaicFlagsDto.TRANSFERABLE) !== 0; + this.restrictable = (flags & MosaicFlagsDto.RESTRICTABLE) !== 0; + this.revokable = (flags & MosaicFlagsDto.REVOKABLE) !== 0; } /** @@ -58,9 +63,15 @@ export class MosaicFlags { * @param supplyMutable * @param transferable * @param restrictable + * @param revokable */ - public static create(supplyMutable: boolean, transferable: boolean, restrictable = false): MosaicFlags { - const flags = (supplyMutable ? 1 : 0) + (transferable ? 2 : 0) + (restrictable ? 4 : 0); + public static create(supplyMutable: boolean, transferable: boolean, restrictable = false, revokable = false): MosaicFlags { + const flags = this.toFlag({ + supplyMutable: supplyMutable, + transferable: transferable, + restrictable: restrictable, + revokable: revokable, + }); return new MosaicFlags(flags); } @@ -69,7 +80,7 @@ export class MosaicFlags { * @returns {number} */ public getValue(): number { - return (this.supplyMutable ? 1 : 0) + (this.transferable ? 2 : 0) + (this.restrictable ? 4 : 0); + return MosaicFlags.toFlag(this); } /** @@ -80,4 +91,27 @@ export class MosaicFlags { flags: this.getValue(), }; } + + /** + * It "adds up" individual flags into a bit wise number flag. + * + * @param supplyMutable - if the supply is mutable. First flag. + * @param transferable - if the balance can be transferred. Second flag. + * @param restrictable - if the transaction can be restricted. Third flag. + * @param revokable - if the balance can be revoked. Fourth flag. + * @private + */ + private static toFlag({ + supplyMutable, + transferable, + restrictable, + revokable, + }: { + supplyMutable: boolean; + transferable: boolean; + restrictable: boolean; + revokable: boolean; + }): number { + return (supplyMutable ? 1 : 0) + (transferable ? 2 : 0) + (restrictable ? 4 : 0) + (revokable ? 8 : 0); + } } diff --git a/src/model/transaction/MosaicSupplyRevocationTransaction.ts b/src/model/transaction/MosaicSupplyRevocationTransaction.ts new file mode 100644 index 0000000000..34b7a6ff3b --- /dev/null +++ b/src/model/transaction/MosaicSupplyRevocationTransaction.ts @@ -0,0 +1,220 @@ +/* + * Copyright 2021 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 { + AmountDto, + EmbeddedMosaicSupplyRevocationTransactionBuilder, + EmbeddedTransactionBuilder, + MosaicSupplyRevocationTransactionBuilder, + TimestampDto, + TransactionBuilder, + UnresolvedAddressDto, + UnresolvedMosaicBuilder, + UnresolvedMosaicIdDto, +} from 'catbuffer-typescript'; +import { DtoMapping } from '../../core'; +import { Convert } from '../../core/format'; +import { UnresolvedMapping } from '../../core/utils/UnresolvedMapping'; +import { Address } from '../account'; +import { PublicAccount } from '../account/PublicAccount'; +import { UnresolvedAddress } from '../account/UnresolvedAddress'; +import { Mosaic } from '../mosaic'; +import { NetworkType } from '../network/NetworkType'; +import { Statement } from '../receipt'; +import { UInt64 } from '../UInt64'; +import { Deadline } from './Deadline'; +import { InnerTransaction } from './InnerTransaction'; +import { Transaction } from './Transaction'; +import { TransactionInfo } from './TransactionInfo'; +import { TransactionType } from './TransactionType'; +import { TransactionVersion } from './TransactionVersion'; + +/** + * Creators of a revokable mosaic will be able to recall any and all balances from any holders. Holders of these mosaics implicitly place trust in the issuer. + * The mosaic issuer can revoke and recall balances using this transaction. + */ +export class MosaicSupplyRevocationTransaction extends Transaction { + /** + * Create a mosaic supply revocation transaction object + * @param deadline - The deadline to include the transaction. + * @param sourceAddress - Address from which tokens should be revoked. + * @param mosaic - Revoked mosaic and amount. + * @param networkType - The network type. + * @param maxFee - (Optional) Max fee defined by the sender + * @param signature - (Optional) Transaction signature + * @param signer - (Optional) Signer public account + * @returns {MosaicSupplyRevocationTransaction} + */ + public static create( + deadline: Deadline, + sourceAddress: UnresolvedAddress, + mosaic: Mosaic, + networkType: NetworkType, + maxFee: UInt64 = new UInt64([0, 0]), + signature?: string, + signer?: PublicAccount, + ): MosaicSupplyRevocationTransaction { + return new MosaicSupplyRevocationTransaction( + networkType, + TransactionVersion.MOSAIC_SUPPLY_REVOCATION, + deadline, + maxFee, + sourceAddress, + mosaic, + signature, + signer, + ); + } + + /** + * @param networkType + * @param version + * @param deadline + * @param maxFee + * @param sourceAddress + * @param mosaic + * @param signature + * @param signer + * @param transactionInfo + */ + constructor( + networkType: NetworkType, + version: number, + deadline: Deadline, + maxFee: UInt64, + /** + * Address from which tokens should be revoked. + */ + public readonly sourceAddress: UnresolvedAddress, + /** + * Revoked mosaic and amount. + */ + public readonly mosaic: Mosaic, + + signature?: string, + signer?: PublicAccount, + transactionInfo?: TransactionInfo, + ) { + super(TransactionType.MOSAIC_SUPPLY_REVOCATION, networkType, version, deadline, maxFee, signature, signer, transactionInfo); + } + + /** + * Create a transaction object from payload + * @param {string} payload Binary payload + * @param {Boolean} isEmbedded Is embedded transaction (Default: false) + * @returns {Transaction | InnerTransaction} + */ + public static createFromPayload(payload: string, isEmbedded = false): Transaction | InnerTransaction { + const builder = isEmbedded + ? EmbeddedMosaicSupplyRevocationTransactionBuilder.loadFromBinary(Convert.hexToUint8(payload)) + : MosaicSupplyRevocationTransactionBuilder.loadFromBinary(Convert.hexToUint8(payload)); + const mosaicBuilder = builder.getMosaic(); + const id = new UInt64(mosaicBuilder.mosaicId.unresolvedMosaicId).toHex(); + const mosaic = new Mosaic(UnresolvedMapping.toUnresolvedMosaic(id), new UInt64(mosaicBuilder.amount.amount)); + const signerPublicKey = Convert.uint8ToHex(builder.getSignerPublicKey().publicKey); + const networkType = builder.getNetwork().valueOf(); + const signature = Transaction.getSignatureFromPayload(payload, isEmbedded); + const deadline = isEmbedded + ? Deadline.createEmtpy() + : Deadline.createFromDTO((builder as MosaicSupplyRevocationTransactionBuilder).getDeadline().timestamp); + const transaction = MosaicSupplyRevocationTransaction.create( + deadline, + UnresolvedMapping.toUnresolvedAddress(Convert.uint8ToHex(builder.getSourceAddress().unresolvedAddress)), + mosaic, + networkType, + isEmbedded ? new UInt64([0, 0]) : new UInt64((builder as MosaicSupplyRevocationTransactionBuilder).fee.amount), + signature, + signerPublicKey.match(`^[0]+$`) ? undefined : PublicAccount.createFromPublicKey(signerPublicKey, networkType), + ); + return isEmbedded ? transaction.toAggregate(PublicAccount.createFromPublicKey(signerPublicKey, networkType)) : transaction; + } + + /** + * @internal + * @returns {TransactionBuilder} + */ + protected createBuilder(): TransactionBuilder { + const mosaicBuilder = new UnresolvedMosaicBuilder( + new UnresolvedMosaicIdDto(this.mosaic.id.id.toDTO()), + new AmountDto(this.mosaic.amount.toDTO()), + ); + + return new MosaicSupplyRevocationTransactionBuilder( + this.getSignatureAsBuilder(), + this.getSignerAsBuilder(), + this.versionToDTO(), + this.networkType.valueOf(), + this.type.valueOf(), + new AmountDto(this.maxFee.toDTO()), + new TimestampDto(this.deadline.toDTO()), + new UnresolvedAddressDto(this.sourceAddress.encodeUnresolvedAddress(this.networkType)), + mosaicBuilder, + ); + } + + /** + * @internal + * @returns {EmbeddedTransactionBuilder} + */ + public toEmbeddedTransaction(): EmbeddedTransactionBuilder { + const mosaicBuilder = new UnresolvedMosaicBuilder( + new UnresolvedMosaicIdDto(this.mosaic.id.id.toDTO()), + new AmountDto(this.mosaic.amount.toDTO()), + ); + return new EmbeddedMosaicSupplyRevocationTransactionBuilder( + this.getSignerAsBuilder(), + this.versionToDTO(), + this.networkType.valueOf(), + this.type.valueOf(), + new UnresolvedAddressDto(this.sourceAddress.encodeUnresolvedAddress(this.networkType)), + mosaicBuilder, + ); + } + + /** + * @internal + * @param statement Block receipt statement + * @param aggregateTransactionIndex Transaction index for aggregated transaction + * @returns {MosaicSupplyRevocationTransaction} + */ + resolveAliases(statement: Statement, aggregateTransactionIndex = 0): MosaicSupplyRevocationTransaction { + const transactionInfo = this.checkTransactionHeightAndIndex(); + return DtoMapping.assign(this, { + sourceAddress: statement.resolveAddress( + this.sourceAddress, + transactionInfo.height.toString(), + transactionInfo.index, + aggregateTransactionIndex, + ), + mosaic: statement.resolveMosaic( + this.mosaic, + transactionInfo.height.toString(), + transactionInfo.index, + aggregateTransactionIndex, + ), + }); + } + + /** + * @internal + * Check a given address should be notified in websocket channels + * @param address address to be notified + * @returns {boolean} + */ + public shouldNotifyAccount(address: Address): boolean { + return super.isSigned(address); + } +} diff --git a/src/model/transaction/TransactionType.ts b/src/model/transaction/TransactionType.ts index 57170ea0ae..b6a2f88501 100644 --- a/src/model/transaction/TransactionType.ts +++ b/src/model/transaction/TransactionType.ts @@ -56,6 +56,12 @@ export enum TransactionType { */ MOSAIC_SUPPLY_CHANGE = 16973, + /** + * Mosaic supply revocation transaction. + * @type {number} + */ + MOSAIC_SUPPLY_REVOCATION = 17229, + /** * Modify multisig account transaction type. * @type {number} diff --git a/src/model/transaction/TransactionVersion.ts b/src/model/transaction/TransactionVersion.ts index 150f6ac0eb..f5dca8f07e 100644 --- a/src/model/transaction/TransactionVersion.ts +++ b/src/model/transaction/TransactionVersion.ts @@ -50,6 +50,11 @@ export class TransactionVersion { */ public static readonly MOSAIC_SUPPLY_CHANGE = 1; + /** + * Mosaic supply revocation transaction. + * @type {number} + */ + public static readonly MOSAIC_SUPPLY_REVOCATION = 1; /** * Modify multisig account transaction version. * @type {number} diff --git a/src/model/transaction/index.ts b/src/model/transaction/index.ts index 69baa2e8f6..7cf33b1cab 100644 --- a/src/model/transaction/index.ts +++ b/src/model/transaction/index.ts @@ -26,6 +26,7 @@ export * from './MosaicDefinitionTransaction'; export * from './MosaicGlobalRestrictionTransaction'; export * from './MosaicMetadataTransaction'; export * from './MosaicSupplyChangeTransaction'; +export * from './MosaicSupplyRevocationTransaction'; export * from './MultisigAccountModificationTransaction'; export * from './MultisigCosignatoryModification'; export * from './NamespaceMetadataTransaction'; diff --git a/test/core/utils/TransactionMapping.spec.ts b/test/core/utils/TransactionMapping.spec.ts index a772272a64..5759b3b7fb 100644 --- a/test/core/utils/TransactionMapping.spec.ts +++ b/test/core/utils/TransactionMapping.spec.ts @@ -19,7 +19,14 @@ import { expect } from 'chai'; import { sha3_256 } from 'js-sha3'; import { Convert } from '../../../src/core/format'; import { DtoMapping, TransactionMapping } from '../../../src/core/utils'; -import { MessageMarker, Transaction, TransactionVersion, UInt64, VotingKeyLinkTransaction } from '../../../src/model'; +import { + MessageMarker, + MosaicSupplyRevocationTransaction, + Transaction, + TransactionVersion, + UInt64, + VotingKeyLinkTransaction, +} from '../../../src/model'; import { Account, Address } from '../../../src/model/account'; import { LockHashAlgorithm } from '../../../src/model/lock'; import { EncryptedMessage, MessageType, PlainMessage } from '../../../src/model/message'; @@ -554,6 +561,12 @@ describe('TransactionMapping - createFromPayload', () => { 'B778A39A3663719DFC5E48C9D78431B1E45C2AF9DF538782BF199C189DABEAC7', TestNetworkType, ); + const mosaicSupplyRevocationTransaction = MosaicSupplyRevocationTransaction.create( + Deadline.createFromDTO('0'), + account.address, + new Mosaic(new MosaicId('0DC67FBE1CAD29E5'), UInt64.fromUint(5)), + NetworkType.TEST_NET, + ); const aggregateTransaction = AggregateTransaction.createComplete( Deadline.createFromDTO('555'), @@ -571,6 +584,7 @@ describe('TransactionMapping - createFromPayload', () => { accountMetadataTransaction.toAggregate(account.publicAccount), mosaicAliasTransaction.toAggregate(account.publicAccount), secretProofTransaction.toAggregate(account.publicAccount), + mosaicSupplyRevocationTransaction.toAggregate(account.publicAccount), ], TestNetworkType, [], @@ -582,10 +596,10 @@ describe('TransactionMapping - createFromPayload', () => { expect(transaction.type).to.be.equal(TransactionType.AGGREGATE_COMPLETE); expect(transaction.innerTransactions[0].type).to.be.equal(TransactionType.TRANSFER); - expect(transaction.innerTransactions.length).to.be.greaterThan(0); + expect(transaction.innerTransactions.length).to.be.equal(14); const expectedHex = - '9805000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198414100000000000000002B0200000000000098FECC65D1B258AF155772919F9CF2BBB3FFDB3802CA8682A8B81ACBBEA6DEA6F0040000000000005D000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019854419826D27E1D0A26CA4E316F901E23E55C8711DB20DFD267760D0000000000000000746573742D6D65737361676500000051000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F0000000001984C412E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F010000000000000051000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019843422E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F010000000000000051000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F0000000001984C422E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F010000000000000059000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F0000000001984341C614558647D02037384A2FECA80ACE95B235D9B9D90035FA46102FE79ECCBA750100000003000000010000000000000055000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F0000000001984E41E803000000000000CFCBE72D994BE69B0013726F6F742D746573742D6E616D6573706163650000005A000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F0000000001985141010000000000000000000000000000005C1100000000000000000000000000000000000000000000000600000000000068000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019851426EC265194C0501D45C11000000000000000000000000000000000000000000009826D27E1D0A26CA4E316F901E23E55C8711DB20DFD2677666000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019844429826D27E1D0A26CA4E316F901E23E55C8711DB20DFD26776E8030000000000004CCCD78612DDF5CA01000A0000000000000000000000000066000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019844439826D27E1D0A26CA4E316F901E23E55C8711DB20DFD26776E8030000000000004CCCD78612DDF5CA01000A000000000000000000000000005E000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019844419826D27E1D0A26CA4E316F901E23E55C8711DB20DFD26776E80300000000000001000A0000000000000000000000000041000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F0000000001984E434CCCD78612DDF5CA4CCCD78612DDF5CA01000000000000008B000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019852429826D27E1D0A26CA4E316F901E23E55C8711DB20DFD267769B3155B37159DA50AA52D5967C509B410F5A36A3B1E31ECB5AC76675D79B4A5E200000B778A39A3663719DFC5E48C9D78431B1E45C2AF9DF538782BF199C189DABEAC70000000000'; + 'F005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198414100000000000000002B0200000000000098FECC65D1B258AF155772919F9CF2BBB3FFDB3802CA8682A8B81ACBBEA6DEA648050000000000005D000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019854419826D27E1D0A26CA4E316F901E23E55C8711DB20DFD267760D0000000000000000746573742D6D65737361676500000051000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F0000000001984C412E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F010000000000000051000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019843422E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F010000000000000051000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F0000000001984C422E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F010000000000000059000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F0000000001984341C614558647D02037384A2FECA80ACE95B235D9B9D90035FA46102FE79ECCBA750100000003000000010000000000000055000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F0000000001984E41E803000000000000CFCBE72D994BE69B0013726F6F742D746573742D6E616D6573706163650000005A000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F0000000001985141010000000000000000000000000000005C1100000000000000000000000000000000000000000000000600000000000068000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019851426EC265194C0501D45C11000000000000000000000000000000000000000000009826D27E1D0A26CA4E316F901E23E55C8711DB20DFD2677666000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019844429826D27E1D0A26CA4E316F901E23E55C8711DB20DFD26776E8030000000000004CCCD78612DDF5CA01000A0000000000000000000000000066000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019844439826D27E1D0A26CA4E316F901E23E55C8711DB20DFD26776E8030000000000004CCCD78612DDF5CA01000A000000000000000000000000005E000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019844419826D27E1D0A26CA4E316F901E23E55C8711DB20DFD26776E80300000000000001000A0000000000000000000000000041000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F0000000001984E434CCCD78612DDF5CA4CCCD78612DDF5CA01000000000000008B000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F00000000019852429826D27E1D0A26CA4E316F901E23E55C8711DB20DFD267769B3155B37159DA50AA52D5967C509B410F5A36A3B1E31ECB5AC76675D79B4A5E200000B778A39A3663719DFC5E48C9D78431B1E45C2AF9DF538782BF199C189DABEAC7000000000058000000000000002E834140FD66CF87B254A693A2C7862C819217B676D3943267156625E816EC6F0000000001984D439826D27E1D0A26CA4E316F901E23E55C8711DB20DFD26776E529AD1CBE7FC60D0500000000000000'; assertSerialization(aggregateTransaction, expectedHex); }); @@ -1616,4 +1630,18 @@ describe('TransactionMapping - createFromDTO (Transaction.toJSON() feed)', () => 'CBD67E2DBA5D69157CE32874EFDD680E41B1BFFD12B781F84E8AD883920BBB50EA38AFE078E99EE5EE4BDFDA77E8C101EBD3100C0D471673471A61B23E513FC7E21F7803316B906A688F14AA75002913A3B57DD13469BC27CF8C82FD5C4C76867011AEDC7C4870D8C5AF9C175F0DA5A8E2AD3A327D868BFBA34A5E3D', ); }); + + it('should serialize, deserialize top level MosaicSupplyRevocationTransaction', () => { + const mosaicId = new MosaicId('0DC67FBE1CAD29E5'); + const transaction = MosaicSupplyRevocationTransaction.create( + Deadline.createFromDTO('100'), + account.address, + new Mosaic(mosaicId, UInt64.fromUint(5)), + NetworkType.TEST_NET, + ); + + const expectedPayload = + 'A8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001984D43000000000000000064000000000000009826D27E1D0A26CA4E316F901E23E55C8711DB20DFD26776E529AD1CBE7FC60D0500000000000000'; + assertSerialization(transaction, expectedPayload); + }); }); diff --git a/test/infrastructure/SerializeTransactionToJSON.spec.ts b/test/infrastructure/SerializeTransactionToJSON.spec.ts index ea0892b3f1..12c5c32a2b 100644 --- a/test/infrastructure/SerializeTransactionToJSON.spec.ts +++ b/test/infrastructure/SerializeTransactionToJSON.spec.ts @@ -19,7 +19,7 @@ import { sha3_256 } from 'js-sha3'; import { Crypto } from '../../src/core/crypto'; import { Convert as convert, Convert } from '../../src/core/format'; import { TransactionMapping } from '../../src/core/utils'; -import { Transaction, TransactionVersion, UInt64 } from '../../src/model'; +import { Mosaic, MosaicSupplyRevocationTransaction, Transaction, TransactionVersion, UInt64 } from '../../src/model'; import { Account, Address } from '../../src/model/account'; import { LockHashAlgorithm } from '../../src/model/lock'; import { PlainMessage } from '../../src/model/message'; @@ -217,6 +217,22 @@ describe('SerializeTransactionToJSON', () => { expect(json.transaction.action).to.be.equal(MosaicSupplyChangeAction.Increase); }); + it('should create MosaicSupplyRevocationTransaction', () => { + const mosaicId = new MosaicId('0DC67FBE1CAD29E5'); + const transaction = MosaicSupplyRevocationTransaction.create( + Deadline.createFromDTO('100'), + account.address, + new Mosaic(mosaicId, UInt64.fromUint(5)), + NetworkType.TEST_NET, + ); + + const json = validateToFromJson(transaction); + expect(json.transaction.version).to.be.equal(1); + expect(json.transaction.type).to.be.equal(TransactionType.MOSAIC_SUPPLY_REVOCATION); + expect(json.transaction.mosaicId).to.be.equal(mosaicId.toHex()); + expect(json.transaction.sourceAddress.address).to.be.equal(account.address.plain()); + }); + it('should create TransferTransaction', () => { const mosaic = NetworkCurrencyLocal.createRelative(100); const transferTransaction = TransferTransaction.create( diff --git a/test/infrastructure/transaction/CreateTransactionFromDTO.spec.ts b/test/infrastructure/transaction/CreateTransactionFromDTO.spec.ts index aa9b20bda8..9f52514a67 100644 --- a/test/infrastructure/transaction/CreateTransactionFromDTO.spec.ts +++ b/test/infrastructure/transaction/CreateTransactionFromDTO.spec.ts @@ -15,6 +15,7 @@ */ import { LocalDateTime } from '@js-joda/core'; import { deepEqual } from 'assert'; +import { TransactionTypeDto } from 'catbuffer-typescript'; import { expect } from 'chai'; import { NamespaceRegistrationTypeEnum, TransactionInfoDTO, TransferTransactionDTO } from 'symbol-openapi-typescript-fetch-client'; import { CreateTransactionFromDTO } from '../../../src/infrastructure/transaction'; @@ -571,6 +572,41 @@ describe('CreateTransactionFromDTO', () => { }); }); + describe('MosaicSupplyRevocationTransaction', () => { + it('standalone', () => { + const dto: TransactionInfoDTO = { + meta: { + height: '212', + hash: '700E495D9E57B5701B3009BF02F522A9C1D7B15ECBBA65B3BD6F52A79EBBC7EB', + merkleComponentHash: '700E495D9E57B5701B3009BF02F522A9C1D7B15ECBBA65B3BD6F52A79EBBC7EB', + index: 0, + timestamp: '62955743775', + feeMultiplier: 11904, + }, + transaction: { + size: 168, + signature: + '6F2FE34C6F09E8C4FB98569831E46A274809CA2D18405E811A0480EEC424C8034D51B65C692CA36BC0533733E4C7B83076B9F9B2FE439314B74E4AD78B36100F', + signerPublicKey: '5AB0BC217283542BF3BC45570FCC5C7232825B8DDDFBFF1F9CA06747BB939F92', + version: 1, + network: 152, + type: 17229, + maxFee: '2000000', + deadline: '62962930644', + sourceAddress: '986E584F3CE223A494D3444BDCA4A425AECED2B1C3318DF1', + mosaicId: '6CEE17786759C983', + amount: '1', + }, + id: '61894560E8034A392B5FD905', + }; + + const transaction = CreateTransactionFromDTO(dto); + expect(transaction.type).eq(TransactionTypeDto.MOSAIC_SUPPLY_REVOCATION); + + ValidateTransaction.validateStandaloneTx(transaction, dto); + }); + }); + describe('MultisigAccountModificationTransaction', () => { it('standalone', () => { const modifyMultisigAccountTransactionDTO = { diff --git a/test/infrastructure/transaction/ValidateTransaction.ts b/test/infrastructure/transaction/ValidateTransaction.ts index 1a6c41525d..f9c73bfc50 100644 --- a/test/infrastructure/transaction/ValidateTransaction.ts +++ b/test/infrastructure/transaction/ValidateTransaction.ts @@ -46,6 +46,8 @@ const ValidateTransaction = { ValidateTransaction.validateMosaicCreationTx(transaction, transactionDTO); } else if (transaction.type === TransactionType.MOSAIC_SUPPLY_CHANGE) { ValidateTransaction.validateMosaicSupplyChangeTx(transaction, transactionDTO); + } else if (transaction.type === TransactionType.MOSAIC_SUPPLY_REVOCATION) { + ValidateTransaction.validateMosaicSupplyRevocationTx(transaction, transactionDTO); } else if (transaction.type === TransactionType.MULTISIG_ACCOUNT_MODIFICATION) { ValidateTransaction.validateMultisigModificationTx(transaction, transactionDTO); } @@ -83,6 +85,12 @@ const ValidateTransaction = { expect(mosaicSupplyChangeTransaction.action).to.be.equal(mosaicSupplyChangeTransactionDTO.transaction.action); deepEqual(mosaicSupplyChangeTransaction.delta, UInt64.fromNumericString(mosaicSupplyChangeTransactionDTO.transaction.delta)); }, + validateMosaicSupplyRevocationTx: (mosaicSupplyRevocationTransaction: any, mosaicSupplyRevocationTransactionDTO: any): void => { + deepEqual(mosaicSupplyRevocationTransaction.mosaic.id, new MosaicId(mosaicSupplyRevocationTransactionDTO.transaction.mosaicId)); + expect(mosaicSupplyRevocationTransaction.sourceAddress.encoded()).to.be.equal( + mosaicSupplyRevocationTransactionDTO.transaction.sourceAddress, + ); + }, validateMultisigModificationTx: (modifyMultisigAccountTransaction: any, modifyMultisigAccountTransactionDTO: any): void => { expect(modifyMultisigAccountTransaction.minApprovalDelta).to.be.equal( modifyMultisigAccountTransactionDTO.transaction.minApprovalDelta, diff --git a/test/model/mosaic/MosaicFlags.spec.ts b/test/model/mosaic/MosaicFlags.spec.ts index 3f60af5a3e..47f9d70602 100644 --- a/test/model/mosaic/MosaicFlags.spec.ts +++ b/test/model/mosaic/MosaicFlags.spec.ts @@ -18,46 +18,46 @@ import { expect } from 'chai'; import { MosaicFlags } from '../../../src/model/mosaic/MosaicFlags'; describe('MosaicFlags', () => { - it('should createComplete an MosaicFlags object with constructor', () => { - const mosaicFlags = new MosaicFlags(7); - expect(mosaicFlags.supplyMutable).to.be.equal(true); - expect(mosaicFlags.transferable).to.be.equal(true); - expect(mosaicFlags.restrictable).to.be.equal(true); - }); - - it('should createComplete an mosaicFlags object with static method', () => { - const mosaicFlags = MosaicFlags.create(false, false, false); - - expect(mosaicFlags.supplyMutable).to.be.equal(false); - expect(mosaicFlags.transferable).to.be.equal(false); - expect(mosaicFlags.restrictable).to.be.equal(false); - }); - - it('should return corredt flags value', () => { - let mosaicFlags = MosaicFlags.create(false, false, false); - expect(mosaicFlags.getValue()).to.be.equal(0); - - mosaicFlags = MosaicFlags.create(true, false, false); - expect(mosaicFlags.getValue()).to.be.equal(1); - - mosaicFlags = MosaicFlags.create(false, true, false); - expect(mosaicFlags.getValue()).to.be.equal(2); - - mosaicFlags = MosaicFlags.create(false, false, true); - expect(mosaicFlags.getValue()).to.be.equal(4); - - mosaicFlags = MosaicFlags.create(true, true, true); - expect(mosaicFlags.getValue()).to.be.equal(7); - - mosaicFlags = MosaicFlags.create(true, false, true); - expect(mosaicFlags.getValue()).to.be.equal(5); - - mosaicFlags = MosaicFlags.create(true, true, false); - expect(mosaicFlags.getValue()).to.be.equal(3); - }); - - it('should return corredt flags json object', () => { - const mosaicFlags = MosaicFlags.create(true, true, true); - expect(mosaicFlags.toDTO().flags).to.be.equal(7); - }); + const assertFlag = (flag: number, supplyMutable: boolean, transferable: boolean, restrictable?: boolean, revokable?: boolean): void => { + it('should create the right MosaicFlags flag ' + [flag, supplyMutable, transferable, restrictable, revokable].join(', '), () => { + const basicAssert = (mosaicFlags: MosaicFlags): void => { + expect(mosaicFlags.getValue()).to.be.equal(flag); + expect(mosaicFlags.supplyMutable).to.be.equal(supplyMutable); + expect(mosaicFlags.transferable).to.be.equal(transferable); + expect(mosaicFlags.restrictable).to.be.equal(restrictable || false); + expect(mosaicFlags.revokable).to.be.equal(revokable || false); + expect(mosaicFlags.toDTO().flags).to.be.equal(flag); + }; + + basicAssert(MosaicFlags.create(supplyMutable, transferable, restrictable, revokable)); + basicAssert(new MosaicFlags(flag)); + }); + }; + + assertFlag(0, false, false, false, false); + assertFlag(1, true, false, false, false); + assertFlag(2, false, true, false, false); + assertFlag(3, true, true, false, false); + assertFlag(4, false, false, true, false); + assertFlag(5, true, false, true, false); + assertFlag(6, false, true, true, false); + assertFlag(7, true, true, true, false); + assertFlag(8, false, false, false, true); + assertFlag(9, true, false, false, true); + assertFlag(10, false, true, false, true); + assertFlag(11, true, true, false, true); + assertFlag(12, false, false, true, true); + assertFlag(13, true, false, true, true); + assertFlag(14, false, true, true, true); + assertFlag(15, true, true, true, true); + + //Using defaults + assertFlag(0, false, false); + assertFlag(1, true, false); + assertFlag(2, false, true); + assertFlag(3, true, true); + assertFlag(4, false, false, true); + assertFlag(5, true, false, true); + assertFlag(6, false, true, true); + assertFlag(7, true, true, true); }); diff --git a/test/model/transaction/MosaicDefinitionTransaction.spec.ts b/test/model/transaction/MosaicDefinitionTransaction.spec.ts index 2c174ef4df..b239459fd3 100644 --- a/test/model/transaction/MosaicDefinitionTransaction.spec.ts +++ b/test/model/transaction/MosaicDefinitionTransaction.spec.ts @@ -38,7 +38,7 @@ describe('MosaicDefinitionTransaction', () => { Deadline.create(epochAdjustment), MosaicNonce.createFromUint8Array(new Uint8Array([0xe6, 0xde, 0x84, 0xb8])), // nonce new MosaicId(UInt64.fromUint(1).toDTO()), // ID - MosaicFlags.create(true, true, true), + MosaicFlags.create(true, true, true, true), 3, UInt64.fromUint(1000), TestNetworkType, @@ -64,12 +64,12 @@ describe('MosaicDefinitionTransaction', () => { expect(mosaicDefinitionTransaction.maxFee.lower).to.be.equal(1); }); - it('should createComplete an MosaicDefinitionTransaction object and sign it with flags 7', () => { + it('should createComplete an MosaicDefinitionTransaction object and sign it with flags 15', () => { const mosaicDefinitionTransaction = MosaicDefinitionTransaction.create( Deadline.create(epochAdjustment), MosaicNonce.createFromUint8Array(new Uint8Array([0xe6, 0xde, 0x84, 0xb8])), // nonce new MosaicId(UInt64.fromUint(1).toDTO()), // ID - MosaicFlags.create(true, true, true), + MosaicFlags.create(true, true, true, true), 3, UInt64.fromUint(1000), TestNetworkType, @@ -81,11 +81,12 @@ describe('MosaicDefinitionTransaction', () => { expect(mosaicDefinitionTransaction.flags.supplyMutable).to.be.equal(true); expect(mosaicDefinitionTransaction.flags.transferable).to.be.equal(true); expect(mosaicDefinitionTransaction.flags.restrictable).to.be.equal(true); + expect(mosaicDefinitionTransaction.flags.revokable).to.be.equal(true); const signedTransaction = mosaicDefinitionTransaction.signWith(account, generationHash); expect(signedTransaction.payload.substring(256, signedTransaction.payload.length)).to.be.equal( - '0100000000000000E803000000000000E6DE84B80703', + '0100000000000000E803000000000000E6DE84B80F03', ); }); @@ -94,7 +95,7 @@ describe('MosaicDefinitionTransaction', () => { Deadline.create(epochAdjustment), MosaicNonce.createFromUint8Array(new Uint8Array([0xe6, 0xde, 0x84, 0xb8])), // nonce new MosaicId(UInt64.fromUint(1).toDTO()), // ID - MosaicFlags.create(false, false, false), + MosaicFlags.create(false, false, false, false), 3, UInt64.fromUint(1000), TestNetworkType, @@ -106,6 +107,7 @@ describe('MosaicDefinitionTransaction', () => { expect(mosaicDefinitionTransaction.flags.supplyMutable).to.be.equal(false); expect(mosaicDefinitionTransaction.flags.transferable).to.be.equal(false); expect(mosaicDefinitionTransaction.flags.restrictable).to.be.equal(false); + expect(mosaicDefinitionTransaction.flags.revokable).to.be.equal(false); const signedTransaction = mosaicDefinitionTransaction.signWith(account, generationHash); diff --git a/test/model/transaction/MosaicSupplyRevocationTransaction.spec.ts b/test/model/transaction/MosaicSupplyRevocationTransaction.spec.ts new file mode 100644 index 0000000000..9b5bcfdb6b --- /dev/null +++ b/test/model/transaction/MosaicSupplyRevocationTransaction.spec.ts @@ -0,0 +1,83 @@ +/* + * Copyright 2021 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 { Mosaic } from '../../../src/model/mosaic'; +import { MosaicId } from '../../../src/model/mosaic/MosaicId'; +import { NamespaceId } from '../../../src/model/namespace/NamespaceId'; +import { NetworkType } from '../../../src/model/network/NetworkType'; +import { ReceiptSource, ResolutionEntry, ResolutionStatement, ResolutionType, Statement } from '../../../src/model/receipt'; +import { Deadline } from '../../../src/model/transaction/Deadline'; +import { MosaicSupplyRevocationTransaction } from '../../../src/model/transaction/MosaicSupplyRevocationTransaction'; +import { UInt64 } from '../../../src/model/UInt64'; +import { TestingAccount } from '../../conf/conf.spec'; +describe('MosaicSupplyRevocationTransaction', () => { + const account = TestingAccount; + const unresolvedMosaicId = new NamespaceId('mosaic'); + const unresolvedAddress = new NamespaceId('address'); + const mosaicId = new MosaicId('0DC67FBE1CAD29E5'); + const height = UInt64.fromUint(2); + const epochAdjustment = 1573430400; + const statement = new Statement( + [], + [ + new ResolutionStatement(ResolutionType.Address, height, unresolvedAddress, [ + new ResolutionEntry(account.address, new ReceiptSource(1, 0)), + ]), + ], + [ + new ResolutionStatement(ResolutionType.Mosaic, height, unresolvedMosaicId, [ + new ResolutionEntry(mosaicId, new ReceiptSource(1, 0)), + ]), + ], + ); + + it('should create transaction', () => { + const transaction = MosaicSupplyRevocationTransaction.create( + Deadline.create(epochAdjustment), + unresolvedAddress, + new Mosaic(unresolvedMosaicId, UInt64.fromUint(5)), + NetworkType.TEST_NET, + ); + + expect(transaction.sourceAddress).to.deep.equal(unresolvedAddress); + expect(transaction.mosaic.id).to.deep.equal(unresolvedMosaicId); + expect(transaction.mosaic.amount.toString()).to.deep.equal('5'); + expect(transaction.maxFee.toString()).to.be.equal('0'); + expect(transaction.networkType).to.be.equal(NetworkType.TEST_NET); + }); + + it('should resolve aliases', () => { + const unresolvedTransaction = MosaicSupplyRevocationTransaction.create( + Deadline.create(epochAdjustment), + unresolvedAddress, + new Mosaic(unresolvedMosaicId, UInt64.fromUint(5)), + NetworkType.TEST_NET, + ); + (unresolvedTransaction as any).transactionInfo = { + height: height, + index: 0, + }; + + const transaction = unresolvedTransaction.resolveAliases(statement); + + expect(transaction.sourceAddress).to.deep.equal(account.address); + expect(transaction.mosaic.id).to.deep.equal(mosaicId); + expect(transaction.mosaic.amount.toString()).to.deep.equal('5'); + expect(transaction.maxFee.toString()).to.be.equal('0'); + expect(transaction.networkType).to.be.equal(NetworkType.TEST_NET); + }); +}); diff --git a/test/model/transaction/TransactionType.spec.ts b/test/model/transaction/TransactionType.spec.ts index 62b10910ab..dadf734162 100644 --- a/test/model/transaction/TransactionType.spec.ts +++ b/test/model/transaction/TransactionType.spec.ts @@ -22,6 +22,7 @@ describe('TransactionType', () => { expect(TransactionType.NAMESPACE_REGISTRATION).to.be.equal(0x414e); expect(TransactionType.MOSAIC_DEFINITION).to.be.equal(0x414d); expect(TransactionType.MOSAIC_SUPPLY_CHANGE).to.be.equal(0x424d); + expect(TransactionType.MOSAIC_SUPPLY_REVOCATION).to.be.equal(0x434d); expect(TransactionType.MULTISIG_ACCOUNT_MODIFICATION).to.be.equal(0x4155); expect(TransactionType.AGGREGATE_COMPLETE).to.be.equal(0x4141); expect(TransactionType.AGGREGATE_BONDED).to.be.equal(0x4241);