From 2acc455305103d5aac989497b32510f7f1f61c99 Mon Sep 17 00:00:00 2001 From: Igor Markin Date: Thu, 19 Oct 2023 12:40:15 +0100 Subject: [PATCH] feat: asset lock special transaction (#288) * feat: asset lock tx payload * refactor: get rid of SubTxRegisterPayload * refactor: removed rest legacy platform special transactions * refactor: unused code --- docs/usage/transaction.md | 8 - index.d.ts | 5 - lib/constants/index.js | 6 +- lib/transaction/payload/assetlockpayload.js | 172 +++++ lib/transaction/payload/index.js | 6 +- lib/transaction/payload/payload.js | 18 +- .../payload/subtxcloseaccountpayload.js | 241 ------- .../payload/subtxregisterpayload.js | 255 -------- .../payload/subtxresetkeypayload.js | 294 --------- lib/transaction/payload/subtxtopuppayload.js | 140 ----- .../payload/subtxtransitionpayload.js | 301 --------- lib/transaction/transaction.js | 18 +- test-d/index.test-d.ts | 7 +- test/transaction/payload/assetlockpayload.js | 229 +++++++ .../payload/subtxcloseaccountpayload.js | 537 ---------------- .../payload/subtxregisterpayload.js | 385 ------------ .../payload/subtxresetkeypayload.js | 595 ------------------ test/transaction/payload/subtxtopuppayload.js | 132 ---- .../payload/subtxtransitionpayload.js | 363 ----------- test/transaction/transaction.js | 204 +----- typings/transaction/Output.d.ts | 9 +- typings/transaction/Transaction.d.ts | 3 +- .../transaction/payload/AssetLockPayload.d.ts | 59 ++ typings/transaction/payload/Payload.d.ts | 17 + .../payload/SubTxCloseAccountPayload.d.ts | 99 --- .../payload/SubTxRegisterPayload.d.ts | 107 ---- .../payload/SubTxResetKeyPayload.d.ts | 127 ---- .../payload/SubTxTopupPayload.d.ts | 65 -- .../payload/SubTxTransitionPayload.d.ts | 124 ---- 29 files changed, 527 insertions(+), 3999 deletions(-) create mode 100644 lib/transaction/payload/assetlockpayload.js delete mode 100644 lib/transaction/payload/subtxcloseaccountpayload.js delete mode 100644 lib/transaction/payload/subtxregisterpayload.js delete mode 100644 lib/transaction/payload/subtxresetkeypayload.js delete mode 100644 lib/transaction/payload/subtxtopuppayload.js delete mode 100644 lib/transaction/payload/subtxtransitionpayload.js create mode 100644 test/transaction/payload/assetlockpayload.js delete mode 100644 test/transaction/payload/subtxcloseaccountpayload.js delete mode 100644 test/transaction/payload/subtxregisterpayload.js delete mode 100644 test/transaction/payload/subtxresetkeypayload.js delete mode 100644 test/transaction/payload/subtxtopuppayload.js delete mode 100644 test/transaction/payload/subtxtransitionpayload.js create mode 100644 typings/transaction/payload/AssetLockPayload.d.ts create mode 100644 typings/transaction/payload/Payload.d.ts delete mode 100644 typings/transaction/payload/SubTxCloseAccountPayload.d.ts delete mode 100644 typings/transaction/payload/SubTxRegisterPayload.d.ts delete mode 100644 typings/transaction/payload/SubTxResetKeyPayload.d.ts delete mode 100644 typings/transaction/payload/SubTxTopupPayload.d.ts delete mode 100644 typings/transaction/payload/SubTxTransitionPayload.d.ts diff --git a/docs/usage/transaction.md b/docs/usage/transaction.md index 38b759f7c..3cd352c77 100644 --- a/docs/usage/transaction.md +++ b/docs/usage/transaction.md @@ -444,14 +444,6 @@ The argument function MUST NOT modify the order of the original array **Parameters**: None. **Returns**: Array -## .canHaveNoUtxo() - -**Description**: - -**Parameters**: None. - -**Returns**: Boolean - ## .toObject() / .toJSON() **Description**: Will return an object representation of the transaction diff --git a/index.d.ts b/index.d.ts index 5ca9a1bc0..8c5b04777 100644 --- a/index.d.ts +++ b/index.d.ts @@ -64,11 +64,6 @@ export { ProRegTxPayload } from './typings/transaction/payload/ProRegTxPayload'; export { ProUpRegTxPayload } from './typings/transaction/payload/ProUpRegTxPayload'; export { ProUpRevTxPayload } from './typings/transaction/payload/ProUpRevTxPayload'; export { ProUpServTxPayload } from './typings/transaction/payload/ProUpServTxPayload'; -export { SubTxCloseAccountPayload } from './typings/transaction/payload/SubTxCloseAccountPayload'; -export { SubTxRegisterPayload } from './typings/transaction/payload/SubTxRegisterPayload'; -export { SubTxResetKeyPayload } from './typings/transaction/payload/SubTxResetKeyPayload'; -export { SubTxTopupPayload } from './typings/transaction/payload/SubTxTopupPayload'; -export { SubTxTransitionPayload } from './typings/transaction/payload/SubTxTransitionPayload'; export { Output } from './typings/transaction/Output'; diff --git a/lib/constants/index.js b/lib/constants/index.js index 5c6fb79c8..3e3c02778 100644 --- a/lib/constants/index.js +++ b/lib/constants/index.js @@ -24,11 +24,7 @@ module.exports = { TRANSACTION_PROVIDER_UPDATE_REVOKE: 4, TRANSACTION_COINBASE: 5, TRANSACTION_QUORUM_COMMITMENT: 6, - TRANSACTION_SUBTX_REGISTER: 8, - TRANSACTION_SUBTX_TOPUP: 9, - TRANSACTION_SUBTX_RESETKEY: 10, - TRANSACTION_SUBTX_CLOSEACCOUNT: 11, - TRANSACTION_SUBTX_TRANSITION: 12, + TRANSACTION_ASSET_LOCK: 8, }, EMPTY_SIGNATURE_SIZE: 0, primitives: { diff --git a/lib/transaction/payload/assetlockpayload.js b/lib/transaction/payload/assetlockpayload.js new file mode 100644 index 000000000..62e64423d --- /dev/null +++ b/lib/transaction/payload/assetlockpayload.js @@ -0,0 +1,172 @@ +/* eslint-disable */ +// TODO: Remove previous line and work through linting issues at next edit + +var Preconditions = require('../../util/preconditions'); +var BufferWriter = require('../../encoding/bufferwriter'); +var BufferReader = require('../../encoding/bufferreader'); +var AbstractPayload = require('./abstractpayload'); +var utils = require('../../util/js'); +const _ = require('lodash'); +const Output = require('../output'); + +var isUnsignedInteger = utils.isUnsignedInteger; + +var CURRENT_PAYLOAD_VERSION = 1; + +/** + * @typedef {Object} AssetLockPayloadJSON + * @property {number} version + * @property {object} creditOutputs + */ + +/** + * @class AssetLockPayload + * @property {Output[]} creditOutputs + */ +function AssetLockPayload() { + AbstractPayload.call(this); + this.version = CURRENT_PAYLOAD_VERSION; + this.creditOutputs = []; +} + +AssetLockPayload.prototype = Object.create(AbstractPayload.prototype); +AssetLockPayload.prototype.constructor = AbstractPayload; + +/* Static methods */ + +/** + * Parse raw transition payload + * @param {Buffer} rawPayload + * @return {AssetLockPayload} + */ +AssetLockPayload.fromBuffer = function (rawPayload) { + var payloadBufferReader = new BufferReader(rawPayload); + var payload = new AssetLockPayload(); + payload.version = payloadBufferReader.readUInt8(); + var numCreditOutputs = payloadBufferReader.readVarintNum(); + for (var i = 0; i < numCreditOutputs; i++) { + payload.creditOutputs.push(Output.fromBufferReader(payloadBufferReader)); + } + + if (!payloadBufferReader.finished()) { + throw new Error( + 'Failed to parse payload: raw payload is bigger than expected.' + ); + } + + payload.validate(); + return payload; +}; + +/** + * Create new instance of payload from JSON + * @param {string|AssetLockPayloadJSON} payloadJson + * @return {AssetLockPayload} + */ +AssetLockPayload.fromJSON = function fromJSON(payloadJson) { + var payload = new AssetLockPayload(); + payload.version = payloadJson.version; + + var creditOutputs = []; + _.each(payloadJson.creditOutputs, function (output) { + creditOutputs.push(new Output(output)); + }); + + payload.creditOutputs = creditOutputs; + + payload.validate(); + return payload; +}; + +/* Instance methods */ + +/** + * Validates payload data + * @return {boolean} + */ +AssetLockPayload.prototype.validate = function () { + Preconditions.checkArgument( + isUnsignedInteger(this.version), + 'Expect version to be an unsigned integer' + ); + + Preconditions.checkArgument( + this.version !== 0 && this.version <= CURRENT_PAYLOAD_VERSION, + 'Invalid version' + ); + + Preconditions.checkArgument( + this.creditOutputs.length > 0, + 'Empty credit outputs' + ); + + _.each(this.creditOutputs, function (output, index) { + Preconditions.checkArgument( + output instanceof Output, + 'Credit output ' + index + ' is not an instance of Output' + ); + }); + + _.each(this.creditOutputs, function (output, index) { + Preconditions.checkArgument( + output.script.isPublicKeyHashOut(), + 'Credit output ' + index + ' is not P2PKH' + ); + }); + + _.each(this.creditOutputs, function (output, index) { + Preconditions.checkArgument( + output.script.isPublicKeyHashOut(), + 'Credit output ' + index + ' is not P2PKH' + ); + }); + + return true; +}; + +/** + * Serializes payload to JSON + * @return {AssetLockPayloadJSON} + */ +AssetLockPayload.prototype.toJSON = function toJSON() { + this.validate(); + const creditOutputs = []; + _.each(this.creditOutputs, function (output) { + creditOutputs.push(output.toJSON()); + }); + var json = { + version: this.version, + creditOutputs + }; + + return json; +}; + +/** + * Serialize payload to buffer + * @return {Buffer} + */ +AssetLockPayload.prototype.toBuffer = function toBuffer() { + this.validate(); + var payloadBufferWriter = new BufferWriter(); + + payloadBufferWriter + .writeUInt8(this.version) + .writeVarintNum(this.creditOutputs.length); + + _.each(this.creditOutputs, function (output) { + output.toBufferWriter(payloadBufferWriter); + }); + + return payloadBufferWriter.toBuffer(); +}; + +/** + * Copy payload instance + * @return {AssetLockPayload} + */ +AssetLockPayload.prototype.copy = function copy() { + return AssetLockPayload.fromJSON(this.toJSON()); +}; + +module.exports = AssetLockPayload; diff --git a/lib/transaction/payload/index.js b/lib/transaction/payload/index.js index 9447934e2..228efe8c9 100644 --- a/lib/transaction/payload/index.js +++ b/lib/transaction/payload/index.js @@ -7,13 +7,9 @@ Payload.ProRegTxPayload = require('./proregtxpayload'); Payload.ProUpRegTxPayload = require('./proupregtxpayload'); Payload.ProUpRevTxPayload = require('./prouprevtxpayload'); Payload.ProTxUpServPayload = require('./proupservtxpayload'); -Payload.SubTxCloseAccountPayload = require('./subtxcloseaccountpayload'); -Payload.SubTxRegisterPayload = require('./subtxregisterpayload'); -Payload.SubTxResetKeyPayload = require('./subtxresetkeypayload'); -Payload.SubTxTopupPayload = require('./subtxtopuppayload'); -Payload.SubTxTransitionPayload = require('./subtxtransitionpayload'); Payload.CoinbasePayload = require('./coinbasepayload'); Payload.constants = require('../../constants'); Payload.CommitmentTxPayload = require('./commitmenttxpayload'); +Payload.AssetLockPayload = require('./assetlockpayload'); module.exports = Payload; diff --git a/lib/transaction/payload/payload.js b/lib/transaction/payload/payload.js index f015eb830..87185b957 100644 --- a/lib/transaction/payload/payload.js +++ b/lib/transaction/payload/payload.js @@ -4,29 +4,15 @@ var RegisteredPayloadTypes = require('../../constants').registeredTransactionTypes; var AbstractPayload = require('./abstractpayload'); -var SubTxCloseAccountPayload = require('./subtxcloseaccountpayload'); -var SubTxRegisterPayload = require('./subtxregisterpayload'); -var SubTxResetKeyPayload = require('./subtxresetkeypayload'); -var SubTxTopUpPayload = require('./subtxtopuppayload'); -var SubTxTransitionPayload = require('./subtxtransitionpayload'); var CoinbasePayload = require('./coinbasepayload'); var CommitmentTxPayload = require('./commitmenttxpayload'); var ProRegTxPayload = require('./proregtxpayload'); var ProTxUpServPayload = require('./proupservtxpayload'); var ProUpRegTxPayload = require('./proupregtxpayload'); var ProUpRevTxPayload = require('./prouprevtxpayload'); +var AssetLockPayload = require('./assetlockpayload'); var PayloadClasses = {}; -PayloadClasses[RegisteredPayloadTypes.TRANSACTION_SUBTX_CLOSEACCOUNT] = - SubTxCloseAccountPayload; -PayloadClasses[RegisteredPayloadTypes.TRANSACTION_SUBTX_REGISTER] = - SubTxRegisterPayload; -PayloadClasses[RegisteredPayloadTypes.TRANSACTION_SUBTX_RESETKEY] = - SubTxResetKeyPayload; -PayloadClasses[RegisteredPayloadTypes.TRANSACTION_SUBTX_TOPUP] = - SubTxTopUpPayload; -PayloadClasses[RegisteredPayloadTypes.TRANSACTION_SUBTX_TRANSITION] = - SubTxTransitionPayload; PayloadClasses[RegisteredPayloadTypes.TRANSACTION_COINBASE] = CoinbasePayload; PayloadClasses[RegisteredPayloadTypes.TRANSACTION_QUORUM_COMMITMENT] = CommitmentTxPayload; @@ -38,6 +24,8 @@ PayloadClasses[RegisteredPayloadTypes.TRANSACTION_PROVIDER_UPDATE_REGISTRAR] = ProUpRegTxPayload; PayloadClasses[RegisteredPayloadTypes.TRANSACTION_PROVIDER_UPDATE_REVOKE] = ProUpRevTxPayload; +PayloadClasses[RegisteredPayloadTypes.TRANSACTION_ASSET_LOCK] = + AssetLockPayload; /** * diff --git a/lib/transaction/payload/subtxcloseaccountpayload.js b/lib/transaction/payload/subtxcloseaccountpayload.js deleted file mode 100644 index c9d4cdd6b..000000000 --- a/lib/transaction/payload/subtxcloseaccountpayload.js +++ /dev/null @@ -1,241 +0,0 @@ -/* eslint-disable */ -// TODO: Remove previous line and work through linting issues at next edit - -var constants = require('../../constants'); -var Preconditions = require('../../util/preconditions'); -var BufferWriter = require('../../encoding/bufferwriter'); -var BufferReader = require('../../encoding/bufferreader'); -var AbstractPayload = require('./abstractpayload'); -var utils = require('../../util/js'); -var PrivateKey = require('../../privatekey'); -var BigNumber = require('bn.js'); - -var isUnsignedInteger = utils.isUnsignedInteger; -var isSha256HexString = utils.isSha256HexString; -var isHexString = utils.isHexaString; - -var CURRENT_PAYLOAD_VERSION = 1; -var HASH_SIZE = constants.SHA256_HASH_SIZE; - -/** - * @typedef {Object} SubTxCloseAccountPayloadJSON - * @property {number} version - payload version - * @property {string} regTxHash - * @property {string} hashPrevSubTx - * @property {number} creditFee - fee to pay for transaction (duffs) - * @property {number} payloadSigSize - length of the signature (payloadSig) - * @property {string} payloadSig - Signature from either the current key or a previous key (<= ~90 days old) - */ - -/** - * @class SubTxCloseAccountPayload - * @property {number} version - payload version - * @property {string} regTxHash - * @property {string} hashPrevSubTx - * @property {number} creditFee - fee to pay for transaction (duffs) - * @property {number} payloadSigSize - length of the signature (payloadSig) - * @property {string} payloadSig - Signature from either the current key or a previous key (<= ~90 days old) - */ -function SubTxCloseAccountPayload(payloadJSON) { - AbstractPayload.call(this); - - if (payloadJSON) { - this.version = payloadJSON.version; - this.regTxHash = payloadJSON.regTxHash; - this.hashPrevSubTx = payloadJSON.hashPrevSubTx; - this.creditFee = payloadJSON.creditFee; - //this.newPubKeySize = payloadJSON.newPubKeySize; - this.newPubKey = payloadJSON.newPubKey; - this.payloadSigSize = 0; - if (payloadJSON.payloadSig) { - this.payloadSig = payloadJSON.payloadSig; - this.payloadSigSize = Number(this.payloadSig.length) / 2; - } - - this.validate(); - } else { - this.version = CURRENT_PAYLOAD_VERSION; - } -} - -SubTxCloseAccountPayload.prototype = Object.create(AbstractPayload.prototype); -SubTxCloseAccountPayload.prototype.constructor = AbstractPayload; - -/* Static methods */ - -/** - * Parse raw transition payload - * @param {Buffer} rawPayload - * @return {SubTxCloseAccountPayload} - */ -SubTxCloseAccountPayload.fromBuffer = function (rawPayload) { - var payloadBufferReader = new BufferReader(rawPayload); - var payload = new SubTxCloseAccountPayload(); - - payload.version = payloadBufferReader.readUInt16LE(); - payload.regTxHash = payloadBufferReader - .read(HASH_SIZE) - .reverse() - .toString('hex'); - payload.hashPrevSubTx = payloadBufferReader - .read(HASH_SIZE) - .reverse() - .toString('hex'); - payload.creditFee = payloadBufferReader.readUInt64LEBN().toNumber(); - payload.payloadSigSize = payloadBufferReader.readVarintNum(); - - if (!payloadBufferReader.finished()) { - payload.payloadSig = payloadBufferReader - .read(payload.payloadSigSize) - .reverse() - .toString('hex'); - } - - if (!payloadBufferReader.finished()) { - throw new Error( - 'Failed to parse payload: raw payload is bigger than expected.' - ); - } - - payload.validate(); - return payload; -}; - -/** - * Create new instance of payload from JSON - * @param {string|SubTxCloseAccountPayloadJSON} payloadJson - * @return {SubTxCloseAccountPayload} - */ -SubTxCloseAccountPayload.fromJSON = function fromJSON(payloadJson) { - return new SubTxCloseAccountPayload(payloadJson); -}; - -/** - * @private - * @param {string|PrivateKey} privateKey - * @return {Buffer} - */ -SubTxCloseAccountPayload.convertPrivateKeyToPubKeyId = function (privateKey) { - if (typeof privateKey === 'string') { - privateKey = new PrivateKey(privateKey); - } - return privateKey.toPublicKey()._getID(); -}; - -/* Instance methods */ - -/** - * Validates payload data - * @return {boolean} - */ -SubTxCloseAccountPayload.prototype.validate = function () { - Preconditions.checkArgumentType(this.version, 'number', 'version'); - Preconditions.checkArgumentType(this.creditFee, 'number', 'creditFee'); - Preconditions.checkArgument( - isUnsignedInteger(this.version), - 'Expect version to be an unsigned integer' - ); - Preconditions.checkArgument( - isSha256HexString(this.regTxHash), - 'Expect regTxHash to be a hex string representing sha256 hash' - ); - Preconditions.checkArgument( - isSha256HexString(this.hashPrevSubTx), - 'Expect hashPrevSubTx to be a hex string representing sha256 hash' - ); - if (this.payloadSig && this.payloadSigSize !== 0) { - Preconditions.checkArgumentType( - this.payloadSigSize, - 'number', - 'payloadSigSize' - ); - Preconditions.checkArgument( - isHexString(this.payloadSig), - 'expect payloadSig to be a hex string but got ' + typeof this.payloadSig - ); - Preconditions.checkArgument( - isUnsignedInteger(this.payloadSigSize), - 'Expect payloadSigSize to be an unsigned integer' - ); - Preconditions.checkArgument( - this.payloadSigSize === constants.COMPACT_SIGNATURE_SIZE, - 'Invalid payloadSigSize size' - ); - Preconditions.checkArgument( - this.payloadSig.length === constants.COMPACT_SIGNATURE_SIZE * 2, - 'Invalid Argument: Invalid payloadSigSize size' - ); - } - return true; -}; - -/** - * @param {string} regTxHash - * @return {SubTxCloseAccountPayload} - */ -SubTxCloseAccountPayload.prototype.setRegTxHash = function (regTxHash) { - this.regTxHash = regTxHash; - return this; -}; - -/** - * @param {string} hashPrevSubTx - * @return {SubTxCloseAccountPayload} - */ -SubTxCloseAccountPayload.prototype.setPrevSubTxHash = function (hashPrevSubTx) { - this.hashPrevSubTx = hashPrevSubTx; - return this; -}; - -/** - * @param {number} duffs - * @return {SubTxCloseAccountPayload} - */ -SubTxCloseAccountPayload.prototype.setCreditFee = function (duffs) { - this.creditFee = duffs; - return this; -}; - -/** - * Serializes payload to JSON - * @return {{version: *, regTxHash: *, hashPrevSubTx: *, creditFee: *, payloadSigSize: *, payloadSig: *}} - */ -SubTxCloseAccountPayload.prototype.toJSON = function toJSON(options) { - var skipSignature = (options && options.skipSignature) || false; - this.validate(); - var payloadJSON = { - version: this.version, - regTxHash: this.regTxHash, - hashPrevSubTx: this.hashPrevSubTx, - creditFee: this.creditFee, - }; - if (!skipSignature) { - payloadJSON.payloadSigSize = this.payloadSigSize; - payloadJSON.payloadSig = this.payloadSig; - } - return payloadJSON; -}; - -/** - * Serialize payload to buffer - * @return {Buffer} - */ -SubTxCloseAccountPayload.prototype.toBuffer = function toBuffer(options) { - var skipSignature = (options && options.skipSignature) || false; - this.validate(); - var payloadBufferWriter = new BufferWriter(); - - payloadBufferWriter.writeUInt16LE(this.version); - payloadBufferWriter.write(Buffer.from(this.regTxHash, 'hex').reverse()); - payloadBufferWriter.write(Buffer.from(this.hashPrevSubTx, 'hex').reverse()); - payloadBufferWriter.writeUInt64LEBN(new BigNumber(this.creditFee)); - if (!skipSignature) { - payloadBufferWriter.writeVarintNum(this.payloadSigSize); - payloadBufferWriter.write(Buffer.from(this.payloadSig, 'hex').reverse()); - } else { - payloadBufferWriter.writeVarintNum(0); - } - return payloadBufferWriter.toBuffer(); -}; - -module.exports = SubTxCloseAccountPayload; diff --git a/lib/transaction/payload/subtxregisterpayload.js b/lib/transaction/payload/subtxregisterpayload.js deleted file mode 100644 index 1314afa49..000000000 --- a/lib/transaction/payload/subtxregisterpayload.js +++ /dev/null @@ -1,255 +0,0 @@ -/* eslint-disable */ -// TODO: Remove previous line and work through linting issues at next edit - -var utils = require('../../util/js'); -var constants = require('../../constants'); -var Preconditions = require('../../util/preconditions'); -var BufferUtil = require('../../util/buffer'); -var BufferWriter = require('../../encoding/bufferwriter'); -var BufferReader = require('../../encoding/bufferreader'); -var PrivateKey = require('../../privatekey'); -var AbstractPayload = require('./abstractpayload'); - -var isHexString = utils.isHexaString; - -var CURRENT_PAYLOAD_VERSION = 1; -var PUBKEY_ID_SIZE = constants.PUBKEY_ID_SIZE; - -/** - * @typedef {Object} BlockchainUserPayloadJSON - * @property {number} version - payload version - * @property {Buffer} pubKeyId - * @property {string} userName - * @property {string} [payloadSig] - * @property {string} [payloadSigSize] - */ - -/** - * @class SubTxRegisterPayload - * @property {number} version - payload version - * @property {Buffer} pubKeyId - * @property {string} userName - * @property {string} [payloadSig] - * @property {string} [payloadSigSize] - */ -function SubTxRegisterPayload() { - AbstractPayload.call(this); - this.version = CURRENT_PAYLOAD_VERSION; -} - -SubTxRegisterPayload.prototype = Object.create(AbstractPayload.prototype); -SubTxRegisterPayload.prototype.constructor = AbstractPayload; - -/* Static methods */ - -/** - * Serialize blockchain user payload - * @param {BlockchainUserPayloadJSON} blockchainUserPayload - * @return {Buffer} serialized payload - */ -SubTxRegisterPayload.serializeJSONToBuffer = function (blockchainUserPayload) { - SubTxRegisterPayload.validatePayloadJSON(blockchainUserPayload); - var payloadBufferWriter = new BufferWriter(); - - var userNameBuffer = Buffer.from(blockchainUserPayload.userName, 'utf8'); - - payloadBufferWriter - .writeUInt16LE(blockchainUserPayload.version) - .writeVarintNum(userNameBuffer.length) - .write(userNameBuffer) - .write(blockchainUserPayload.pubKeyId); - - if (blockchainUserPayload.payloadSig) { - var signatureBuf = Buffer.from(blockchainUserPayload.payloadSig, 'hex'); - payloadBufferWriter.writeVarintNum(signatureBuf.length); - payloadBufferWriter.write(signatureBuf); - } else { - payloadBufferWriter.writeVarintNum(constants.EMPTY_SIGNATURE_SIZE); - } - - return payloadBufferWriter.toBuffer(); -}; - -/** - * Parse raw blockchain user payload - * @param {Buffer} rawPayload - * @return {SubTxRegisterPayload} - */ -SubTxRegisterPayload.fromBuffer = function fromBuffer(rawPayload) { - var payloadBufferReader = new BufferReader(rawPayload); - var blockchainUserPayload = new SubTxRegisterPayload(); - var signatureSize = 0; - - blockchainUserPayload.version = payloadBufferReader.readUInt16LE(); - var usernameLen = payloadBufferReader.readVarintNum(); - blockchainUserPayload.userName = payloadBufferReader - .read(usernameLen) - .toString(); - blockchainUserPayload.pubKeyId = payloadBufferReader.read(PUBKEY_ID_SIZE); - - if (!payloadBufferReader.finished()) { - signatureSize = payloadBufferReader.readVarintNum(); - } - - if (signatureSize > 0) { - blockchainUserPayload.payloadSigSize = signatureSize; - blockchainUserPayload.payloadSig = payloadBufferReader - .read(signatureSize) - .toString('hex'); - } - - SubTxRegisterPayload.validatePayloadJSON(blockchainUserPayload.toJSON()); - return blockchainUserPayload; -}; - -/** - * Create new instance of payload from JSON - * @param {string|BlockchainUserPayloadJSON} payloadJson - * @return {SubTxRegisterPayload} - */ -SubTxRegisterPayload.fromJSON = function fromJSON(payloadJson) { - SubTxRegisterPayload.validatePayloadJSON(payloadJson); - var payload = new SubTxRegisterPayload(); - payload.version = payloadJson.version; - payload.setUserName(payloadJson.userName); - payload.setPubKeyId(payloadJson.pubKeyId); - - if (payloadJson.payloadSig) { - payload.payloadSig = payloadJson.payloadSig; - } - - if (payloadJson.payloadSigSize) { - payload.payloadSigSize = payloadJson.payloadSigSize; - } - - return payload; -}; - -/** - * Validate payload - * @param {BlockchainUserPayloadJSON} blockchainUserPayload - * @return {boolean} - */ -SubTxRegisterPayload.validatePayloadJSON = function (blockchainUserPayload) { - if (!blockchainUserPayload) { - throw new Error('No Payload specified'); - } - - Preconditions.checkArgumentType( - blockchainUserPayload.version, - 'number', - 'version' - ); - Preconditions.checkArgument( - BufferUtil.isBuffer(blockchainUserPayload.pubKeyId), - 'expect pubKeyId to be a Buffer but got ' + - typeof blockchainUserPayload.pubKeyId - ); - Preconditions.checkArgument( - blockchainUserPayload.pubKeyId.length === constants.PUBKEY_ID_SIZE, - 'Invalid pubKeyId size' - ); - Preconditions.checkArgumentType( - blockchainUserPayload.userName, - 'string', - 'userName' - ); - Preconditions.checkArgument( - blockchainUserPayload.userName.length > 1, - 'userName is too short' - ); - - if (blockchainUserPayload.payloadSig) { - Preconditions.checkArgument( - isHexString(blockchainUserPayload.payloadSig), - 'expect payloadSig to be a hex string but got ' + - typeof blockchainUserPayload.payloadSig - ); - Preconditions.checkArgument( - blockchainUserPayload.payloadSig.length === - constants.COMPACT_SIGNATURE_SIZE * 2, - 'Invalid payloadSig size' - ); - } -}; - -/** - * @private - * @param {string|PrivateKey} privateKey - * @return {Buffer} - */ -SubTxRegisterPayload.convertPrivateKeyToPubKeyId = function (privateKey) { - if (typeof privateKey === 'string') { - privateKey = new PrivateKey(privateKey); - } - return privateKey.toPublicKey()._getID(); -}; - -/* Instance methods */ - -/** - * @param {string} userName - * @return {SubTxRegisterPayload} - */ -SubTxRegisterPayload.prototype.setUserName = function setUserName(userName) { - this.userName = userName; - return this; -}; - -/** - * @param {Buffer} pubKeyId - * @return {SubTxRegisterPayload} - */ -SubTxRegisterPayload.prototype.setPubKeyId = function (pubKeyId) { - this.pubKeyId = BufferUtil.copy(pubKeyId); - return this; -}; - -/** - * Extracts and sets pubKeyId from private key - * @param {string|PrivateKey} privateKey - * @return {SubTxRegisterPayload} - */ -SubTxRegisterPayload.prototype.setPubKeyIdFromPrivateKey = function ( - privateKey -) { - this.setPubKeyId( - SubTxRegisterPayload.convertPrivateKeyToPubKeyId(privateKey) - ); - return this; -}; - -/** - * Serializes payload to JSON - * @param [options] - * @param {boolean} options.skipSignature - skip signature part. Needed for creating new signature - * @return {BlockchainUserPayloadJSON} - */ -SubTxRegisterPayload.prototype.toJSON = function toJSON(options) { - var skipSignature = options && options.skipSignature; - var payloadJSON = { - version: this.version, - userName: this.userName, - pubKeyId: this.pubKeyId, - }; - - if (!skipSignature) { - payloadJSON.payloadSig = this.payloadSig; - payloadJSON.payloadSigSize = this.payloadSigSize; - } - - SubTxRegisterPayload.validatePayloadJSON(payloadJSON); - return payloadJSON; -}; - -/** - * Serialize payload to buffer - * @param [options] - * @param {boolean} options.skipSignature - skip signature part. Needed for creating new signature - * @return {Buffer} - */ -SubTxRegisterPayload.prototype.toBuffer = function toBuffer(options) { - return SubTxRegisterPayload.serializeJSONToBuffer(this.toJSON(options)); -}; - -module.exports = SubTxRegisterPayload; diff --git a/lib/transaction/payload/subtxresetkeypayload.js b/lib/transaction/payload/subtxresetkeypayload.js deleted file mode 100644 index a9c39ac41..000000000 --- a/lib/transaction/payload/subtxresetkeypayload.js +++ /dev/null @@ -1,294 +0,0 @@ -/* eslint-disable */ -// TODO: Remove previous line and work through linting issues at next edit - -var constants = require('../../constants'); -var Preconditions = require('../../util/preconditions'); -var BufferUtil = require('../../util/buffer'); -var BufferWriter = require('../../encoding/bufferwriter'); -var BufferReader = require('../../encoding/bufferreader'); -var AbstractPayload = require('./abstractpayload'); -var utils = require('../../util/js'); -var PrivateKey = require('../../privatekey'); -var BigNumber = require('bn.js'); - -var isUnsignedInteger = utils.isUnsignedInteger; -var isSha256HexString = utils.isSha256HexString; -var isHexString = utils.isHexaString; - -var CURRENT_PAYLOAD_VERSION = 1; -var HASH_SIZE = constants.SHA256_HASH_SIZE; -var PUBKEY_ID_SIZE = constants.PUBKEY_ID_SIZE; - -/** - * @typedef {Object} SubTxResetKeyPayloadJSON - * @property {number} version - payload version - * @property {string} regTxHash - * @property {string} hashPrevSubTx - * @property {number} creditFee - fee to pay for transaction (duffs) - * @property {number} newPubKeySize - length of the new public key (not present in implementation) - * @property {Buffer} newPubKey - * @property {number} payloadSigSize - length of the signature (payloadSig) - * @property {string} payloadSig - signature of most recent pubkey - */ - -/** - * @class SubTxResetKeyPayload - * @property {number} version - payload version - * @property {string} regTxHash - * @property {string} hashPrevSubTx - * @property {number} creditFee - fee to pay for transaction (duffs) - * @property {number} newPubKeySize - length of the new public key (not present in implementation) - * @property {Buffer} newPubKey - * @property {number} payloadSigSize - length of the signature (payloadSig) - * @property {string} payloadSig - signature of most recent pubkey - */ -function SubTxResetKeyPayload(payloadJSON) { - AbstractPayload.call(this); - - if (payloadJSON) { - this.version = payloadJSON.version; - this.regTxHash = payloadJSON.regTxHash; - this.hashPrevSubTx = payloadJSON.hashPrevSubTx; - this.creditFee = payloadJSON.creditFee; - //this.newPubKeySize = payloadJSON.newPubKeySize; - this.newPubKey = payloadJSON.newPubKey; - this.payloadSigSize = 0; - if (payloadJSON.payloadSig) { - this.payloadSig = payloadJSON.payloadSig; - this.payloadSigSize = Number(this.payloadSig.length) / 2; - } - - this.validate(); - } else { - this.version = CURRENT_PAYLOAD_VERSION; - } -} - -SubTxResetKeyPayload.prototype = Object.create(AbstractPayload.prototype); -SubTxResetKeyPayload.prototype.constructor = AbstractPayload; - -/* Static methods */ - -/** - * Parse raw transition payload - * @param {Buffer} rawPayload - * @return {SubTxResetKeyPayload} - */ -SubTxResetKeyPayload.fromBuffer = function (rawPayload) { - var payloadBufferReader = new BufferReader(rawPayload); - var payload = new SubTxResetKeyPayload(); - - payload.version = payloadBufferReader.readUInt16LE(); - payload.regTxHash = payloadBufferReader - .read(HASH_SIZE) - .reverse() - .toString('hex'); - payload.hashPrevSubTx = payloadBufferReader - .read(HASH_SIZE) - .reverse() - .toString('hex'); - payload.creditFee = payloadBufferReader.readUInt64LEBN().toNumber(); - // TODO: enable following two lines when bug is fixed and core implementation corresponds to DIP5 - //payload.newPubKeySize = payloadBufferReader.readVarintNum(); - //payload.newPubKey = payloadBufferReader.read(payload.newPubKeySize); - payload.newPubKey = payloadBufferReader.read(PUBKEY_ID_SIZE); - payload.payloadSigSize = payloadBufferReader.readVarintNum(); - - if (!payloadBufferReader.finished()) { - payload.payloadSig = payloadBufferReader - .read(payload.payloadSigSize) - .reverse() - .toString('hex'); - } - - if (!payloadBufferReader.finished()) { - throw new Error( - 'Failed to parse payload: raw payload is bigger than expected.' - ); - } - - payload.validate(); - return payload; -}; - -/** - * Create new instance of payload from JSON - * @param {string|SubTxResetKeyPayloadJSON} payloadJson - * @return {SubTxResetKeyPayload} - */ -SubTxResetKeyPayload.fromJSON = function fromJSON(payloadJson) { - return new SubTxResetKeyPayload(payloadJson); -}; - -/** - * @private - * @param {string|PrivateKey} privateKey - * @return {Buffer} - */ -SubTxResetKeyPayload.convertPrivateKeyToPubKeyId = function (privateKey) { - if (typeof privateKey === 'string') { - privateKey = new PrivateKey(privateKey); - } - return privateKey.toPublicKey()._getID(); -}; - -/* Instance methods */ - -/** - * Validates payload data - * @return {boolean} - */ -SubTxResetKeyPayload.prototype.validate = function () { - Preconditions.checkArgumentType(this.version, 'number', 'version'); - Preconditions.checkArgumentType(this.creditFee, 'number', 'creditFee'); - // TODO: enable following two checks when bug is fixed and core implementation corresponds to DIP5 - //Preconditions.checkArgumentType(this.newPubKeySize, 'number', 'newPubKeySize'); - Preconditions.checkArgument( - isUnsignedInteger(this.version), - 'Expect version to be an unsigned integer' - ); - Preconditions.checkArgument( - isSha256HexString(this.regTxHash), - 'Expect regTxHash to be a hex string representing sha256 hash' - ); - Preconditions.checkArgument( - isSha256HexString(this.hashPrevSubTx), - 'Expect hashPrevSubTx to be a hex string representing sha256 hash' - ); - Preconditions.checkArgument( - isUnsignedInteger(this.creditFee), - 'Expect creditFee to be an unsigned integer' - ); - // TODO: change following checks if necessary once DIP 5 payloads will be updated with BLS keys and signatures - // TODO: enable following two checks when bug is fixed and core implementation corresponds to DIP5 - //Preconditions.checkArgument(isUnsignedInteger(this.newPubKeySize), 'Expect newPubKeySize to be an unsigned integer'); - //Preconditions.checkArgument(this.newPubKeySize === constants.PUBKEY_ID_SIZE, 'Invalid newPubKeySize size'); - Preconditions.checkArgument( - BufferUtil.isBuffer(this.newPubKey), - 'expect newPubKey to be a Buffer but got ' + typeof this.newPubKey - ); - if (this.payloadSig && this.payloadSigSize !== 0) { - Preconditions.checkArgumentType( - this.payloadSigSize, - 'number', - 'payloadSigSize' - ); - Preconditions.checkArgument( - isHexString(this.payloadSig), - 'expect payloadSig to be a hex string but got ' + typeof this.payloadSig - ); - Preconditions.checkArgument( - isUnsignedInteger(this.payloadSigSize), - 'Expect payloadSigSize to be an unsigned integer' - ); - Preconditions.checkArgument( - this.payloadSigSize === constants.COMPACT_SIGNATURE_SIZE, - 'Invalid payloadSigSize size' - ); - Preconditions.checkArgument( - this.payloadSig.length === constants.COMPACT_SIGNATURE_SIZE * 2, - 'Invalid Argument: Invalid payloadSigSize size' - ); - } - return true; -}; - -/** - * @param {string} regTxHash - * @return {SubTxResetKeyPayload} - */ -SubTxResetKeyPayload.prototype.setRegTxHash = function (regTxHash) { - this.regTxHash = regTxHash; - return this; -}; - -/** - * @param {string} hashPrevSubTx - * @return {SubTxResetKeyPayload} - */ -SubTxResetKeyPayload.prototype.setPrevSubTxHash = function (hashPrevSubTx) { - this.hashPrevSubTx = hashPrevSubTx; - return this; -}; - -/** - * @param {number} duffs - * @return {SubTxResetKeyPayload} - */ -SubTxResetKeyPayload.prototype.setCreditFee = function (duffs) { - this.creditFee = duffs; - return this; -}; - -/** - * @param {Buffer} pubKeyId - * @return {SubTxResetKeyPayload} - */ -SubTxResetKeyPayload.prototype.setNewPubKeyId = function (pubKeyId) { - this.newPubKey = BufferUtil.copy(pubKeyId); - return this; -}; - -/** - * Extracts and sets pubKeyId from private key - * @param {string|PrivateKey} privateKey - * @return {SubTxResetKeyPayload} - */ -SubTxResetKeyPayload.prototype.setPubKeyIdFromPrivateKey = function ( - privateKey -) { - this.setNewPubKeyId( - SubTxResetKeyPayload.convertPrivateKeyToPubKeyId(privateKey) - ); - return this; -}; - -/** - * Serializes payload to JSON - * @return {{version: *, regTxHash: *, hashPrevSubTx: *, creditFee: *, newPubKeySize: *, newPubKey: *, payloadSigSize: *, payloadSig: *}} - */ -SubTxResetKeyPayload.prototype.toJSON = function toJSON(options) { - var skipSignature = (options && options.skipSignature) || false; - this.validate(); - var payloadJSON = { - version: this.version, - regTxHash: this.regTxHash, - hashPrevSubTx: this.hashPrevSubTx, - creditFee: this.creditFee, - // TODO: enable following line when bug is fixed and core implementation corresponds to DIP5 - //newPubKeySize: this.newPubKeySize, - newPubKey: this.newPubKey, - }; - if (!skipSignature) { - payloadJSON.payloadSigSize = this.payloadSigSize; - payloadJSON.payloadSig = this.payloadSig; - } - return payloadJSON; -}; - -/** - * Serialize payload to buffer - * @return {Buffer} - */ -SubTxResetKeyPayload.prototype.toBuffer = function toBuffer(options) { - var skipSignature = (options && options.skipSignature) || false; - this.validate(); - var payloadBufferWriter = new BufferWriter(); - - payloadBufferWriter.writeUInt16LE(this.version); - payloadBufferWriter.write(Buffer.from(this.regTxHash, 'hex').reverse()); - payloadBufferWriter.write(Buffer.from(this.hashPrevSubTx, 'hex').reverse()); - payloadBufferWriter.writeUInt64LEBN(new BigNumber(this.creditFee)); - // TODO: enable following line when bug is fixed and core implementation corresponds to DIP5 - //payloadBufferWriter.writeVarintNum(this.newPubKeySize); - payloadBufferWriter.write(this.newPubKey); - if (!skipSignature) { - payloadBufferWriter.writeVarintNum(this.payloadSigSize); - payloadBufferWriter.write(Buffer.from(this.payloadSig, 'hex').reverse()); - } else { - payloadBufferWriter.writeVarintNum(0); - } - return payloadBufferWriter.toBuffer(); -}; - -module.exports = SubTxResetKeyPayload; diff --git a/lib/transaction/payload/subtxtopuppayload.js b/lib/transaction/payload/subtxtopuppayload.js deleted file mode 100644 index 42a658ab6..000000000 --- a/lib/transaction/payload/subtxtopuppayload.js +++ /dev/null @@ -1,140 +0,0 @@ -/* eslint-disable */ -// TODO: Remove previous line and work through linting issues at next edit - -var constants = require('../../constants'); -var Preconditions = require('../../util/preconditions'); -var BufferWriter = require('../../encoding/bufferwriter'); -var BufferReader = require('../../encoding/bufferreader'); -var AbstractPayload = require('./abstractpayload'); -var utils = require('../../util/js'); - -var isUnsignedInteger = utils.isUnsignedInteger; -var isSha256HexString = utils.isSha256HexString; - -var CURRENT_PAYLOAD_VERSION = 1; -var HASH_SIZE = constants.SHA256_HASH_SIZE; - -/** - * @typedef {Object} SubTxTopupPayloadJSON - * @property {number} version - * @property {string} regTxHash - */ - -/** - * @class SubTxTopupPayload - * @property {number} version - * @property {string} regTxHash - */ -function SubTxTopupPayload(payloadJSON) { - AbstractPayload.call(this); - - if (payloadJSON) { - this.version = payloadJSON.version; - this.regTxHash = payloadJSON.regTxHash; - - this.validate(); - } else { - this.version = CURRENT_PAYLOAD_VERSION; - } -} - -SubTxTopupPayload.prototype = Object.create(AbstractPayload.prototype); -SubTxTopupPayload.prototype.constructor = AbstractPayload; - -/* Static methods */ - -/** - * Parse raw transition payload - * @param {Buffer} rawPayload - * @return {SubTxTopupPayload} - */ -SubTxTopupPayload.fromBuffer = function (rawPayload) { - var payloadBufferReader = new BufferReader(rawPayload); - var payload = new SubTxTopupPayload(); - - payload.version = payloadBufferReader.readUInt16LE(); - payload.regTxHash = payloadBufferReader - .read(HASH_SIZE) - .reverse() - .toString('hex'); - - if (!payloadBufferReader.finished()) { - throw new Error( - 'Failed to parse payload: raw payload is bigger than expected.' - ); - } - - payload.validate(); - return payload; -}; - -/** - * Create new instance of payload from JSON - * @param {string|SubTxTopupPayloadJSON} payloadJson - * @return {SubTxTopupPayload} - */ -SubTxTopupPayload.fromJSON = function fromJSON(payloadJson) { - return new SubTxTopupPayload(payloadJson); -}; - -/* Instance methods */ - -/** - * Validates payload data - * @return {boolean} - */ -SubTxTopupPayload.prototype.validate = function () { - Preconditions.checkArgument( - isUnsignedInteger(this.version), - 'Expect version to be an unsigned integer' - ); - Preconditions.checkArgument( - isSha256HexString(this.regTxHash), - 'Expect regTxHash to be a hex string representing sha256 hash' - ); - return true; -}; - -/** - * Serializes payload to JSON - * @return {SubTxTopupPayload} - */ -SubTxTopupPayload.prototype.toJSON = function toJSON() { - this.validate(); - return { - version: this.version, - regTxHash: this.regTxHash, - }; -}; - -/** - * Serialize payload to buffer - * @return {Buffer} - */ -SubTxTopupPayload.prototype.toBuffer = function toBuffer() { - this.validate(); - var payloadBufferWriter = new BufferWriter(); - - payloadBufferWriter.writeUInt16LE(this.version); - payloadBufferWriter.write(Buffer.from(this.regTxHash, 'hex').reverse()); - - return payloadBufferWriter.toBuffer(); -}; - -/** - * Copy payload instance - * @return {SubTxTopupPayload} - */ -SubTxTopupPayload.prototype.copy = function copy() { - return SubTxTopupPayload.fromJSON(this.toJSON()); -}; -/** - * @param {string} regTxHash - * @return {SubTxTopupPayload} - */ -SubTxTopupPayload.prototype.setRegTxHash = function (regTxHash) { - this.regTxHash = regTxHash; - return this; -}; - -module.exports = SubTxTopupPayload; diff --git a/lib/transaction/payload/subtxtransitionpayload.js b/lib/transaction/payload/subtxtransitionpayload.js deleted file mode 100644 index 7d1de54bc..000000000 --- a/lib/transaction/payload/subtxtransitionpayload.js +++ /dev/null @@ -1,301 +0,0 @@ -/* eslint-disable */ -// TODO: Remove previous line and work through linting issues at next edit - -var constants = require('../../constants'); -var constants = require('../../constants'); -var Preconditions = require('../../util/preconditions'); -var BufferWriter = require('../../encoding/bufferwriter'); -var BufferReader = require('../../encoding/bufferreader'); -var AbstractPayload = require('./abstractpayload'); -var utils = require('../../util/js'); -var BigNumber = require('bn.js'); - -var isUnsignedInteger = utils.isUnsignedInteger; -var isHexString = utils.isHexaString; - -var CURRENT_PAYLOAD_VERSION = 1; -var HASH_SIZE = constants.SHA256_HASH_SIZE; - -/** - * @typedef {Object} TransitionPayloadJSON - * @property {Number} version - * @property {string} regTxId - * @property {string} hashPrevSubTx - * @property {Number} creditFee - * @property {string} hashSTPacket - * @property {string} [payloadSig] - * @property {string} [payloadSigSize] - */ - -/** - * @class SubTxTransitionPayload - * @property {number} version - * @property {string} regTxId - * @property {string} hashPrevSubTx - * @property {number} creditFee - * @property {string} hashSTPacket - * @property {string} [payloadSig] - * @property {string} [payloadSigSize] - */ -function SubTxTransitionPayload() { - AbstractPayload.call(this); - this.version = CURRENT_PAYLOAD_VERSION; -} - -SubTxTransitionPayload.prototype = Object.create(AbstractPayload.prototype); -SubTxTransitionPayload.prototype.constructor = AbstractPayload; - -/* Static methods */ - -/** - * Serialize transition payload - * @param {TransitionPayloadJSON} transitionPayload - * @return {Buffer} serialized payload - */ -SubTxTransitionPayload.serializeJSONToBuffer = function (transitionPayload) { - var payloadBufferWriter = new BufferWriter(); - - // TODO: credit fee size - payloadBufferWriter - .writeUInt16LE(transitionPayload.version) - .write(Buffer.from(transitionPayload.regTxId, 'hex').reverse()) - .write(Buffer.from(transitionPayload.hashPrevSubTx, 'hex').reverse()) - .writeUInt64LEBN(new BigNumber(transitionPayload.creditFee)) - .write(Buffer.from(transitionPayload.hashSTPacket, 'hex').reverse()); - - if (transitionPayload.payloadSig) { - var signatureBuf = Buffer.from(transitionPayload.payloadSig, 'hex'); - payloadBufferWriter.writeVarintNum(signatureBuf.length); - payloadBufferWriter.write(signatureBuf); - } else { - payloadBufferWriter.writeVarintNum(constants.EMPTY_SIGNATURE_SIZE); - } - - return payloadBufferWriter.toBuffer(); -}; - -/** - * Parse raw transition payload - * @param {Buffer} rawPayload - * @return {SubTxTransitionPayload} - */ -SubTxTransitionPayload.fromBuffer = function (rawPayload) { - var payloadBufferReader = new BufferReader(rawPayload); - var payload = new SubTxTransitionPayload(); - var signatureSize = 0; - payload.version = payloadBufferReader.readUInt16LE(); - payload - .setRegTxId(payloadBufferReader.read(HASH_SIZE).reverse().toString('hex')) - .setHashPrevSubTx( - payloadBufferReader.read(HASH_SIZE).reverse().toString('hex') - ) - .setCreditFee(payloadBufferReader.readUInt64LEBN().toNumber()) - .setHashSTPacket( - payloadBufferReader.read(HASH_SIZE).reverse().toString('hex') - ); - - if (!payloadBufferReader.finished()) { - signatureSize = payloadBufferReader.readVarintNum(); - } - - if (signatureSize > 0) { - payload.payloadSigSize = signatureSize; - payload.payloadSig = payloadBufferReader - .read(signatureSize) - .toString('hex'); - } - - SubTxTransitionPayload.validatePayloadJSON(payload.toJSON()); - return payload; -}; - -/** - * Create new instance of payload from JSON - * @param {string|TransitionPayloadJSON} payloadJson - * @return {SubTxTransitionPayload} - */ -SubTxTransitionPayload.fromJSON = function fromJSON(payloadJson) { - var payload = new SubTxTransitionPayload(); - payload.version = payloadJson.version; - payload - .setHashSTPacket(payloadJson.hashSTPacket) - .setCreditFee(payloadJson.creditFee) - .setRegTxId(payloadJson.regTxId) - .setHashPrevSubTx(payloadJson.hashPrevSubTx); - - if (payloadJson.payloadSig) { - payload.payloadSig = payloadJson.payloadSig; - } - - if (payloadJson.payloadSigSize) { - payload.payloadSigSize = payloadJson.payloadSigSize; - } - - SubTxTransitionPayload.validatePayloadJSON(payload.toJSON()); - return payload; -}; - -/** - * Validate payload - * @param {TransitionPayloadJSON} blockchainUserPayload - * @return {boolean} - */ -SubTxTransitionPayload.validatePayloadJSON = function (blockchainUserPayload) { - if (!blockchainUserPayload) { - throw new Error('No Payload specified'); - } - - Preconditions.checkArgumentType( - blockchainUserPayload.version, - 'number', - 'version' - ); - Preconditions.checkArgumentType( - blockchainUserPayload.creditFee, - 'number', - 'creditFee' - ); - - Preconditions.checkArgument( - isUnsignedInteger(blockchainUserPayload.version), - 'Expect version to be an unsigned integer' - ); - Preconditions.checkArgument( - isUnsignedInteger(blockchainUserPayload.creditFee), - 'Expect creditFee to be an unsigned integer' - ); - - Preconditions.checkArgument( - isHexString(blockchainUserPayload.regTxId), - 'expect regTxId to be a hex string but got ' + - typeof blockchainUserPayload.regTxId - ); - Preconditions.checkArgument( - blockchainUserPayload.regTxId.length === constants.SHA256_HASH_SIZE * 2, - 'Invalid regTxId size' - ); - - Preconditions.checkArgument( - isHexString(blockchainUserPayload.hashPrevSubTx), - 'expect hashPrevSubTx to be a hex string but got ' + - typeof blockchainUserPayload.hashPrevSubTx - ); - Preconditions.checkArgument( - blockchainUserPayload.hashPrevSubTx.length === - constants.SHA256_HASH_SIZE * 2, - 'Invalid hashPrevSubTx size' - ); - - Preconditions.checkArgument( - isHexString(blockchainUserPayload.hashSTPacket), - 'expect hashSTPacket to be a hex string but got ' + - typeof blockchainUserPayload.hashSTPacket - ); - Preconditions.checkArgument( - blockchainUserPayload.hashSTPacket.length === - constants.SHA256_HASH_SIZE * 2, - 'Invalid hashSTPacket size' - ); - - if (blockchainUserPayload.payloadSig) { - Preconditions.checkArgument( - isHexString(blockchainUserPayload.payloadSig), - 'expect payloadSig to be a hex string but got ' + - typeof blockchainUserPayload.payloadSig - ); - Preconditions.checkArgument( - blockchainUserPayload.payloadSig.length === - constants.COMPACT_SIGNATURE_SIZE * 2, - 'Invalid payloadSig size' - ); - } -}; - -/* Instance methods */ - -/** - * Validates payload data - * @return {boolean} - */ -SubTxTransitionPayload.prototype.validate = function () { - return SubTxTransitionPayload.validatePayloadJSON(this.toJSON()); -}; - -/** - * @param {string} regTxId - Hex string - */ -SubTxTransitionPayload.prototype.setRegTxId = function (regTxId) { - this.regTxId = regTxId; - return this; -}; - -/** - * @param {string} hashPrevSubTx - Hex string - * @return {SubTxTransitionPayload} - */ -SubTxTransitionPayload.prototype.setHashPrevSubTx = function (hashPrevSubTx) { - this.hashPrevSubTx = hashPrevSubTx; - return this; -}; - -/** - * @param {string} hashSTPacket - Hex string - * @return {SubTxTransitionPayload} - */ -SubTxTransitionPayload.prototype.setHashSTPacket = function (hashSTPacket) { - this.hashSTPacket = hashSTPacket; - return this; -}; - -/** - * @param {number} creditFee - * @return {SubTxTransitionPayload} - */ -SubTxTransitionPayload.prototype.setCreditFee = function (creditFee) { - this.creditFee = creditFee; - return this; -}; - -/** - * Serializes payload to JSON - * @param [options] - * @param {boolean} options.skipSignature - skip signature part. Needed for creating new signature - * @return {TransitionPayloadJSON} - */ -SubTxTransitionPayload.prototype.toJSON = function toJSON(options) { - var skipSignature = - Boolean(options && options.skipSignature) || !Boolean(this.payloadSig); - var payloadJSON = { - version: this.version, - regTxId: this.regTxId, - hashPrevSubTx: this.hashPrevSubTx, - creditFee: this.creditFee, - hashSTPacket: this.hashSTPacket, - }; - if (!skipSignature) { - payloadJSON.payloadSig = this.payloadSig; - payloadJSON.payloadSigSize = this.payloadSigSize; - } - SubTxTransitionPayload.validatePayloadJSON(payloadJSON); - return payloadJSON; -}; - -/** - * Serialize payload to buffer - * @param [options] - * @param {boolean} options.skipSignature - skip signature part. Needed for creating new signature - * @return {Buffer} - */ -SubTxTransitionPayload.prototype.toBuffer = function toBuffer(options) { - return SubTxTransitionPayload.serializeJSONToBuffer(this.toJSON(options)); -}; - -/** - * Copy payload instance - * @return {SubTxTransitionPayload} - */ -SubTxTransitionPayload.prototype.copy = function copy() { - return SubTxTransitionPayload.fromJSON(this.toJSON()); -}; - -module.exports = SubTxTransitionPayload; diff --git a/lib/transaction/transaction.js b/lib/transaction/transaction.js index eb3d33799..150a91b49 100644 --- a/lib/transaction/transaction.js +++ b/lib/transaction/transaction.js @@ -247,7 +247,7 @@ Transaction.prototype.getSerializationError = function (opts) { if (!opts.disableMoreOutputThanInput) { unspentError = new errors.Transaction.InvalidOutputAmountSum(); } - } else if (!this.canHaveNoUtxo()) { + } else { unspentError = this._hasFeeError(opts, unspent); } @@ -259,9 +259,8 @@ Transaction.prototype.getSerializationError = function (opts) { return new errors.Transaction.SpecialTransactionTypeIsNotSet(); } - var isMissingSignatures = - !this.canHaveNoUtxo() && this._isMissingSignatures(opts); - var hasDustOutputs = !this.canHaveNoUtxo() && this._hasDustOutputs(opts); + var isMissingSignatures = this._isMissingSignatures(opts); + var hasDustOutputs = this._hasDustOutputs(opts); return unspentError || hasDustOutputs || isMissingSignatures; }; @@ -1209,9 +1208,7 @@ Transaction.prototype.removeInput = function (txId, outputIndex) { * @return {Transaction} this, for chaining */ Transaction.prototype.sign = function (privateKey, sigtype) { - if (!this.canHaveNoUtxo()) { - $.checkState(this.hasAllUtxoInfo()); - } + $.checkState(this.hasAllUtxoInfo()); var self = this; if (_.isArray(privateKey)) { _.each(privateKey, function (privateKey) { @@ -1242,13 +1239,6 @@ Transaction.prototype.getSignatures = function (privKey, sigtype) { return results; }; -Transaction.prototype.canHaveNoUtxo = function () { - return ( - this.isSpecialTransaction() && - this.type === Transaction.TYPES.TRANSACTION_SUBTX_TRANSITION - ); -}; - /** * Add a signature to the transaction * diff --git a/test-d/index.test-d.ts b/test-d/index.test-d.ts index 8022a35d3..115995e4c 100644 --- a/test-d/index.test-d.ts +++ b/test-d/index.test-d.ts @@ -43,14 +43,9 @@ import type { ProUpRegTxPayload, ProUpRevTxPayload, ProUpServTxPayload, - SubTxCloseAccountPayload, - SubTxRegisterPayload, - SubTxResetKeyPayload, - SubTxTopupPayload, - SubTxTransitionPayload, Output, Transaction, TransactionSignature, UnspentOutput, - ChainLockSigMessage + ChainLockSigMessage, } from ".."; diff --git a/test/transaction/payload/assetlockpayload.js b/test/transaction/payload/assetlockpayload.js new file mode 100644 index 000000000..b3a33d8e1 --- /dev/null +++ b/test/transaction/payload/assetlockpayload.js @@ -0,0 +1,229 @@ +/* eslint-disable */ +// TODO: Remove previous line and work through linting issues at next edit + +var expect = require('chai').expect; +var sinon = require('sinon'); + +var DashcoreLib = require('../../../index'); + +var BN = require('../../../lib/crypto/bn'); + +var AssetLockPayload = DashcoreLib.Transaction.Payload.AssetLockPayload; +var Script = DashcoreLib.Script; +var Address = DashcoreLib.Address; +var Output = DashcoreLib.Transaction.Output; + +var output1 = Output.fromObject({ + satoshis: 1000, + script: Script.buildPublicKeyHashOut( + Address.fromString('XxGJLCB7BBXAgA1AbgtNDMyVpQV9yXd7oB', 'mainnet') + ).toHex() +}); + +var output2 = Output.fromObject({ + satoshis: 2000, + script: Script.buildPublicKeyHashOut( + Address.fromString('7hRXBxSmKqaJ6JfsVaSeZqAeyxvrxcHyV1', 'mainnet') + ).toHex() +}); + + +var validAssetLockPayloadJSON = { + version: 1, + creditOutputs: [ + output1.toJSON(), + output2.toJSON() + ] +}; +// Contains same data as JSON above +var validAssetLockPayload = AssetLockPayload.fromJSON(validAssetLockPayloadJSON); +var validAssetLockPayloadBuffer = validAssetLockPayload.toBuffer(); +var validAssetLockPayloadHexString = validAssetLockPayloadBuffer.toString('hex'); + +describe('AssetLockPayload', function () { + describe('.fromBuffer', function () { + beforeEach(function () { + sinon.spy(AssetLockPayload.prototype, 'validate'); + }); + + afterEach(function () { + AssetLockPayload.prototype.validate.restore(); + }); + + it('Should return instance of AssetLockPayload and call #validate on it', function () { + var payload = AssetLockPayload.fromBuffer(validAssetLockPayloadBuffer); + + expect(payload).to.be.an.instanceOf(AssetLockPayload); + expect(payload.version).to.be.equal(1); + expect(payload.creditOutputs).to.deep.equal([ + output1, + output2 + ]); + expect(payload.validate.callCount).to.be.equal(1); + }); + + it('Should throw in case if there is some unexpected information in raw payload', function () { + var payloadWithAdditionalZeros = Buffer.from( + validAssetLockPayloadHexString + '0000', + 'hex' + ); + + expect(function () { + AssetLockPayload.fromBuffer(payloadWithAdditionalZeros); + }).to.throw( + 'Failed to parse payload: raw payload is bigger than expected.' + ); + }); + }); + + describe('.fromJSON', function () { + before(function () { + sinon.spy(AssetLockPayload.prototype, 'validate'); + }); + + it('Should return instance of AssetLockPayload and call #validate on it', function () { + var payload = AssetLockPayload.fromJSON(validAssetLockPayloadJSON); + + expect(payload).to.be.an.instanceOf(AssetLockPayload); + expect(payload.version).to.be.equal(1); + expect(payload.creditOutputs) + .to.deep.equal([ + output1, + output2 + ]); + }); + + after(function () { + AssetLockPayload.prototype.validate.restore(); + }); + }); + + describe('#validate', function () { + it('Should allow only unsigned integer as version', function () { + var payload = validAssetLockPayload.copy(); + + payload.version = -1; + + expect(function () { + payload.validate(); + }).to.throw('Invalid Argument: Expect version to be an unsigned integer'); + + payload.version = 1.5; + + expect(function () { + payload.validate(); + }).to.throw('Invalid Argument: Expect version to be an unsigned integer'); + + payload.version = '12'; + + expect(function () { + payload.validate(); + }).to.throw('Invalid Argument: Expect version to be an unsigned integer'); + + payload.version = Buffer.from('0a0f', 'hex'); + + expect(function () { + payload.validate(); + }).to.throw('Invalid Argument: Expect version to be an unsigned integer'); + + payload.version = 123; + + expect(function () { + payload.validate(); + }).not.to.throw; + }); + + describe('creditOutputs', function () { + it('should not allow empty array', function() { + var payload = validAssetLockPayload.copy(); + payload.creditOutputs = []; + + expect(function () { + payload.validate(); + }).to.throw( + 'Invalid Argument: Empty credit outputs' + ); + }); + + it('should allow only instances of Output', function() { + var payload = validAssetLockPayload.copy(); + payload.creditOutputs.push('Test'); + + expect(function () { + payload.validate(); + }).to.throw( + 'Invalid Argument: Credit output 2 is not an instance of Output' + ); + }); + + it('should allow only P2PKH Outputs', function() { + var payload = validAssetLockPayload.copy(); + payload.creditOutputs.push(Output.fromObject({ + satoshis: 1000, + script: Script.buildDataOut('0x0') + })); + + expect(function () { + payload.validate(); + }).to.throw( + 'Invalid Argument: Credit output 2 is not P2PKH' + ); + }); + }); + }); + + describe('#toJSON', function () { + beforeEach(function () { + sinon.spy(AssetLockPayload.prototype, 'validate'); + }); + + afterEach(function () { + AssetLockPayload.prototype.validate.restore(); + }); + + it('Should be able to serialize payload JSON', function () { + var payload = validAssetLockPayload.copy(); + + var payloadJSON = payload.toJSON(); + + expect(payloadJSON.version).to.be.equal(payload.version); + expect(payloadJSON.creditOutputs) + .to.deep.equal(payload.creditOutputs.map(output => output.toJSON())); + }); + it('Should call #validate', function () { + var payload = AssetLockPayload.fromJSON(validAssetLockPayloadJSON); + AssetLockPayload.prototype.validate.resetHistory(); + payload.toJSON(); + expect(payload.validate.callCount).to.be.equal(1); + }); + }); + + describe('#toBuffer', function () { + beforeEach(function () { + sinon.spy(AssetLockPayload.prototype, 'validate'); + }); + + afterEach(function () { + AssetLockPayload.prototype.validate.restore(); + }); + + it('Should be able to serialize payload to Buffer', function () { + var payload = validAssetLockPayload.copy(); + + var serializedPayload = payload.toBuffer(); + var restoredPayload = AssetLockPayload.fromBuffer(serializedPayload); + + expect(restoredPayload.version).to.be.equal(payload.version); + expect(payload.creditOutputs).to.deep.equal([ + output1, + output2 + ]); + }); + it('Should call #validate', function () { + var payload = AssetLockPayload.fromJSON(validAssetLockPayloadJSON); + AssetLockPayload.prototype.validate.resetHistory(); + payload.toBuffer(); + expect(payload.validate.callCount).to.be.equal(1); + }); + }); +}); diff --git a/test/transaction/payload/subtxcloseaccountpayload.js b/test/transaction/payload/subtxcloseaccountpayload.js deleted file mode 100644 index ea171e9f0..000000000 --- a/test/transaction/payload/subtxcloseaccountpayload.js +++ /dev/null @@ -1,537 +0,0 @@ -/* eslint-disable */ -// TODO: Remove previous line and work through linting issues at next edit - -var expect = require('chai').expect; -var sinon = require('sinon'); -var DashcoreLib = require('../../../index'); -var SubTxCloseAccountPayload = - DashcoreLib.Transaction.Payload.SubTxCloseAccountPayload; -var PrivateKey = DashcoreLib.PrivateKey; -var BufferUtil = DashcoreLib.util.buffer; -var isHexString = DashcoreLib.util.js.isHexaString; -var privateKey = 'cQSA77TsRYNEsYRmLoY7Y3gNF3Kb5qff4yUv3hWB7fm46YQ2njqN'; -var regTxHash = - '54b8f5e4e77853f136ced5d29e92afabf380bf37ac54b46755c2211774960ee1'; -var prevSubTxHash = - 'bf742c5eafd6f8f1241a9e1a0a62fd7e5affed72178d8e03712fe42a34c27ca7'; -var pubKeyId = new PrivateKey(privateKey).toPublicKey()._getID(); -var CORRECT_SIGNATURE_SIZE = - DashcoreLib.Transaction.Payload.constants.COMPACT_SIGNATURE_SIZE; -var payloadSig = - '8167200911e63e846621d6e5c7f55ea872a791d9ef51fa32294ce2a3e4247016f0750c9cb7af3a50f19455b77f9789f79b7c5ecb84dbb897b3d50961b73a003b1f'; - -var validSubTxCloseAccountPayloadJSON = { - version: 1, - regTxHash: regTxHash, - hashPrevSubTx: prevSubTxHash, - creditFee: 1000, -}; - -var validSubTxCloseAccountPayloadJSONsigned = { - version: 1, - regTxHash: regTxHash, - hashPrevSubTx: prevSubTxHash, - creditFee: 1000, - payloadSigSize: 65, - payloadSig: payloadSig, -}; - -var validSubTxCloseAccountPayloadHexString = - '0100e10e96741721c25567b454ac37bf80f3abaf929ed2d5ce36f15378e7e4f5b854a77cc2342ae42f71038e8d1772edff5a7efd620a1a9e1a24f1f8d6af5e2c74bfe80300000000000000'; -var validSubTxCloseAccountPayloadBuffer = Buffer.from( - validSubTxCloseAccountPayloadHexString, - 'hex' -); -var validSubTxCloseAccountPayload = SubTxCloseAccountPayload.fromBuffer( - validSubTxCloseAccountPayloadBuffer -); - -var validSubTxCloseAccountPayloadHexStringSigned = - '0100e10e96741721c25567b454ac37bf80f3abaf929ed2d5ce36f15378e7e4f5b854a77cc2342ae42f71038e8d1772edff5a7efd620a1a9e1a24f1f8d6af5e2c74bfe803000000000000411f3b003ab76109d5b397b8db84cb5e7c9bf789977fb75594f1503aafb79c0c75f0167024e4a3e24c2932fa51efd991a772a85ef5c7e5d62166843ee61109206781'; -var validSubTxCloseAccountPayloadBufferSigned = Buffer.from( - validSubTxCloseAccountPayloadHexStringSigned, - 'hex' -); -var validSubTxCloseAccountPayloadSigned = SubTxCloseAccountPayload.fromBuffer( - validSubTxCloseAccountPayloadBufferSigned -); - -describe('SubTxCloseAccountPayload', function () { - describe('constructor', function () { - it('Should create SubTxCloseAccountPayload instance', function () { - var payload = new SubTxCloseAccountPayload(); - expect(payload).to.have.property('version'); - }); - }); - - describe('.fromBuffer', function () { - beforeEach(function () { - sinon.spy(SubTxCloseAccountPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxCloseAccountPayload.prototype.validate.restore(); - }); - - it('Should return instance of SubTxCloseAccountPayload and call #validate on it', function () { - var payload = SubTxCloseAccountPayload.fromBuffer( - Buffer.from(validSubTxCloseAccountPayloadHexString, 'hex') - ); - - expect(payload.version).to.be.equal(1); - expect(payload.regTxHash).to.be.equal(regTxHash); - expect(payload.hashPrevSubTx).to.be.equal(prevSubTxHash); - expect(payload.creditFee).to.be.equal(1000); - }); - - it('Should throw in case if there is some unexpected information in raw payload', function () { - var payloadWithAdditionalZeros = Buffer.from( - validSubTxCloseAccountPayloadHexString + '0000', - 'hex' - ); - - expect(function () { - SubTxCloseAccountPayload.fromBuffer(payloadWithAdditionalZeros); - }).to.throw( - 'Failed to parse payload: raw payload is bigger than expected.' - ); - }); - - it('Should return instance of SubTxCloseAccountPayload with parsed data', function () { - var payloadBuffer = new SubTxCloseAccountPayload() - .setRegTxHash(regTxHash) - .setPrevSubTxHash(prevSubTxHash) - .setCreditFee(1000) - .toBuffer({ skipSignature: true }); - - expect(BufferUtil.isBuffer(payloadBuffer)).to.be.true; - - var parsedPayload = SubTxCloseAccountPayload.fromBuffer(payloadBuffer); - expect(parsedPayload.regTxHash).to.be.equal(regTxHash); - expect(parsedPayload.hashPrevSubTx).to.be.equal(prevSubTxHash); - expect(parsedPayload.creditFee).to.be.equal(1000); - }); - - it('Should throw an error if data is incomplete', function () { - var payloadBuffer = new SubTxCloseAccountPayload() - .setRegTxHash(regTxHash) - .setPrevSubTxHash(prevSubTxHash) - .setCreditFee(1000) - .toBuffer({ skipSignature: true }); - // 2 bytes is payload version, 32 is regTxHash size, 32 is preSubTxHash - var payloadBufferWithoutCreditFee = payloadBuffer.slice(0, 2 + 32 + 32); - - expect(function () { - SubTxCloseAccountPayload.fromBuffer(payloadBufferWithoutCreditFee); - }).to.throw(); - }); - }); - - describe('.fromBuffer signed', function () { - beforeEach(function () { - sinon.spy(SubTxCloseAccountPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxCloseAccountPayload.prototype.validate.restore(); - }); - - it('Should return instance of SubTxCloseAccountPayload and call #validate on it', function () { - var payload = SubTxCloseAccountPayload.fromBuffer( - Buffer.from(validSubTxCloseAccountPayloadHexStringSigned, 'hex') - ); - - expect(payload.version).to.be.equal(1); - expect(payload.regTxHash).to.be.equal(regTxHash); - expect(payload.hashPrevSubTx).to.be.equal(prevSubTxHash); - expect(payload.creditFee).to.be.equal(1000); - expect(payload.payloadSigSize).to.be.equal(65); - expect(payload.payloadSig).to.be.equal(payloadSig); - }); - - it('Should throw in case if there is some unexpected information in raw payload', function () { - var payloadWithAdditionalZeros = Buffer.from( - validSubTxCloseAccountPayloadHexString + '0000', - 'hex' - ); - - expect(function () { - SubTxCloseAccountPayload.fromBuffer(payloadWithAdditionalZeros); - }).to.throw( - 'Failed to parse payload: raw payload is bigger than expected.' - ); - }); - }); - - describe('.fromJSON', function () { - before(function () { - sinon.spy(SubTxCloseAccountPayload.prototype, 'validate'); - }); - - it('Should return instance of SubTxCloseAccountPayload and call #validate on it', function () { - var payload = SubTxCloseAccountPayload.fromJSON( - validSubTxCloseAccountPayloadJSON - ); - - expect(payload.version).to.be.equal(1); - expect(payload.regTxHash).to.be.equal(regTxHash); - expect(payload.hashPrevSubTx).to.be.equal(prevSubTxHash); - expect(payload.creditFee).to.be.equal(1000); - }); - - after(function () { - SubTxCloseAccountPayload.prototype.validate.restore(); - }); - - it('Should return instance of SubTxCloseAccountPayload with correct parsed data', function () { - var payloadJSON = { - version: 10, - regTxHash: regTxHash, - hashPrevSubTx: prevSubTxHash, - creditFee: 1000, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payload = SubTxCloseAccountPayload.fromJSON(payloadJSON); - expect(payload.version).to.be.equal(10); - expect(payload.regTxHash).to.be.equal(payloadJSON.regTxHash); - expect(payload.hashPrevSubTx).to.be.equal(payloadJSON.hashPrevSubTx); - expect(payload.creditFee).to.be.equal(payloadJSON.creditFee); - expect(BufferUtil.equals(payload.payloadSig, payloadJSON.payloadSig)).to - .be.true; - }); - it('Should throw an error if the data is incomplete', function () { - var payloadWithoutRegTxHash = { - version: 10, - hashPrevSubTx: prevSubTxHash, - creditFee: 1000, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payloadWithoutCreditFee = { - version: 10, - regTxHash: regTxHash, - hashPrevSubTx: prevSubTxHash, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payloadWithoutVersion = { - regTxHash: regTxHash, - hashPrevSubTx: prevSubTxHash, - creditFee: 1000, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - expect(function () { - SubTxCloseAccountPayload.fromJSON(payloadWithoutRegTxHash); - }).to.throw( - 'Invalid Argument: Expect regTxHash to be a hex string representing sha256 hash' - ); - expect(function () { - SubTxCloseAccountPayload.fromJSON(payloadWithoutCreditFee); - }).to.throw( - 'Invalid Argument for creditFee, expected number but got undefined' - ); - expect(function () { - SubTxCloseAccountPayload.fromJSON(payloadWithoutVersion); - }).to.throw( - 'Invalid Argument for version, expected number but got undefined' - ); - }); - it('Should throw an error if the data is incorrect', function () { - var payloadWithIncorrectRegTxHash = { - version: 10, - regTxHash: 10, - hashPrevSubTx: prevSubTxHash, - creditFee: 1000, - payloadSigSize: CORRECT_SIGNATURE_SIZE, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payloadWithIncorrectVersion = { - version: '10', - regTxHash: regTxHash, - hashPrevSubTx: prevSubTxHash, - creditFee: 1000, - payloadSigSize: CORRECT_SIGNATURE_SIZE, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payloadWithIncorrectSignature = { - version: 10, - regTxHash: regTxHash, - hashPrevSubTx: prevSubTxHash, - creditFee: 1000, - payloadSigSize: CORRECT_SIGNATURE_SIZE, - payloadSig: 'signature', - }; - var payloadWithIncorrectSignatureSize = { - version: 10, - regTxHash: regTxHash, - hashPrevSubTx: prevSubTxHash, - creditFee: 1000, - payloadSig: BufferUtil.emptyBuffer(22).toString('hex'), - }; - expect(function () { - SubTxCloseAccountPayload.fromJSON(payloadWithIncorrectRegTxHash); - }).to.throw( - 'Invalid Argument: Expect regTxHash to be a hex string representing sha256 hash' - ); - expect(function () { - SubTxCloseAccountPayload.fromJSON(payloadWithIncorrectVersion); - }).to.throw( - 'Invalid Argument for version, expected number but got string' - ); - expect(function () { - SubTxCloseAccountPayload.fromJSON(payloadWithIncorrectSignature); - }).to.throw( - 'Invalid Argument: expect payloadSig to be a hex string but got string' - ); - expect(function () { - SubTxCloseAccountPayload.fromJSON(payloadWithIncorrectSignatureSize); - }).to.throw('Invalid Argument: Invalid payloadSigSize size'); - }); - }); - - describe('.fromJSON signed', function () { - before(function () { - sinon.spy(SubTxCloseAccountPayload.prototype, 'validate'); - }); - - it('Should return instance of SubTxCloseAccountPayload and call #validate on it', function () { - var payload = SubTxCloseAccountPayload.fromJSON( - validSubTxCloseAccountPayloadJSONsigned - ); - - expect(payload.version).to.be.equal(1); - expect(payload.regTxHash).to.be.equal(regTxHash); - expect(payload.hashPrevSubTx).to.be.equal(prevSubTxHash); - expect(payload.creditFee).to.be.equal(1000); - expect(payload.payloadSigSize).to.be.equal(65); - expect(payload.payloadSig).to.be.equal(payloadSig); - }); - - after(function () { - SubTxCloseAccountPayload.prototype.validate.restore(); - }); - }); - describe('#setRegTxHash', function () { - it('Should set regTxHash and return instance back', function () { - var payload = new SubTxCloseAccountPayload().setRegTxHash(regTxHash); - - expect(payload).to.be.an.instanceOf(SubTxCloseAccountPayload); - expect(payload.regTxHash).to.be.equal(regTxHash); - }); - }); - describe('#setPrevSubTxHash', function () { - it('Should set regTxHash and return instance back', function () { - var payload = new SubTxCloseAccountPayload().setPrevSubTxHash( - prevSubTxHash - ); - - expect(payload).to.be.an.instanceOf(SubTxCloseAccountPayload); - expect(payload.hashPrevSubTx).to.be.equal(prevSubTxHash); - }); - }); - describe('#setCreditFee', function () { - it('Should set creditFee and return instance back', function () { - var payload = new SubTxCloseAccountPayload().setCreditFee(1000); - - expect(payload).to.be.an.instanceOf(SubTxCloseAccountPayload); - expect(payload.creditFee).to.be.deep.equal(1000); - }); - }); - describe('#sign', function () { - it('Should sign payload and return instance back if a private key is a string', function () { - var payload = new SubTxCloseAccountPayload() - .setRegTxHash(regTxHash) - .setPrevSubTxHash(prevSubTxHash) - .setCreditFee(1000) - .sign(privateKey); - expect(payload.payloadSig).to.be.a.string; - expect(isHexString(payload.payloadSig)).to.be.true; - expect(payload.payloadSig.length).to.be.equal(CORRECT_SIGNATURE_SIZE * 2); - }); - it('Should sign payload and return instance back if a private key is an instance of PrivateKey', function () { - var payload = new SubTxCloseAccountPayload() - .setRegTxHash(regTxHash) - .setPrevSubTxHash(prevSubTxHash) - .setCreditFee(1000) - .sign(new PrivateKey(privateKey)); - expect(payload.payloadSig).to.be.a.string; - expect(isHexString(payload.payloadSig)).to.be.true; - expect(payload.payloadSig.length).to.be.equal(CORRECT_SIGNATURE_SIZE * 2); - }); - it('Should throw when trying to sign incomplete data', function () { - var payload = new SubTxCloseAccountPayload().setRegTxHash(regTxHash); - - expect(function () { - payload.sign(privateKey); - }).to.throw( - 'Invalid Argument for creditFee, expected number but got undefined' - ); - }); - }); - describe('#verifyHashSignature', function () { - it('Should verify signature if pubKeyId is a Buffer', function () { - var payload = new SubTxCloseAccountPayload() - .setRegTxHash(regTxHash) - .setPrevSubTxHash(prevSubTxHash) - .setCreditFee(1000) - .sign(privateKey); - - expect( - payload.verifySignature( - SubTxCloseAccountPayload.convertPrivateKeyToPubKeyId(privateKey) - ) - ).to.be.true; - }); - it('Should verify signature if pubKeyId is a hex string', function () { - var payload = new SubTxCloseAccountPayload() - .setRegTxHash(regTxHash) - .setPrevSubTxHash(prevSubTxHash) - .setCreditFee(1000) - .sign(privateKey); - - expect(payload.verifySignature(pubKeyId.toString('hex'))).to.be.true; - }); - it("Should return false if pubKeyId doesn't match the signature", function () { - var payload = new SubTxCloseAccountPayload() - .setRegTxHash(regTxHash) - .setPrevSubTxHash(prevSubTxHash) - .setCreditFee(1000) - .sign(privateKey); - - expect(payload.verifySignature(new PrivateKey().toPublicKey()._getID())) - .to.be.false; - }); - }); - describe('#toJSON', function () { - beforeEach(function () { - sinon.spy(SubTxCloseAccountPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxCloseAccountPayload.prototype.validate.restore(); - }); - - it('Should be able to serialize payload JSON', function () { - var payload = validSubTxCloseAccountPayload; - - var payloadJSON = payload.toJSON({ skipSignature: true }); - - expect(payloadJSON.version).to.be.equal(1); - expect(payloadJSON.regTxHash).to.be.equal(regTxHash); - expect(payloadJSON.hashPrevSubTx).to.be.equal(prevSubTxHash); - expect(payloadJSON.creditFee).to.be.equal(1000); - }); - it('Should call #validate', function () { - var payload = SubTxCloseAccountPayload.fromJSON( - validSubTxCloseAccountPayloadJSON - ); - SubTxCloseAccountPayload.prototype.validate.resetHistory(); - payload.toJSON({ skipSignature: true }); - expect(payload.validate.callCount).to.be.equal(1); - }); - }); - - describe('#toJSON signed', function () { - beforeEach(function () { - sinon.spy(SubTxCloseAccountPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxCloseAccountPayload.prototype.validate.restore(); - }); - - it('Should be able to serialize payload JSON', function () { - var payload = validSubTxCloseAccountPayloadSigned; - var payloadJSON = payload.toJSON(); - expect(payloadJSON.version).to.be.equal(1); - expect(payloadJSON.regTxHash).to.be.equal(regTxHash); - expect(payloadJSON.hashPrevSubTx).to.be.equal(prevSubTxHash); - expect(payloadJSON.creditFee).to.be.equal(1000); - expect(payloadJSON.payloadSigSize).to.be.equal(65); - expect(payloadJSON.payloadSig).to.be.equal(payloadSig); - }); - it('Should call #validate', function () { - var payload = SubTxCloseAccountPayload.fromJSON( - validSubTxCloseAccountPayloadJSONsigned - ); - SubTxCloseAccountPayload.prototype.validate.resetHistory(); - payload.toJSON(); - expect(payload.validate.callCount).to.be.equal(1); - }); - }); - - describe('#toBuffer', function () { - beforeEach(function () { - sinon.spy(SubTxCloseAccountPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxCloseAccountPayload.prototype.validate.restore(); - }); - - it('Should be able to serialize payload to Buffer', function () { - var payload = validSubTxCloseAccountPayload; - - var serializedPayload = payload.toBuffer({ skipSignature: true }); - var restoredPayload = - SubTxCloseAccountPayload.fromBuffer(serializedPayload); - - expect(restoredPayload.version).to.be.equal(1); - expect(restoredPayload.regTxHash).to.be.equal(regTxHash); - expect(restoredPayload.hashPrevSubTx).to.be.equal(prevSubTxHash); - expect(restoredPayload.creditFee).to.be.equal(1000); - expect(restoredPayload.payloadSigSize).to.be.equal(0); - }); - it('Should call #validate', function () { - var payload = SubTxCloseAccountPayload.fromJSON( - validSubTxCloseAccountPayloadJSON - ); - SubTxCloseAccountPayload.prototype.validate.resetHistory(); - payload.toBuffer({ skipSignature: true }); - expect(payload.validate.callCount).to.be.equal(1); - }); - }); - - describe('#toBuffer signed', function () { - beforeEach(function () { - sinon.spy(SubTxCloseAccountPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxCloseAccountPayload.prototype.validate.restore(); - }); - - it('Should be able to serialize payload to Buffer', function () { - var payload = validSubTxCloseAccountPayloadSigned; - - var serializedPayload = payload.toBuffer(); - var restoredPayload = - SubTxCloseAccountPayload.fromBuffer(serializedPayload); - - expect(restoredPayload.version).to.be.equal(1); - expect(restoredPayload.regTxHash).to.be.equal(regTxHash); - expect(restoredPayload.hashPrevSubTx).to.be.equal(prevSubTxHash); - expect(restoredPayload.creditFee).to.be.equal(1000); - expect(restoredPayload.payloadSigSize).to.be.equal(65); - expect(restoredPayload.payloadSig).to.be.equal(payloadSig); - }); - it('Should call #validate', function () { - var payload = SubTxCloseAccountPayload.fromJSON( - validSubTxCloseAccountPayloadJSONsigned - ); - SubTxCloseAccountPayload.prototype.validate.resetHistory(); - payload.toBuffer(); - expect(payload.validate.callCount).to.be.equal(1); - }); - }); -}); diff --git a/test/transaction/payload/subtxregisterpayload.js b/test/transaction/payload/subtxregisterpayload.js deleted file mode 100644 index 697eacc1c..000000000 --- a/test/transaction/payload/subtxregisterpayload.js +++ /dev/null @@ -1,385 +0,0 @@ -/* eslint-disable */ -// TODO: Remove previous line and work through linting issues at next edit - -var expect = require('chai').expect; - -var DashcoreLib = require('../../../index'); - -var PrivateKey = DashcoreLib.PrivateKey; -var BufferUtil = DashcoreLib.util.buffer; -var Payload = DashcoreLib.Transaction.Payload; -var SubTxRegisterPayload = Payload.SubTxRegisterPayload; -var isHexString = DashcoreLib.util.js.isHexaString; - -var CORRECT_SIGNATURE_SIZE = Payload.constants.COMPACT_SIGNATURE_SIZE; -var privateKey = 'cSBnVM4xvxarwGQuAfQFwqDg9k5tErHUHzgWsEfD4zdwUasvqRVY'; -var pubKeyId = new PrivateKey(privateKey).toPublicKey()._getID(); - -describe('SubTxRegisterPayload', function () { - describe('constructor', function () { - it('Should create SubTxRegisterPayload instance', function () { - var payload = new SubTxRegisterPayload(); - expect(payload).to.have.property('version'); - }); - }); - describe('fromBuffer', function () { - it('Should return instance of SubTxRegisterPayload with parsed data', function () { - var payloadBuffer = new SubTxRegisterPayload() - .setUserName('test') - .setPubKeyId(pubKeyId) - .toBuffer(); - - expect(BufferUtil.isBuffer(payloadBuffer)).to.be.true; - - var parsedPayload = SubTxRegisterPayload.fromBuffer(payloadBuffer); - expect(parsedPayload.userName).to.be.equal('test'); - expect(BufferUtil.equals(parsedPayload.pubKeyId, pubKeyId)).to.be.true; - }); - it('Should throw an error if data is incomplete', function () { - var payloadBuffer = new SubTxRegisterPayload() - .setUserName('test') - .setPubKeyId(pubKeyId) - .toBuffer(); - // 2 bytes is payload version, 1 is username size, 2 is sig size and zero signature - var payloadBufferWithoutPubKeyId = payloadBuffer.slice( - 0, - 2 + 1 + Buffer.from('test').length + 2 - ); - - expect(function () { - SubTxRegisterPayload.fromBuffer(payloadBufferWithoutPubKeyId); - }).to.throw(); - }); - }); - describe('fromJSON', function () { - it('Should return instance of SubTxRegisterPayload with correct parsed data', function () { - var payloadJSON = { - version: 10, - userName: 'test', - pubKeyId: pubKeyId, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payload = SubTxRegisterPayload.fromJSON(payloadJSON); - expect(payload.version).to.be.equal(10); - expect(payload.userName).to.be.equal('test'); - expect(BufferUtil.equals(payload.pubKeyId, payloadJSON.pubKeyId)).to.be - .true; - expect(BufferUtil.equals(payload.payloadSig, payloadJSON.payloadSig)).to - .be.true; - }); - it('Should throw an error if the data is incomplete', function () { - var payloadWithoutUserName = { - version: 10, - pubKeyId: pubKeyId, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE), - }; - var payloadWithoutPubKeyId = { - version: 10, - userName: 'test', - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE), - }; - var payloadWithoutVersion = { - userName: 'test', - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE), - pubKeyId: pubKeyId, - }; - expect(function () { - SubTxRegisterPayload.fromJSON(payloadWithoutUserName); - }).to.throw( - 'Invalid Argument for userName, expected string but got undefined' - ); - expect(function () { - SubTxRegisterPayload.fromJSON(payloadWithoutPubKeyId); - }).to.throw( - 'Invalid Argument: expect pubKeyId to be a Buffer but got undefined' - ); - expect(function () { - SubTxRegisterPayload.fromJSON(payloadWithoutVersion); - }).to.throw( - 'Invalid Argument for version, expected number but got undefined' - ); - }); - it('Should throw an error if the data is incorrect', function () { - var payloadWithIncorrectUsername = { - version: 10, - userName: 10, - pubKeyId: pubKeyId, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE), - }; - var payloadWithIncorrectPubKeyId = { - version: 10, - userName: 'test', - pubKeyId: 'pubKeyId', - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE), - }; - var payloadWithIncorrectPubKeyIdSize = { - version: 10, - userName: 'test', - pubKeyId: BufferUtil.emptyBuffer(46), - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE), - }; - var payloadWithIncorrectVersion = { - version: '10', - userName: 'test', - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE), - pubKeyId: pubKeyId, - }; - var payloadWithIncorrectSignature = { - version: 10, - userName: 'test', - payloadSig: 'signature', - pubKeyId: pubKeyId, - }; - var payloadWithIncorrectSignatureSize = { - version: 10, - userName: 'test', - payloadSig: BufferUtil.emptyBuffer(28).toString('hex'), - pubKeyId: pubKeyId, - }; - expect(function () { - SubTxRegisterPayload.fromJSON(payloadWithIncorrectUsername); - }).to.throw( - 'Invalid Argument for userName, expected string but got number' - ); - expect(function () { - SubTxRegisterPayload.fromJSON(payloadWithIncorrectPubKeyId); - }).to.throw( - 'Invalid Argument: expect pubKeyId to be a Buffer but got string' - ); - expect(function () { - SubTxRegisterPayload.fromJSON(payloadWithIncorrectPubKeyIdSize); - }).to.throw('Invalid Argument: Invalid pubKeyId size'); - expect(function () { - SubTxRegisterPayload.fromJSON(payloadWithIncorrectVersion); - }).to.throw( - 'Invalid Argument for version, expected number but got string' - ); - expect(function () { - SubTxRegisterPayload.fromJSON(payloadWithIncorrectSignature); - }).to.throw( - 'Invalid Argument: expect payloadSig to be a hex string but got string' - ); - expect(function () { - SubTxRegisterPayload.fromJSON(payloadWithIncorrectSignatureSize); - }).to.throw('Invalid Argument: Invalid payloadSig size'); - }); - }); - describe('#setUserName', function () { - it('Should set username and return instance back', function () { - var payload = new SubTxRegisterPayload().setUserName('test'); - - expect(payload).to.be.an.instanceOf(SubTxRegisterPayload); - expect(payload.userName).to.be.equal('test'); - }); - }); - describe('#setPubKeyId', function () { - it('Should set pubKeyId and return instance back', function () { - var payload = new SubTxRegisterPayload().setPubKeyId(pubKeyId); - - expect(payload).to.be.an.instanceOf(SubTxRegisterPayload); - expect(payload.pubKeyId).to.be.deep.equal(pubKeyId); - }); - }); - describe('#setPubKeyIdFromPrivateKey', function () { - it('Should set pubKeyId and return instance back if private key is a string', function () { - var payload = new SubTxRegisterPayload().setPubKeyIdFromPrivateKey( - privateKey - ); - - expect(payload).to.be.an.instanceOf(SubTxRegisterPayload); - expect(payload.pubKeyId).to.be.deep.equal(pubKeyId); - }); - it('Should set pubKeyId and return instance back if private key is an instance of PrivateKey', function () { - var payload = new SubTxRegisterPayload().setPubKeyIdFromPrivateKey( - new PrivateKey(privateKey) - ); - - expect(payload).to.be.an.instanceOf(SubTxRegisterPayload); - expect(payload.pubKeyId).to.be.deep.equal(pubKeyId); - }); - }); - describe('#sign', function () { - it('Should sign payload and return instance back if a private key is a string', function () { - var payload = new SubTxRegisterPayload() - .setUserName('test') - .setPubKeyId(pubKeyId) - .sign(privateKey); - expect(payload.payloadSig).to.be.a.string; - expect(isHexString(payload.payloadSig)).to.be.true; - expect(payload.payloadSig.length).to.be.equal(CORRECT_SIGNATURE_SIZE * 2); - }); - it('Should sign payload and return instance back if a private key is an instance of PrivateKey', function () { - var payload = new SubTxRegisterPayload() - .setUserName('test') - .setPubKeyId(pubKeyId) - .sign(new PrivateKey(privateKey)); - expect(payload.payloadSig).to.be.a.string; - expect(isHexString(payload.payloadSig)).to.be.true; - expect(payload.payloadSig.length).to.be.equal(CORRECT_SIGNATURE_SIZE * 2); - }); - it('Should throw when trying to sign incomplete data', function () { - var payload = new SubTxRegisterPayload().setUserName('test'); - - expect(function () { - payload.sign(privateKey); - }).to.throw( - 'Invalid Argument: expect pubKeyId to be a Buffer but got undefined' - ); - }); - }); - describe('#verifyHashSignature', function () { - it('Should verify signature if pubKeyId is a Buffer', function () { - var payload = new SubTxRegisterPayload() - .setUserName('test') - .setPubKeyId(pubKeyId) - .sign(privateKey); - - expect(payload.verifySignature(pubKeyId)).to.be.true; - }); - it('Should verify signature if pubKeyId is a hex string', function () { - var payload = new SubTxRegisterPayload() - .setUserName('test') - .setPubKeyId(pubKeyId) - .sign(privateKey); - - expect(payload.verifySignature(pubKeyId.toString('hex'))).to.be.true; - }); - it("Should return false if pubKeyId doesn't match the signature", function () { - var payload = new SubTxRegisterPayload() - .setUserName('test') - .setPubKeyId(pubKeyId) - .sign(privateKey); - - expect(payload.verifySignature(new PrivateKey().toPublicKey()._getID())) - .to.be.false; - }); - }); - describe('#toJSON', function () { - it('Should return a JSON that contains same data as the payload instance', function () { - var payload = new SubTxRegisterPayload() - .setUserName('test') - .setPubKeyId(pubKeyId) - .sign(privateKey); - - var payloadJSON = payload.toJSON(); - expect(payload.userName).to.be.equal(payloadJSON.userName); - expect(payload.pubKeyId).to.be.deep.equal(pubKeyId); - expect(payload.payloadSig).to.be.deep.equal(payload.payloadSig); - }); - it('Should throw if the data is incomplete', function () { - var payload = new SubTxRegisterPayload().setUserName('test'); - - expect(function () { - payload.toJSON(); - }).to.throw( - 'Invalid Argument: expect pubKeyId to be a Buffer but got undefined' - ); - }); - it('Should throw if the data is invalid', function () { - var payload = new SubTxRegisterPayload() - .setUserName(4) - .setPubKeyId(pubKeyId); - - expect(function () { - payload.toJSON(); - }).to.throw( - 'Invalid Argument for userName, expected string but got number' - ); - }); - it('Should skip signature if such option is passed', function () { - var payload = new SubTxRegisterPayload() - .setUserName('test') - .setPubKeyId(pubKeyId) - .sign(privateKey); - - var payloadJSON = payload.toJSON({ skipSignature: true }); - expect(payloadJSON).not.to.have.property('payloadSig'); - }); - }); - describe('#toBuffer', function () { - it('Should return a Buffer that contains same data as the payload instance', function () { - var payload = new SubTxRegisterPayload() - .setUserName('test') - .setPubKeyId(pubKeyId) - .sign(privateKey); - - var payloadBuffer = payload.toBuffer(); - - var restoredPayload = SubTxRegisterPayload.fromBuffer(payloadBuffer); - expect(restoredPayload.version).to.be.equal(payload.version); - expect(restoredPayload.userName).to.be.equal(payload.userName); - expect(restoredPayload.pubKeyId).to.be.deep.equal(payload.pubKeyId); - expect(restoredPayload.payloadSig).to.be.deep.equal(payload.payloadSig); - }); - it('Should write zero byte instead of signature if skipSignature option passed', function () { - var payload = new SubTxRegisterPayload() - .setUserName('test') - .setPubKeyId(pubKeyId) - .sign(privateKey); - - var expectedLength = - payload.toBuffer().length - Payload.constants.COMPACT_SIGNATURE_SIZE; - - var payloadBuffer = payload.toBuffer({ skipSignature: true }); - - expect(payloadBuffer.length).to.be.equal(expectedLength); - }); - it('Should throw if the data is incomplete', function () { - var payload = new SubTxRegisterPayload().setUserName('test'); - - expect(function () { - payload.toBuffer(); - }).to.throw( - 'Invalid Argument: expect pubKeyId to be a Buffer but got undefined' - ); - }); - it('Should throw if the data is invalid', function () { - var payload = new SubTxRegisterPayload() - .setUserName(4) - .setPubKeyId(pubKeyId); - - expect(function () { - payload.toBuffer(); - }).to.throw( - 'Invalid Argument for userName, expected string but got number' - ); - }); - }); - describe('#getHash', function () { - it('Should return hash', function () { - var payload = new SubTxRegisterPayload() - .setUserName('test') - .setPubKeyId(pubKeyId) - .sign(privateKey); - - var hash = payload.getHash(); - expect(hash).to.be.an.instanceOf(Buffer); - expect(hash.length).to.be.equal(32); - }); - it('Should return hash without signature if option passed', function () { - var payload = new SubTxRegisterPayload() - .setUserName('test') - .setPubKeyId(pubKeyId) - .sign(privateKey); - - var hash = payload.getHash(); - var hashFromDataWithoutSignature = payload.getHash({ - skipSignature: true, - }); - expect(hashFromDataWithoutSignature).to.be.an.instanceOf(Buffer); - expect(hashFromDataWithoutSignature.length).to.be.equal(32); - expect(hashFromDataWithoutSignature).to.be.not.deep.equal(hash); - }); - it('Should throw if data is incomplete', function () { - var payload = new SubTxRegisterPayload().setUserName('test'); - - expect(function () { - payload.getHash(); - }).to.throw( - 'Invalid Argument: expect pubKeyId to be a Buffer but got undefined' - ); - }); - }); -}); diff --git a/test/transaction/payload/subtxresetkeypayload.js b/test/transaction/payload/subtxresetkeypayload.js deleted file mode 100644 index a1dececa9..000000000 --- a/test/transaction/payload/subtxresetkeypayload.js +++ /dev/null @@ -1,595 +0,0 @@ -/* eslint-disable */ -// TODO: Remove previous line and work through linting issues at next edit - -var expect = require('chai').expect; -var sinon = require('sinon'); -var DashcoreLib = require('../../../index'); -var SubTxResetKeyPayload = DashcoreLib.Transaction.Payload.SubTxResetKeyPayload; -var PrivateKey = DashcoreLib.PrivateKey; -var BufferUtil = DashcoreLib.util.buffer; -var isHexString = DashcoreLib.util.js.isHexaString; -var privateKey = 'cQSA77TsRYNEsYRmLoY7Y3gNF3Kb5qff4yUv3hWB7fm46YQ2njqN'; -var subTxHash = - '54b8f5e4e77853f136ced5d29e92afabf380bf37ac54b46755c2211774960ee1'; -var pubKeyId = new PrivateKey(privateKey).toPublicKey()._getID(); -var CORRECT_SIGNATURE_SIZE = - DashcoreLib.Transaction.Payload.constants.COMPACT_SIGNATURE_SIZE; -var payloadSig = - '96a4dba864e46b2a8283763351a74a53ebc0a7ce7611f62b5250b6592156b618d584c363bf04dc20ebd5f8ba8f073e0e4e78a89364e5c57a814eef6278fd51ab1f'; - -var validSubTxResetKeyPayloadJSON = { - version: 1, - regTxHash: subTxHash, - hashPrevSubTx: subTxHash, - creditFee: 1000, - //newPubKeySize: 20, - newPubKey: pubKeyId, -}; - -var validSubTxResetKeyPayloadJSONsigned = { - version: 1, - regTxHash: subTxHash, - hashPrevSubTx: subTxHash, - creditFee: 1000, - //newPubKeySize: 20, - newPubKey: pubKeyId, - payloadSigSize: 65, - payloadSig: payloadSig, -}; - -var validSubTxResetKeyPayloadHexString = - '0100e10e96741721c25567b454ac37bf80f3abaf929ed2d5ce36f15378e7e4f5b854e10e96741721c25567b454ac37bf80f3abaf929ed2d5ce36f15378e7e4f5b854e803000000000000eb9c2482ecc406f5cb6ad40f15bfc4eb203316a400'; -var validSubTxResetKeyPayloadBuffer = Buffer.from( - validSubTxResetKeyPayloadHexString, - 'hex' -); -var validSubTxResetKeyPayload = SubTxResetKeyPayload.fromBuffer( - validSubTxResetKeyPayloadBuffer -); - -var validSubTxResetKeyPayloadHexStringSigned = - '0100e10e96741721c25567b454ac37bf80f3abaf929ed2d5ce36f15378e7e4f5b854e10e96741721c25567b454ac37bf80f3abaf929ed2d5ce36f15378e7e4f5b854e803000000000000eb9c2482ecc406f5cb6ad40f15bfc4eb203316a4411fab51fd7862ef4e817ac5e56493a8784e0e3e078fbaf8d5eb20dc04bf63c384d518b6562159b650522bf61176cea7c0eb534aa751337683822a6be464a8dba496'; -var validSubTxResetKeyPayloadBufferSigned = Buffer.from( - validSubTxResetKeyPayloadHexStringSigned, - 'hex' -); -var validSubTxResetKeyPayloadSigned = SubTxResetKeyPayload.fromBuffer( - validSubTxResetKeyPayloadBufferSigned -); - -describe('SubTxResetKeyPayload', function () { - describe('constructor', function () { - it('Should create SubTxResetKeyPayload instance', function () { - var payload = new SubTxResetKeyPayload(); - expect(payload).to.have.property('version'); - }); - }); - - describe('.fromBuffer', function () { - beforeEach(function () { - sinon.spy(SubTxResetKeyPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxResetKeyPayload.prototype.validate.restore(); - }); - - it('Should return instance of SubTxResetKeyPayload and call #validate on it', function () { - var payload = SubTxResetKeyPayload.fromBuffer( - Buffer.from(validSubTxResetKeyPayloadHexString, 'hex') - ); - - expect(payload.version).to.be.equal(1); - expect(payload.regTxHash).to.be.equal(subTxHash); - expect(payload.hashPrevSubTx).to.be.equal(subTxHash); - expect(payload.creditFee).to.be.equal(1000); - //expect(payload.newPubKeySize).to.be.equal(20); - expect(BufferUtil.equals(payload.newPubKey, pubKeyId)).to.be.true; - }); - - it('Should throw in case if there is some unexpected information in raw payload', function () { - var payloadWithAdditionalZeros = Buffer.from( - validSubTxResetKeyPayloadHexString + '0000', - 'hex' - ); - - expect(function () { - SubTxResetKeyPayload.fromBuffer(payloadWithAdditionalZeros); - }).to.throw( - 'Failed to parse payload: raw payload is bigger than expected.' - ); - }); - - it('Should return instance of SubTxResetKeyPayload with parsed data', function () { - var payloadBuffer = new SubTxResetKeyPayload() - .setRegTxHash(subTxHash) - .setPrevSubTxHash(subTxHash) - .setCreditFee(1000) - .setNewPubKeyId(pubKeyId) - .toBuffer({ skipSignature: true }); - - expect(BufferUtil.isBuffer(payloadBuffer)).to.be.true; - - var parsedPayload = SubTxResetKeyPayload.fromBuffer(payloadBuffer); - expect(parsedPayload.regTxHash).to.be.equal(subTxHash); - expect(parsedPayload.hashPrevSubTx).to.be.equal(subTxHash); - expect(parsedPayload.creditFee).to.be.equal(1000); - expect(BufferUtil.equals(parsedPayload.newPubKey, pubKeyId)).to.be.true; - }); - - it('Should throw an error if data is incomplete', function () { - var payloadBuffer = new SubTxResetKeyPayload() - .setRegTxHash(subTxHash) - .setPrevSubTxHash(subTxHash) - .setCreditFee(1000) - .setNewPubKeyId(pubKeyId) - .toBuffer({ skipSignature: true }); - // 2 bytes is payload version, 32 is regTxHash size, 32 is preSubTxHash, 8 is varint size for creditFee of 1000 duffs - var payloadBufferWithoutPubKeyId = payloadBuffer.slice( - 0, - 2 + 32 + 32 + 8 - ); - - expect(function () { - SubTxResetKeyPayload.fromBuffer(payloadBufferWithoutPubKeyId); - }).to.throw(); - }); - }); - - describe('.fromBuffer signed', function () { - beforeEach(function () { - sinon.spy(SubTxResetKeyPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxResetKeyPayload.prototype.validate.restore(); - }); - - it('Should return instance of SubTxResetKeyPayload and call #validate on it', function () { - var payload = SubTxResetKeyPayload.fromBuffer( - Buffer.from(validSubTxResetKeyPayloadHexStringSigned, 'hex') - ); - - expect(payload.version).to.be.equal(1); - expect(payload.regTxHash).to.be.equal(subTxHash); - expect(payload.hashPrevSubTx).to.be.equal(subTxHash); - expect(payload.creditFee).to.be.equal(1000); - //expect(payload.newPubKeySize).to.be.equal(20); - expect(BufferUtil.equals(payload.newPubKey, pubKeyId)).to.be.true; - expect(payload.payloadSigSize).to.be.equal(65); - expect(payload.payloadSig).to.be.equal(payloadSig); - }); - - it('Should throw in case if there is some unexpected information in raw payload', function () { - var payloadWithAdditionalZeros = Buffer.from( - validSubTxResetKeyPayloadHexString + '0000', - 'hex' - ); - - expect(function () { - SubTxResetKeyPayload.fromBuffer(payloadWithAdditionalZeros); - }).to.throw( - 'Failed to parse payload: raw payload is bigger than expected.' - ); - }); - }); - - describe('.fromJSON', function () { - before(function () { - sinon.spy(SubTxResetKeyPayload.prototype, 'validate'); - }); - - it('Should return instance of SubTxResetKeyPayload and call #validate on it', function () { - var payload = SubTxResetKeyPayload.fromJSON( - validSubTxResetKeyPayloadJSON - ); - - expect(payload.version).to.be.equal(1); - expect(payload.regTxHash).to.be.equal(subTxHash); - expect(payload.hashPrevSubTx).to.be.equal(subTxHash); - expect(payload.creditFee).to.be.equal(1000); - //expect(payload.newPubKeySize).to.be.equal(20); - expect(BufferUtil.equals(payload.newPubKey, pubKeyId)).to.be.true; - }); - - after(function () { - SubTxResetKeyPayload.prototype.validate.restore(); - }); - - it('Should return instance of SubTxResetKeyPayload with correct parsed data', function () { - var payloadJSON = { - version: 10, - regTxHash: subTxHash, - hashPrevSubTx: subTxHash, - creditFee: 1000, - newPubKey: pubKeyId, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payload = SubTxResetKeyPayload.fromJSON(payloadJSON); - expect(payload.version).to.be.equal(10); - expect(payload.regTxHash).to.be.equal(payloadJSON.regTxHash); - expect(payload.hashPrevSubTx).to.be.equal(payloadJSON.hashPrevSubTx); - expect(payload.creditFee).to.be.equal(payloadJSON.creditFee); - expect(BufferUtil.equals(payload.newPubKey, payloadJSON.newPubKey)).to.be - .true; - expect(BufferUtil.equals(payload.payloadSig, payloadJSON.payloadSig)).to - .be.true; - }); - it('Should throw an error if the data is incomplete', function () { - var payloadWithoutRegTxHash = { - version: 10, - hashPrevSubTx: subTxHash, - creditFee: 1000, - newPubKey: pubKeyId, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payloadWithoutNewPubKey = { - version: 10, - regTxHash: subTxHash, - hashPrevSubTx: subTxHash, - creditFee: 1000, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payloadWithoutVersion = { - regTxHash: subTxHash, - hashPrevSubTx: subTxHash, - creditFee: 1000, - newPubKey: pubKeyId, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - expect(function () { - SubTxResetKeyPayload.fromJSON(payloadWithoutRegTxHash); - }).to.throw( - 'Invalid Argument: Expect regTxHash to be a hex string representing sha256 hash' - ); - expect(function () { - SubTxResetKeyPayload.fromJSON(payloadWithoutNewPubKey); - }).to.throw( - 'Invalid Argument: expect newPubKey to be a Buffer but got undefined' - ); - expect(function () { - SubTxResetKeyPayload.fromJSON(payloadWithoutVersion); - }).to.throw( - 'Invalid Argument for version, expected number but got undefined' - ); - }); - it('Should throw an error if the data is incorrect', function () { - var payloadWithIncorrectRegTxHash = { - version: 10, - regTxHash: 10, - hashPrevSubTx: subTxHash, - creditFee: 1000, - newPubKey: pubKeyId, - payloadSigSize: CORRECT_SIGNATURE_SIZE, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payloadWithIncorrectPubKeyId = { - version: 10, - regTxHash: subTxHash, - hashPrevSubTx: subTxHash, - creditFee: 1000, - newPubKey: 'pubKeyId', - payloadSigSize: CORRECT_SIGNATURE_SIZE, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payloadWithIncorrectVersion = { - version: '10', - regTxHash: subTxHash, - hashPrevSubTx: subTxHash, - creditFee: 1000, - newPubKey: pubKeyId, - payloadSigSize: CORRECT_SIGNATURE_SIZE, - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payloadWithIncorrectSignature = { - version: 10, - regTxHash: subTxHash, - hashPrevSubTx: subTxHash, - creditFee: 1000, - newPubKey: pubKeyId, - payloadSigSize: CORRECT_SIGNATURE_SIZE, - payloadSig: 'signature', - }; - var payloadWithIncorrectSignatureSize = { - version: 10, - regTxHash: subTxHash, - hashPrevSubTx: subTxHash, - creditFee: 1000, - newPubKey: pubKeyId, - payloadSig: BufferUtil.emptyBuffer(22).toString('hex'), - }; - expect(function () { - SubTxResetKeyPayload.fromJSON(payloadWithIncorrectRegTxHash); - }).to.throw( - 'Invalid Argument: Expect regTxHash to be a hex string representing sha256 hash' - ); - expect(function () { - SubTxResetKeyPayload.fromJSON(payloadWithIncorrectPubKeyId); - }).to.throw( - 'Invalid Argument: expect newPubKey to be a Buffer but got string' - ); - expect(function () { - SubTxResetKeyPayload.fromJSON(payloadWithIncorrectVersion); - }).to.throw( - 'Invalid Argument for version, expected number but got string' - ); - expect(function () { - SubTxResetKeyPayload.fromJSON(payloadWithIncorrectSignature); - }).to.throw( - 'Invalid Argument: expect payloadSig to be a hex string but got string' - ); - expect(function () { - SubTxResetKeyPayload.fromJSON(payloadWithIncorrectSignatureSize); - }).to.throw('Invalid Argument: Invalid payloadSigSize size'); - }); - }); - - describe('.fromJSON signed', function () { - before(function () { - sinon.spy(SubTxResetKeyPayload.prototype, 'validate'); - }); - - it('Should return instance of SubTxResetKeyPayload and call #validate on it', function () { - var payload = SubTxResetKeyPayload.fromJSON( - validSubTxResetKeyPayloadJSONsigned - ); - - expect(payload.version).to.be.equal(1); - expect(payload.regTxHash).to.be.equal(subTxHash); - expect(payload.hashPrevSubTx).to.be.equal(subTxHash); - expect(payload.creditFee).to.be.equal(1000); - //expect(payload.newPubKeySize).to.be.equal(20); - expect(BufferUtil.equals(payload.newPubKey, pubKeyId)).to.be.true; - expect(payload.payloadSigSize).to.be.equal(65); - expect(payload.payloadSig).to.be.equal(payloadSig); - }); - - after(function () { - SubTxResetKeyPayload.prototype.validate.restore(); - }); - }); - describe('#setRegTxHash', function () { - it('Should set regTxHash and return instance back', function () { - var payload = new SubTxResetKeyPayload().setRegTxHash(subTxHash); - - expect(payload).to.be.an.instanceOf(SubTxResetKeyPayload); - expect(payload.regTxHash).to.be.equal(subTxHash); - }); - }); - describe('#setPrevSubTxHash', function () { - it('Should set regTxHash and return instance back', function () { - var payload = new SubTxResetKeyPayload().setPrevSubTxHash(subTxHash); - - expect(payload).to.be.an.instanceOf(SubTxResetKeyPayload); - expect(payload.hashPrevSubTx).to.be.equal(subTxHash); - }); - }); - describe('#setCreditFee', function () { - it('Should set creditFee and return instance back', function () { - var payload = new SubTxResetKeyPayload().setCreditFee(1000); - - expect(payload).to.be.an.instanceOf(SubTxResetKeyPayload); - expect(payload.creditFee).to.be.deep.equal(1000); - }); - }); - describe('#setNewPubKey', function () { - it('Should set newPubKey and return instance back', function () { - var payload = new SubTxResetKeyPayload().setNewPubKeyId(pubKeyId); - - expect(payload).to.be.an.instanceOf(SubTxResetKeyPayload); - expect(payload.newPubKey).to.be.deep.equal(pubKeyId); - }); - }); - describe('#sign', function () { - it('Should sign payload and return instance back if a private key is a string', function () { - var payload = new SubTxResetKeyPayload() - .setRegTxHash(subTxHash) - .setPrevSubTxHash(subTxHash) - .setCreditFee(1000) - .setNewPubKeyId(pubKeyId) - .sign(privateKey); - expect(payload.payloadSig).to.be.a.string; - expect(isHexString(payload.payloadSig)).to.be.true; - expect(payload.payloadSig.length).to.be.equal(CORRECT_SIGNATURE_SIZE * 2); - }); - it('Should sign payload and return instance back if a private key is an instance of PrivateKey', function () { - var payload = new SubTxResetKeyPayload() - .setRegTxHash(subTxHash) - .setPrevSubTxHash(subTxHash) - .setCreditFee(1000) - .setNewPubKeyId(pubKeyId) - .sign(new PrivateKey(privateKey)); - expect(payload.payloadSig).to.be.a.string; - expect(isHexString(payload.payloadSig)).to.be.true; - expect(payload.payloadSig.length).to.be.equal(CORRECT_SIGNATURE_SIZE * 2); - }); - it('Should throw when trying to sign incomplete data', function () { - var payload = new SubTxResetKeyPayload().setRegTxHash(subTxHash); - - expect(function () { - payload.sign(privateKey); - }).to.throw( - 'Invalid Argument for creditFee, expected number but got undefined' - ); - }); - }); - describe('#verifyHashSignature', function () { - it('Should verify signature if pubKeyId is a Buffer', function () { - var payload = new SubTxResetKeyPayload() - .setRegTxHash(subTxHash) - .setPrevSubTxHash(subTxHash) - .setCreditFee(1000) - .setNewPubKeyId(pubKeyId) - .sign(privateKey); - - expect( - payload.verifySignature( - SubTxResetKeyPayload.convertPrivateKeyToPubKeyId(privateKey) - ) - ).to.be.true; - }); - it('Should verify signature if pubKeyId is a hex string', function () { - var payload = new SubTxResetKeyPayload() - .setRegTxHash(subTxHash) - .setPrevSubTxHash(subTxHash) - .setCreditFee(1000) - .setNewPubKeyId(pubKeyId) - .sign(privateKey); - - expect(payload.verifySignature(pubKeyId.toString('hex'))).to.be.true; - }); - it("Should return false if pubKeyId doesn't match the signature", function () { - var payload = new SubTxResetKeyPayload() - .setRegTxHash(subTxHash) - .setPrevSubTxHash(subTxHash) - .setCreditFee(1000) - .setNewPubKeyId(pubKeyId) - .sign(privateKey); - - expect(payload.verifySignature(new PrivateKey().toPublicKey()._getID())) - .to.be.false; - }); - }); - describe('#toJSON', function () { - beforeEach(function () { - sinon.spy(SubTxResetKeyPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxResetKeyPayload.prototype.validate.restore(); - }); - - it('Should be able to serialize payload JSON', function () { - var payload = validSubTxResetKeyPayload; - - var payloadJSON = payload.toJSON({ skipSignature: true }); - - expect(payloadJSON.version).to.be.equal(1); - expect(payloadJSON.regTxHash).to.be.equal(subTxHash); - expect(payloadJSON.hashPrevSubTx).to.be.equal(subTxHash); - expect(payloadJSON.creditFee).to.be.equal(1000); - //expect(payloadJSON.newPubKeySize).to.be.equal(20); - expect(BufferUtil.equals(payloadJSON.newPubKey, pubKeyId)).to.be.true; - }); - it('Should call #validate', function () { - var payload = SubTxResetKeyPayload.fromJSON( - validSubTxResetKeyPayloadJSON - ); - SubTxResetKeyPayload.prototype.validate.resetHistory(); - payload.toJSON({ skipSignature: true }); - expect(payload.validate.callCount).to.be.equal(1); - }); - }); - - describe('#toJSON signed', function () { - beforeEach(function () { - sinon.spy(SubTxResetKeyPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxResetKeyPayload.prototype.validate.restore(); - }); - - it('Should be able to serialize payload JSON', function () { - var payload = validSubTxResetKeyPayloadSigned; - var payloadJSON = payload.toJSON(); - expect(payloadJSON.version).to.be.equal(1); - expect(payloadJSON.regTxHash).to.be.equal(subTxHash); - expect(payloadJSON.hashPrevSubTx).to.be.equal(subTxHash); - expect(payloadJSON.creditFee).to.be.equal(1000); - //expect(payload.newPubKeySize).to.be.equal(20); - expect(BufferUtil.equals(payloadJSON.newPubKey, pubKeyId)).to.be.true; - expect(payloadJSON.payloadSigSize).to.be.equal(65); - expect(payloadJSON.payloadSig).to.be.equal(payloadSig); - }); - it('Should call #validate', function () { - var payload = SubTxResetKeyPayload.fromJSON( - validSubTxResetKeyPayloadJSONsigned - ); - SubTxResetKeyPayload.prototype.validate.resetHistory(); - payload.toJSON(); - expect(payload.validate.callCount).to.be.equal(1); - }); - }); - - describe('#toBuffer', function () { - beforeEach(function () { - sinon.spy(SubTxResetKeyPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxResetKeyPayload.prototype.validate.restore(); - }); - - it('Should be able to serialize payload to Buffer', function () { - var payload = validSubTxResetKeyPayload; - - var serializedPayload = payload.toBuffer({ skipSignature: true }); - var restoredPayload = SubTxResetKeyPayload.fromBuffer(serializedPayload); - - expect(restoredPayload.version).to.be.equal(1); - expect(restoredPayload.regTxHash).to.be.equal(subTxHash); - expect(restoredPayload.hashPrevSubTx).to.be.equal(subTxHash); - expect(restoredPayload.creditFee).to.be.equal(1000); - //expect(payload.newPubKeySize).to.be.equal(20); - expect(BufferUtil.equals(restoredPayload.newPubKey, pubKeyId)).to.be.true; - expect(restoredPayload.payloadSigSize).to.be.equal(0); - }); - it('Should call #validate', function () { - var payload = SubTxResetKeyPayload.fromJSON( - validSubTxResetKeyPayloadJSON - ); - SubTxResetKeyPayload.prototype.validate.resetHistory(); - payload.toBuffer({ skipSignature: true }); - expect(payload.validate.callCount).to.be.equal(1); - }); - }); - - describe('#toBuffer signed', function () { - beforeEach(function () { - sinon.spy(SubTxResetKeyPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxResetKeyPayload.prototype.validate.restore(); - }); - - it('Should be able to serialize payload to Buffer', function () { - var payload = validSubTxResetKeyPayloadSigned; - - var serializedPayload = payload.toBuffer(); - var restoredPayload = SubTxResetKeyPayload.fromBuffer(serializedPayload); - - expect(restoredPayload.version).to.be.equal(1); - expect(restoredPayload.regTxHash).to.be.equal(subTxHash); - expect(restoredPayload.hashPrevSubTx).to.be.equal(subTxHash); - expect(restoredPayload.creditFee).to.be.equal(1000); - //expect(payload.newPubKeySize).to.be.equal(20); - expect(BufferUtil.equals(restoredPayload.newPubKey, pubKeyId)).to.be.true; - expect(restoredPayload.payloadSigSize).to.be.equal(65); - expect(restoredPayload.payloadSig).to.be.equal(payloadSig); - }); - it('Should call #validate', function () { - var payload = SubTxResetKeyPayload.fromJSON( - validSubTxResetKeyPayloadJSONsigned - ); - SubTxResetKeyPayload.prototype.validate.resetHistory(); - payload.toBuffer(); - expect(payload.validate.callCount).to.be.equal(1); - }); - }); -}); diff --git a/test/transaction/payload/subtxtopuppayload.js b/test/transaction/payload/subtxtopuppayload.js deleted file mode 100644 index 6770316f5..000000000 --- a/test/transaction/payload/subtxtopuppayload.js +++ /dev/null @@ -1,132 +0,0 @@ -/* eslint-disable */ -// TODO: Remove previous line and work through linting issues at next edit - -var expect = require('chai').expect; -var sinon = require('sinon'); - -var DashcoreLib = require('../../../index'); -var SubTxTopupPayload = DashcoreLib.Transaction.Payload.SubTxTopupPayload; - -var validSubTxTopupPayloadJSON = { - version: 1, - regTxHash: '45fd882f0df723d90a01a56ee1e83f45bf2446fd45d03522f390aae5b7f12737', -}; -var validSubTxTopupPayloadHexString = - '01003727f1b7e5aa90f32235d045fd4624bf453fe8e16ea5010ad923f70d2f88fd45'; -var validSubTxTopupPayloadBuffer = Buffer.from( - validSubTxTopupPayloadHexString, - 'hex' -); -var validSubTxTopupPayload = SubTxTopupPayload.fromBuffer( - validSubTxTopupPayloadBuffer -); - -describe('SubTxTopupPayload', function () { - describe('.fromBuffer', function () { - beforeEach(function () { - sinon.spy(SubTxTopupPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxTopupPayload.prototype.validate.restore(); - }); - - it('Should return instance of SubTxTopupPayload and call #validate on it', function () { - var payload = SubTxTopupPayload.fromBuffer( - Buffer.from(validSubTxTopupPayloadHexString, 'hex') - ); - - expect(payload.version).to.be.equal(1); - expect(payload.regTxHash).to.be.equal( - '45fd882f0df723d90a01a56ee1e83f45bf2446fd45d03522f390aae5b7f12737' - ); - }); - - it('Should throw in case if there is some unexpected information in raw payload', function () { - var payloadWithAdditionalZeros = Buffer.from( - validSubTxTopupPayloadHexString + '0000', - 'hex' - ); - - expect(function () { - SubTxTopupPayload.fromBuffer(payloadWithAdditionalZeros); - }).to.throw( - 'Failed to parse payload: raw payload is bigger than expected.' - ); - }); - }); - - describe('.fromJSON', function () { - before(function () { - sinon.spy(SubTxTopupPayload.prototype, 'validate'); - }); - - it('Should return instance of SubTxTopupPayload and call #validate on it', function () { - var payload = SubTxTopupPayload.fromJSON(validSubTxTopupPayloadJSON); - - expect(payload.version).to.be.equal(1); - expect(payload.regTxHash).to.be.equal( - '45fd882f0df723d90a01a56ee1e83f45bf2446fd45d03522f390aae5b7f12737' - ); - }); - - after(function () { - SubTxTopupPayload.prototype.validate.restore(); - }); - }); - - describe('#toJSON', function () { - beforeEach(function () { - sinon.spy(SubTxTopupPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxTopupPayload.prototype.validate.restore(); - }); - - it('Should be able to serialize payload JSON', function () { - var payload = validSubTxTopupPayload.copy(); - - var payloadJSON = payload.toJSON(); - - expect(payloadJSON.version).to.be.equal(1); - expect(payloadJSON.regTxHash).to.be.equal( - '45fd882f0df723d90a01a56ee1e83f45bf2446fd45d03522f390aae5b7f12737' - ); - }); - it('Should call #validate', function () { - var payload = SubTxTopupPayload.fromJSON(validSubTxTopupPayloadJSON); - SubTxTopupPayload.prototype.validate.resetHistory(); - payload.toJSON(); - expect(payload.validate.callCount).to.be.equal(1); - }); - }); - - describe('#toBuffer', function () { - beforeEach(function () { - sinon.spy(SubTxTopupPayload.prototype, 'validate'); - }); - - afterEach(function () { - SubTxTopupPayload.prototype.validate.restore(); - }); - - it('Should be able to serialize payload to Buffer', function () { - var payload = validSubTxTopupPayload.copy(); - - var serializedPayload = payload.toBuffer(); - var restoredPayload = SubTxTopupPayload.fromBuffer(serializedPayload); - - expect(restoredPayload.version).to.be.equal(1); - expect(restoredPayload.regTxHash).to.be.equal( - '45fd882f0df723d90a01a56ee1e83f45bf2446fd45d03522f390aae5b7f12737' - ); - }); - it('Should call #validate', function () { - var payload = SubTxTopupPayload.fromJSON(validSubTxTopupPayloadJSON); - SubTxTopupPayload.prototype.validate.resetHistory(); - payload.toBuffer(); - expect(payload.validate.callCount).to.be.equal(1); - }); - }); -}); diff --git a/test/transaction/payload/subtxtransitionpayload.js b/test/transaction/payload/subtxtransitionpayload.js deleted file mode 100644 index 91415723d..000000000 --- a/test/transaction/payload/subtxtransitionpayload.js +++ /dev/null @@ -1,363 +0,0 @@ -/* eslint-disable */ -// TODO: Remove previous line and work through linting issues at next edit - -var expect = require('chai').expect; -var sinon = require('sinon'); - -var DashcoreLib = require('../../../index'); - -var PrivateKey = DashcoreLib.PrivateKey; -var BufferUtil = DashcoreLib.util.buffer; -var Payload = DashcoreLib.Transaction.Payload; -var SubTxTransitionPayload = Payload.SubTxTransitionPayload; -var HashUtil = DashcoreLib.util.hashUtil; - -var CORRECT_SIGNATURE_SIZE = Payload.constants.COMPACT_SIGNATURE_SIZE; -var privateKey = 'cSBnVM4xvxarwGQuAfQFwqDg9k5tErHUHzgWsEfD4zdwUasvqRVY'; -var pubKeyId = new PrivateKey(privateKey).toPublicKey()._getID(); -var validPayloadJSONFixture = { - version: 10, - creditFee: 100, - hashPrevSubTx: HashUtil.getRandomHashHexString(), - regTxId: HashUtil.getRandomHashHexString(), - hashSTPacket: HashUtil.getRandomHashHexString(), -}; - -var validPayloadFixture = SubTxTransitionPayload.fromJSON( - validPayloadJSONFixture -); - -describe('SubTxTransitionPayload', function () { - describe('constructor', function () { - it('Should create SubTxTransitionPayload instance', function () { - var payload = new SubTxTransitionPayload(); - expect(payload).to.have.property('version'); - }); - }); - - describe('#setRegTxId', function () { - it('Should set regTxId and return instance back', function () { - var regTxId = HashUtil.getRandomHashHexString(); - - var payload = new SubTxTransitionPayload().setRegTxId(regTxId); - - expect(payload).to.be.an.instanceOf(SubTxTransitionPayload); - expect(payload.regTxId).to.be.deep.equal(regTxId); - }); - }); - - describe('#setHashPrevSubTx', function () { - it('Should set hashPrevSubTx and return instance back', function () { - var hashPrevSubTx = HashUtil.getRandomHashHexString(); - - var payload = new SubTxTransitionPayload().setHashPrevSubTx( - hashPrevSubTx - ); - - expect(payload).to.be.an.instanceOf(SubTxTransitionPayload); - expect(payload.hashPrevSubTx).to.be.deep.equal(hashPrevSubTx); - }); - }); - - describe('#setCreditFee', function () { - it('Should set creditFee and return instance back', function () { - var creditFee = 10; - - var payload = new SubTxTransitionPayload().setCreditFee(creditFee); - - expect(payload).to.be.an.instanceOf(SubTxTransitionPayload); - expect(payload.creditFee).to.be.equal(creditFee); - }); - }); - - describe('#hashSTPacket', function () { - it('Should set hashSTPacket and return instance back', function () { - var hashSTPacket = HashUtil.getRandomHashHexString(); - - var payload = new SubTxTransitionPayload().setHashSTPacket(hashSTPacket); - - expect(payload).to.be.an.instanceOf(SubTxTransitionPayload); - expect(payload.hashSTPacket).to.be.deep.equal(hashSTPacket); - }); - }); - - describe('fromBuffer', function () { - it('Should return instance of SubTxTransitionPayload with parsed data', function () { - var hashPrevSubTx = HashUtil.getRandomHashHexString(); - var regTxId = HashUtil.getRandomHashHexString(); - var hashSTPacket = HashUtil.getRandomHashHexString(); - - var payload = new SubTxTransitionPayload() - .setHashPrevSubTx(hashPrevSubTx) - .setCreditFee(10) - .setRegTxId(regTxId) - .setHashSTPacket(hashSTPacket); - - var payloadBuffer = payload.toBuffer(); - var stringBuf = payloadBuffer.toString('hex'); - - expect(BufferUtil.isBuffer(payloadBuffer)).to.be.true; - - var parsedPayload = SubTxTransitionPayload.fromBuffer(payloadBuffer); - expect(parsedPayload.hashPrevSubTx).to.be.deep.equal(hashPrevSubTx); - expect(parsedPayload.regTxId).to.be.deep.equal(regTxId); - expect(parsedPayload.hashSTPacket).to.be.deep.equal(hashSTPacket); - expect(parsedPayload.creditFee).to.be.equal(10); - expect(parsedPayload.version).to.be.equal(payload.version); - }); - it('Should throw an error if data is incomplete', function () { - var hashPrevSubTx = HashUtil.getRandomHashHexString(); - var regTxId = HashUtil.getRandomHashHexString(); - var hashSTPacket = HashUtil.getRandomHashHexString(); - - var payload = new SubTxTransitionPayload() - .setHashPrevSubTx(hashPrevSubTx) - .setCreditFee(10) - .setRegTxId(regTxId) - .setHashSTPacket(hashSTPacket); - - var payloadBuffer = payload.toBuffer(); - payloadBuffer = payloadBuffer.slice(0, payloadBuffer.length - 32); - - expect(BufferUtil.isBuffer(payloadBuffer)).to.be.true; - - expect(function () { - SubTxTransitionPayload.fromBuffer(payloadBuffer); - }).to.throw(); - }); - }); - describe('fromJSON', function () { - it('Should return instance of SubTxTransitionPayload with correct parsed data', function () { - var payloadJSON = { - version: 10, - creditFee: 100, - hashPrevSubTx: HashUtil.getRandomHashHexString(), - regTxId: HashUtil.getRandomHashHexString(), - hashSTPacket: HashUtil.getRandomHashHexString(), - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payload = SubTxTransitionPayload.fromJSON(payloadJSON); - expect(payload.version).to.be.equal(10); - expect(payload.creditFee).to.be.equal(100); - expect(payload.hashPrevSubTx).to.be.deep.equal(payloadJSON.hashPrevSubTx); - expect(payload.hashSTPacket).to.be.deep.equal(payloadJSON.hashSTPacket); - expect(payload.regTxId).to.be.deep.equal(payloadJSON.regTxId); - expect(payload.creditFee).to.be.deep.equal(payloadJSON.creditFee); - }); - it('Should throw an error if the data is incomplete', function () { - var payloadWithoutHashPrevSubTx = { - version: 10, - creditFee: 100, - regTxId: HashUtil.getRandomHashHexString(), - hashSTPacket: HashUtil.getRandomHashHexString(), - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payloadWithoutRegTxId = { - version: 10, - creditFee: 100, - hashPrevSubTx: HashUtil.getRandomHashHexString(), - hashSTPacket: HashUtil.getRandomHashHexString(), - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payloadWithoutHashSTPacket = { - version: 10, - creditFee: 100, - hashPrevSubTx: HashUtil.getRandomHashHexString(), - regTxId: HashUtil.getRandomHashHexString(), - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - var payloadWithoutCreditFee = { - version: 10, - hashPrevSubTx: HashUtil.getRandomHashHexString(), - hashSTPacket: HashUtil.getRandomHashHexString(), - regTxId: HashUtil.getRandomHashHexString(), - payloadSig: BufferUtil.emptyBuffer(CORRECT_SIGNATURE_SIZE).toString( - 'hex' - ), - }; - expect(function () { - SubTxTransitionPayload.fromJSON(payloadWithoutHashPrevSubTx); - }).to.throw( - 'Invalid Argument: expect hashPrevSubTx to be a hex string but got undefined' - ); - expect(function () { - SubTxTransitionPayload.fromJSON(payloadWithoutRegTxId); - }).to.throw( - 'Invalid Argument: expect regTxId to be a hex string but got undefined' - ); - expect(function () { - SubTxTransitionPayload.fromJSON(payloadWithoutHashSTPacket); - }).to.throw( - 'Invalid Argument: expect hashSTPacket to be a hex string but got undefined' - ); - expect(function () { - SubTxTransitionPayload.fromJSON(payloadWithoutCreditFee); - }).to.throw( - 'Invalid Argument for creditFee, expected number but got undefined' - ); - }); - it('Should throw an error if the data is incorrect', function () { - var invalidVersions = [-1, '1', 1.5, []]; - var payloadsWithInvalidVersions = invalidVersions.map(function (version) { - var payload = validPayloadFixture.copy().toJSON(); - payload.version = version; - return payload; - }); - payloadsWithInvalidVersions.forEach(function (payloadWithInvalidVersion) { - expect(function () { - SubTxTransitionPayload.fromJSON(payloadWithInvalidVersion); - }).to.throw('Invalid Argument'); - }); - var payloadWithIncorrectRegTxIdSize = validPayloadFixture - .copy() - .setRegTxId('123'); - var payloadWithIncorrectHashSTPacketSize = validPayloadFixture - .copy() - .setHashSTPacket('123'); - var payloadWithIncorrectCreditFee = validPayloadFixture - .copy() - .setCreditFee(-10); - var payloadWithIncorrectHashPrevSubTx = validPayloadFixture - .copy() - .setHashPrevSubTx('123'); - var payloadWithIncorrectSignature = validPayloadFixture.copy(); - payloadWithIncorrectSignature.payloadSig = 'signature'; - var payloadWithIncorrectSignatureSize = validPayloadFixture.copy(); - payloadWithIncorrectSignatureSize.payloadSig = - BufferUtil.emptyBuffer(10).toString('hex'); - expect(function () { - SubTxTransitionPayload.fromJSON(payloadWithIncorrectRegTxIdSize); - }).to.throw('Invalid Argument: Invalid regTxId size'); - expect(function () { - SubTxTransitionPayload.fromJSON(payloadWithIncorrectHashSTPacketSize); - }).to.throw('Invalid Argument: Invalid hashSTPacket size'); - expect(function () { - SubTxTransitionPayload.fromJSON(payloadWithIncorrectCreditFee); - }).to.throw( - 'Invalid Argument: Expect creditFee to be an unsigned integer' - ); - expect(function () { - SubTxTransitionPayload.fromJSON(payloadWithIncorrectHashPrevSubTx); - }).to.throw('Invalid Argument: Invalid hashPrevSubTx size'); - expect(function () { - SubTxTransitionPayload.fromJSON(payloadWithIncorrectSignature); - }).to.throw('Invalid Argument: expect payloadSig to be a hex string'); - expect(function () { - SubTxTransitionPayload.fromJSON(payloadWithIncorrectSignatureSize); - }).to.throw('Invalid Argument: Invalid payloadSig size'); - }); - }); - describe('#sign', function () { - it('Should sign payload and return instance back if a private key is a string', function () { - var payload = validPayloadFixture.copy().sign(privateKey); - expect(payload.payloadSig).to.be.a.string; - expect(payload.payloadSig.length).to.be.equal(CORRECT_SIGNATURE_SIZE * 2); - }); - it('Should sign payload and return instance back if a private key is an instance of PrivateKey', function () { - var payload = validPayloadFixture.copy().sign(new PrivateKey(privateKey)); - expect(payload.payloadSig).to.be.a.string; - expect(payload.payloadSig.length).to.be.equal(CORRECT_SIGNATURE_SIZE * 2); - }); - it('Should throw when trying to sign incomplete data', function () { - var payload = validPayloadFixture.copy().setRegTxId('ffa2'); - - expect(function () { - payload.sign(privateKey); - }).to.throw('Invalid Argument: Invalid regTxId size'); - }); - }); - describe('#verifyHashSignature', function () { - it('Should verify signature if pubKeyId is a Buffer', function () { - var payload = validPayloadFixture.copy().sign(privateKey); - expect(payload.verifySignature(pubKeyId)).to.be.true; - }); - it('Should verify signature if pubKeyId is a hex string', function () { - var payload = validPayloadFixture.copy().sign(privateKey); - expect(payload.verifySignature(pubKeyId.toString('hex'))).to.be.true; - }); - it("Should return false if pubKeyId doesn't match the signature", function () { - var payload = validPayloadFixture.copy().sign(privateKey); - expect(payload.verifySignature(new PrivateKey().toPublicKey()._getID())) - .to.be.false; - }); - }); - describe('#toJSON', function () { - it('Should return a JSON that contains same data as the payload instance', function () { - var payload = validPayloadFixture.copy().sign(privateKey); - var payloadJSON = payload.toJSON(); - expect(payloadJSON.version).to.be.equal(payload.version); - expect(payloadJSON.hashPrevSubTx).to.be.deep.equal(payload.hashPrevSubTx); - expect(payloadJSON.hashSTPacket).to.be.deep.equal(payload.hashSTPacket); - expect(payloadJSON.regTxId).to.be.deep.equal(payload.regTxId); - expect(payloadJSON.creditFee).to.be.equal(payload.creditFee); - expect(payloadJSON.payloadSig).to.be.deep.equal(payload.payloadSig); - }); - it('Should validate data before serialization', function () { - var payload = validPayloadFixture.copy(); - var spy = sinon.spy(SubTxTransitionPayload, 'validatePayloadJSON'); - payload.toJSON(); - expect(spy.calledOnce).to.be.true; - spy.restore(); - }); - it('Should skip signature if such option is passed', function () { - var payload = validPayloadFixture.copy(); - - var payloadJSON = payload.toJSON({ skipSignature: true }); - expect(payloadJSON).not.to.have.property('payloadSig'); - }); - }); - describe('#toBuffer', function () { - it('Should return a Buffer that contains same data as the payload instance', function () { - var payload = validPayloadFixture.copy(); - var payloadBuffer = payload.toBuffer(); - - var restoredPayload = SubTxTransitionPayload.fromBuffer(payloadBuffer); - expect(restoredPayload).to.be.deep.equal(payload); - }); - it('Should validate data before serialization', function () { - var payload = validPayloadFixture.copy(); - var spy = sinon.spy(SubTxTransitionPayload, 'validatePayloadJSON'); - expect(spy.callCount).to.be.equal(0); - payload.toBuffer(); - expect(spy.callCount).to.be.equal(1); - spy.restore(); - }); - }); - describe('#getHash', function () { - it('Should return deterministic hash', function () { - var payload = validPayloadFixture.copy(); - - var hash = payload.getHash(); - expect(hash).to.be.an.instanceOf(Buffer); - expect(hash.length).to.be.equal(32); - var hash2 = payload.getHash(); - expect(hash).to.be.deep.equal(hash2); - }); - it('Should return hash without signature if option passed', function () { - var payload = validPayloadFixture.copy().sign(privateKey); - - var hash = payload.getHash(); - var hashFromDataWithoutSignature = payload.getHash({ - skipSignature: true, - }); - expect(hashFromDataWithoutSignature).to.be.an.instanceOf(Buffer); - expect(hashFromDataWithoutSignature.length).to.be.equal(32); - expect(hashFromDataWithoutSignature).to.be.not.deep.equal(hash); - }); - it('Should validate data', function () { - var payload = validPayloadFixture.copy(); - var spy = sinon.spy(SubTxTransitionPayload, 'validatePayloadJSON'); - payload.getHash(); - expect(spy.callCount).to.be.equal(1); - spy.restore(); - }); - }); -}); diff --git a/test/transaction/transaction.js b/test/transaction/transaction.js index 9048336bc..7c8e0b366 100644 --- a/test/transaction/transaction.js +++ b/test/transaction/transaction.js @@ -21,7 +21,7 @@ var Address = bitcore.Address; var Opcode = bitcore.Opcode; var errors = bitcore.errors; var Payload = bitcore.Transaction.Payload; -var SubTxRegisterPayload = Payload.SubTxRegisterPayload; +var AssetLockPayload = Payload.AssetLockPayload; var RegisteredTransactionTypes = Payload.constants.registeredTransactionTypes; var transactionVector = require('../data/tx_creation'); @@ -208,9 +208,7 @@ describe('Transaction', function () { it('should autofill version field if nothing passed to constructor', function () { var testKey = 'cNfg1KdmEXySkwK5XyydmgoKLbMaCiRyqPEtXZPw1aq8XMd5U5GF'; - var testName = 'test'; var transaction = new Transaction({ - type: Transaction.TYPES.TRANSACTION_SUBTX_REGISTER, outputs: [ { satoshis: 18492520000, @@ -229,10 +227,6 @@ describe('Transaction', function () { solvable: true, ps_rounds: -2, }); - transaction.extraPayload - .setUserName(testName) - .setPubKeyIdFromPrivateKey(testKey) - .sign(testKey); expect(transaction.version).to.be.equal(Transaction.CURRENT_VERSION); var serialized = transaction.sign(new PrivateKey(testKey)).serialize(true); @@ -1376,39 +1370,47 @@ describe('Transaction', function () { }); }); describe('setExtraPayload', function () { - var testName = 'test'; - var nameSize = Buffer.from(testName, 'utf8').length; - var validPayload = new SubTxRegisterPayload() - .setUserName(testName) - .setPubKeyIdFromPrivateKey(privateKey); + var output = Output.fromObject({ + satoshis: 1000, + script: Script.buildPublicKeyHashOut(fromAddress), + }); + + var validPayload = new AssetLockPayload.fromJSON({ + version: 1, + creditOutputs: [ + output + ] + }); it('Should set payload and size', function () { var transaction = Transaction() - .setType(Transaction.TYPES.TRANSACTION_SUBTX_REGISTER) + .setType(Transaction.TYPES.TRANSACTION_ASSET_LOCK) .setExtraPayload(validPayload); - // 2 bytes for payload version, 1 byte for username size, and 1 is empty signature + // 1 byte for payload version, 1 byte for array size and remaining is for output var expectedPayloadSize = - 2 + 1 + nameSize + Payload.constants.PUBKEY_ID_SIZE + 1; + 1 + 1 + output.toBufferWriter().toBuffer().length; var payloadSize = transaction.getExtraPayloadSize(); expect(payloadSize).to.be.equal(expectedPayloadSize); expect(transaction.extraPayload).to.be.deep.equal(validPayload); }); + it('Should be possible to serialize and deserialize special transaction', function () { var transaction = Transaction() .from(simpleUtxoWith1BTC) .to(fromAddress, 10000) .change(fromAddress) - .setType(RegisteredTransactionTypes.TRANSACTION_SUBTX_REGISTER) + .setType(RegisteredTransactionTypes.TRANSACTION_ASSET_LOCK) .setExtraPayload(validPayload) .sign(privateKey); var serialized = transaction.serialize(); var deserialized = new Transaction(serialized); - expect(deserialized.extraPayload).to.be.deep.equal(validPayload); + expect(deserialized.extraPayload.toJSON()).to.be.deep.equal(validPayload.toJSON()); expect(deserialized.type).to.be.equal(transaction.type); }); + it('Should not be possible to set extra payload if transaction type is not set', function () { expect(function () { var transaction = Transaction() @@ -1424,14 +1426,14 @@ describe('Transaction', function () { .from(simpleUtxoWith1BTC) .to(fromAddress, 10000) .change(fromAddress) - .setType(RegisteredTransactionTypes.TRANSACTION_SUBTX_REGISTER) + .setType(RegisteredTransactionTypes.TRANSACTION_ASSET_LOCK) .setExtraPayload(validPayload) .sign(privateKey); var serialized = transaction.toObject(); var deserialized = new Transaction(serialized); - expect(deserialized.extraPayload).to.be.deep.equal(validPayload); + expect(deserialized.extraPayload.toJSON()).to.be.deep.equal(validPayload.toJSON()); expect(deserialized.type).to.be.equal(transaction.type); }); it('Should throw when trying to serialize special transaction without any payload', function () { @@ -1439,7 +1441,7 @@ describe('Transaction', function () { .from(simpleUtxoWith1BTC) .to(fromAddress, 10000) .change(fromAddress) - .setType(Transaction.TYPES.TRANSACTION_SUBTX_REGISTER); + .setType(Transaction.TYPES.TRANSACTION_ASSET_LOCK); delete transaction.extraPayload; @@ -1447,12 +1449,13 @@ describe('Transaction', function () { transaction.sign(privateKey).serialize(); }).to.throw('Transaction payload size is invalid'); }); + it('Should throw when extra payload is set, but special transaction type is not set', function () { var transaction = Transaction() .from(simpleUtxoWith1BTC) .to(fromAddress, 10000) .change(fromAddress) - .setType(Transaction.TYPES.TRANSACTION_SUBTX_REGISTER) + .setType(Transaction.TYPES.TRANSACTION_ASSET_LOCK) .setExtraPayload(validPayload) .sign(privateKey); @@ -1463,6 +1466,8 @@ describe('Transaction', function () { }).to.throw('Special transaction type is not set'); }); }); + + describe('isSpecialTransaction', function () { it('Should return true if a transaction is qualified to be a special transaction', function () { var transaction = Transaction().setType( @@ -1480,24 +1485,24 @@ describe('Transaction', function () { describe('setType', function () { it('Should set type and create payload', function () { var transaction = new Transaction().setType( - Transaction.TYPES.TRANSACTION_SUBTX_REGISTER + Transaction.TYPES.TRANSACTION_ASSET_LOCK ); expect(transaction.type).to.be.equal( - Transaction.TYPES.TRANSACTION_SUBTX_REGISTER + Transaction.TYPES.TRANSACTION_ASSET_LOCK ); expect(transaction.extraPayload).to.be.an.instanceOf( - SubTxRegisterPayload + AssetLockPayload ); }); it('Should not be able to set transaction type after it was already set', function () { var transaction = new Transaction().setType( - Transaction.TYPES.TRANSACTION_SUBTX_REGISTER + Transaction.TYPES.TRANSACTION_ASSET_LOCK ); expect(transaction.extraPayload).to.be.an.instanceOf( - SubTxRegisterPayload + AssetLockPayload ); expect(function () { @@ -1637,94 +1642,6 @@ describe('Transaction', function () { }); describe('Special transaction payload integration', function () { - var randomPubKeyId = new PrivateKey() - .toPublicKey() - ._getID() - .toString('hex'); - var subTxRegisterHex = - '03000800000140420f0000000000016a000000005d0100047465737488d9931ea73d60eaf7e5671efc0552b912911f2a412068b83466eaae3ac1f5c021d8d95559592c1e4c49142dc0da61e4912e124b4bca5ad5f5e282e24f6c0c1b1580545479d2c40ca088e54316c836221a143da5596c'; - var username = 'test'; - var expectedPubKeyId = new PrivateKey(privateKey) - .toPublicKey() - ._getID() - .toString('hex'); - var privateKeyToSignTransaction = - 'cRbKdvygFSgwQQ61owyRuiNiknvWPN2zjjw7KS22q7kCwt2naVJf'; - - describe('Registration transaction', function () { - it('Should parse special transaction correctly', function () { - var parsedTransaction = new Transaction(subTxRegisterHex); - - expect(parsedTransaction.type).to.be.equal( - Transaction.TYPES.TRANSACTION_SUBTX_REGISTER - ); - expect(parsedTransaction.extraPayload.version).to.be.equal(1); - expect(parsedTransaction.extraPayload.userName).to.be.equal(username); - expect( - parsedTransaction.extraPayload.pubKeyId.toString('hex') - ).to.be.equal(expectedPubKeyId); - - expect(parsedTransaction.extraPayload.verifySignature(expectedPubKeyId)) - .to.be.true; - expect(parsedTransaction.extraPayload.verifySignature(randomPubKeyId)) - .to.be.false; - }); - - it('Should create valid hex', function () { - // In this case, funding will be 0.0001 and fee 0.00001 - var transaction = new Transaction() - .setType(Transaction.TYPES.TRANSACTION_SUBTX_REGISTER) - .from({ - txid: '51c8cc5d5f375983eb37891d66da4656aa2617ef3f82073a34dc7a76331486ff', - vout: 0, - address: 'yT9Lms2ATYLd3QLA4pVpg3mQ5KiHB9Dp1b', - scriptPubKey: - '210316dd99f0c194577d9f60ebfc889bdaf013f7bfd990acdf71b26d5eef14597c96ac', - amount: 345.18076547, - confirmations: 337, - spendable: true, - solvable: true, - ps_rounds: -2, - }) - .addFundingOutput(10000) - .to('yT9Lms2ATYLd3QLA4pVpg3mQ5KiHB9Dp1b', 34518076547 - 11000); - - transaction.extraPayload - .setUserName(username) - .setPubKeyIdFromPrivateKey(privateKey) - .sign(privateKey); - - transaction.sign(new PrivateKey(privateKeyToSignTransaction)); - - expect(transaction.extraPayload.version).to.be.equal(1); - expect(transaction.extraPayload.userName).to.be.equal(username); - expect(transaction.extraPayload.pubKeyId.toString('hex')).to.be.equal( - expectedPubKeyId - ); - - expect(transaction.extraPayload.verifySignature(expectedPubKeyId)).to.be - .true; - expect(transaction.extraPayload.verifySignature(randomPubKeyId)).to.be - .false; - }); - }); - - describe('Topup Transaction', function () { - it('Should parse the payload', function () { - var txHexString = - '030009000001001bb70000000000016a000000002201003727f1b7e5aa90f32235d045fd4624bf453fe8e16ea5010ad923f70d2f88fd45'; - - var transaction = new Transaction(txHexString); - - expect(transaction.extraPayload.version).to.be.equal(1); - expect(transaction.extraPayload.regTxHash).to.be.equal( - '45fd882f0df723d90a01a56ee1e83f45bf2446fd45d03522f390aae5b7f12737' - ); - - expect(transaction.outputs[0].satoshis).to.be.equal(12000000); - }); - }); - describe('Provider Register Transaction with collateral (protx register)', function () { it('Should parse the payload if transaction serialized as a hex string', function () { var tx = new Transaction(proRegTxFixture.getProRegTransactionHex()); @@ -1880,65 +1797,6 @@ describe('Transaction', function () { expect(tx.extraPayload.version).to.be.equal(1); }); }); - - describe('State transition', function () { - var regTxId = - 'd0df4810f9899a71968b5e4147b52cab86ad9342a9806a514227514d8a160a3c'; - var hashPrevSubTx = - 'd0df4810f9899a71968b5e4147b52cab86ad9342a9806a514227514d8a160a3c'; - var hashSTPacket = - 'a0df4810f9899a71968b5e4147b52cab86ad9342a9806a514227514d8a160a3a'; - var creditFee = 1000; // 0.00001 dash - - it('Should parse and verify hex', function () { - var subTxTransitionTxHex = - '03000c00000000000000ac01003c0a168a4d512742516a80a94293ad86ab2cb547415e8b96719a89f91048dfd03c0a168a4d512742516a80a94293ad86ab2cb547415e8b96719a89f91048dfd0e8030000000000003a0a168a4d512742516a80a94293ad86ab2cb547415e8b96719a89f91048dfa0411f3ae683b0a3ac3c3342ab30e646df344e8c3648902b48c5cb5f29c17f15a43ad93943b49c1f83a06321c6c434ae1c73d22ae83da3d39b9c5ce98a7947f5deab90'; - - var transaction = new Transaction(subTxTransitionTxHex); - - expect(transaction.extraPayload.version).to.be.equal(1); - expect(transaction.extraPayload.regTxId).to.be.equal(regTxId); - expect(transaction.extraPayload.hashPrevSubTx).to.be.equal( - hashPrevSubTx - ); - expect(transaction.extraPayload.hashSTPacket).to.be.equal(hashSTPacket); - expect(transaction.extraPayload.creditFee).to.be.equal(creditFee); - - expect(transaction.extraPayload.verifySignature(expectedPubKeyId)).to.be - .true; - expect(transaction.extraPayload.verifySignature(randomPubKeyId)).to.be - .false; - }); - - it('Should create valid hex', function () { - var prevSubTx = - 'ef94b22076eddf91430f52910f13dce287e46a9d878164ce07292a7f7ccaeb70'; - - var transaction = new Transaction().setType( - Transaction.TYPES.TRANSACTION_SUBTX_TRANSITION - ); - - transaction.extraPayload - .setRegTxId(regTxId) - .setHashPrevSubTx(prevSubTx) - .setHashSTPacket(hashSTPacket) - .setCreditFee(creditFee) - .sign(privateKey); - - var transactionHex = transaction.serialize(); - - expect(transaction.extraPayload.version).to.be.equal(1); - expect(transaction.extraPayload.regTxId).to.be.equal(regTxId); - expect(transaction.extraPayload.hashPrevSubTx).to.be.equal(prevSubTx); - expect(transaction.extraPayload.hashSTPacket).to.be.equal(hashSTPacket); - expect(transaction.extraPayload.creditFee).to.be.equal(creditFee); - - expect(transaction.extraPayload.verifySignature(expectedPubKeyId)).to.be - .true; - expect(transaction.extraPayload.verifySignature(randomPubKeyId)).to.be - .false; - }); - }); }); }); diff --git a/typings/transaction/Output.d.ts b/typings/transaction/Output.d.ts index 8b37f52fd..911e6e1c5 100644 --- a/typings/transaction/Output.d.ts +++ b/typings/transaction/Output.d.ts @@ -1,6 +1,11 @@ import { Script } from '../script/Script'; import { BufferWriter } from '../buffer/BufferWriter'; +export type OutputJSON = { + satoshis: number, + script: string +} + /** * Instantiate an Output from an Object @@ -36,9 +41,9 @@ export class Output { /** * @function - * @returns {Object} A plain object with the output information + * @returns {OutputJSON} A plain object with the output information */ - toJSON(): Object; + toJSON(): OutputJSON; /** * Instantiate an address from an Object diff --git a/typings/transaction/Transaction.d.ts b/typings/transaction/Transaction.d.ts index e2a28589a..abf9f508b 100644 --- a/typings/transaction/Transaction.d.ts +++ b/typings/transaction/Transaction.d.ts @@ -9,6 +9,7 @@ import { AbstractPayload } from './payload/AbstractPayload'; import { bitcore } from '../bitcore'; import { TransactionSignature } from './TransactionSignature'; import { UnspentOutput } from './UnspentOutput'; +import { Payload } from './payload/Payload'; export namespace Transaction { /** @@ -38,6 +39,7 @@ export namespace Transaction { export { Output }; export { UnspentOutput }; export { TransactionSignature as Signature }; + export { Payload }; } /** * Represents a transaction, a set of inputs and outputs to change ownership of tokens @@ -385,7 +387,6 @@ export class Transaction { sign(privateKey: any[] | string | PrivateKey, sigtype?: number): Transaction; getSignatures(): any[]; - canHaveNoUtxo(): boolean; /** * Add a signature to the transaction diff --git a/typings/transaction/payload/AssetLockPayload.d.ts b/typings/transaction/payload/AssetLockPayload.d.ts new file mode 100644 index 000000000..718383469 --- /dev/null +++ b/typings/transaction/payload/AssetLockPayload.d.ts @@ -0,0 +1,59 @@ +import { Output, OutputJSON } from '../Output'; + +/** + * @typedef {Object} AssetLockPayloadJSON + * @property {number} version + * @property {OutputJSON[]} creditOutputs + */ +export type AssetLockPayloadJSON = { + version: number; + creditOutputs: OutputJSON[] +}; + +/** + * @class AssetLockPayload + * @property {number} version + * @property {Output[]} creditOutputs + */ +export class AssetLockPayload { + /** + * Parse raw transition payload + * @param {Buffer} rawPayload + * @return {AssetLockPayload} + */ + static fromBuffer(rawPayload: Buffer): AssetLockPayload; + + /** + * Create new instance of payload from JSON + * @param {string|AssetLockPayloadJSON} payloadJson + * @return {AssetLockPayload} + */ + static fromJSON(payloadJson: string | AssetLockPayloadJSON): AssetLockPayload; + + /** + * Validates payload data + * @return {boolean} + */ + validate(): boolean; + + /** + * Serializes payload to JSON + * @return {AssetLockPayloadJSON} + */ + toJSON(): AssetLockPayloadJSON; + + /** + * Serialize payload to buffer + * @return {Buffer} + */ + toBuffer(): Buffer; + + /** + * Copy payload instance + * @return {AssetLockPayload} + */ + copy(): AssetLockPayload; + + version: number; + creditOutputs: Output[] +} diff --git a/typings/transaction/payload/Payload.d.ts b/typings/transaction/payload/Payload.d.ts new file mode 100644 index 000000000..5fbdcb24e --- /dev/null +++ b/typings/transaction/payload/Payload.d.ts @@ -0,0 +1,17 @@ +import { ProRegTxPayload } from './ProRegTxPayload'; +import { ProUpRegTxPayload } from './ProUpRegTxPayload'; +import { ProUpRevTxPayload } from './ProUpRevTxPayload'; +import { ProUpServTxPayload } from './ProUpServTxPayload'; +import { CoinbasePayload } from './CoinbasePayload'; +import { CommitmentTxPayload } from './CommitmentTxPayload'; +import { AssetLockPayload } from './AssetLockPayload'; + +export namespace Payload { + export { ProRegTxPayload }; + export { ProUpRegTxPayload }; + export { ProUpRevTxPayload }; + export { ProUpServTxPayload }; + export { CoinbasePayload }; + export { CommitmentTxPayload }; + export { AssetLockPayload }; +} \ No newline at end of file diff --git a/typings/transaction/payload/SubTxCloseAccountPayload.d.ts b/typings/transaction/payload/SubTxCloseAccountPayload.d.ts deleted file mode 100644 index 78cc1c55c..000000000 --- a/typings/transaction/payload/SubTxCloseAccountPayload.d.ts +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @typedef {Object} SubTxCloseAccountPayloadJSON - * @property {number} version - payload version - * @property {string} regTxHash - * @property {string} hashPrevSubTx - * @property {number} creditFee - fee to pay for transaction (duffs) - * @property {number} payloadSigSize - length of the signature (payloadSig) - * @property {string} payloadSig - Signature from either the current key or a previous key (<= ~90 days old) - */ -export type SubTxCloseAccountPayloadJSON = { - version: number; - regTxHash: string; - hashPrevSubTx: string; - creditFee: number; - payloadSigSize: number; - payloadSig: string; -}; - -/** - * @class SubTxCloseAccountPayload - * @property {number} version - payload version - * @property {string} regTxHash - * @property {string} hashPrevSubTx - * @property {number} creditFee - fee to pay for transaction (duffs) - * @property {number} payloadSigSize - length of the signature (payloadSig) - * @property {string} payloadSig - Signature from either the current key or a previous key (<= ~90 days old) - */ -export class SubTxCloseAccountPayload { - /** - * Parse raw transition payload - * @param {Buffer} rawPayload - * @return {SubTxCloseAccountPayload} - */ - static fromBuffer(rawPayload: Buffer): SubTxCloseAccountPayload; - - /** - * Create new instance of payload from JSON - * @param {string|SubTxCloseAccountPayloadJSON} payloadJson - * @return {SubTxCloseAccountPayload} - */ - static fromJSON( - payloadJson: string | SubTxCloseAccountPayloadJSON - ): SubTxCloseAccountPayload; - - /** - * Validates payload data - * @return {boolean} - */ - validate(): boolean; - - /** - * @param {string} regTxHash - * @return {SubTxCloseAccountPayload} - */ - setRegTxHash(regTxHash: string): SubTxCloseAccountPayload; - - /** - * @param {string} hashPrevSubTx - * @return {SubTxCloseAccountPayload} - */ - setPrevSubTxHash(hashPrevSubTx: string): SubTxCloseAccountPayload; - - /** - * @param {number} duffs - * @return {SubTxCloseAccountPayload} - */ - setCreditFee(duffs: number): SubTxCloseAccountPayload; - - /** - * Serializes payload to JSON - * @return {{version: *, regTxHash: *, hashPrevSubTx: *, creditFee: *, payloadSigSize: *, payloadSig: *}} - */ - toJSON(): any; - - /** - * Serialize payload to buffer - * @return {Buffer} - */ - toBuffer(): Buffer; - - /** - * payload version - */ - version: number; - regTxHash: string; - hashPrevSubTx: string; - /** - * fee to pay for transaction (duffs) - */ - creditFee: number; - /** - * length of the signature (payloadSig) - */ - payloadSigSize: number; - /** - * Signature from either the current key or a previous key (<= ~90 days old) - */ - payloadSig: string; -} diff --git a/typings/transaction/payload/SubTxRegisterPayload.d.ts b/typings/transaction/payload/SubTxRegisterPayload.d.ts deleted file mode 100644 index 4e26d6ef7..000000000 --- a/typings/transaction/payload/SubTxRegisterPayload.d.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { PrivateKey } from '../../PrivateKey'; - -/** - * @typedef {Object} BlockchainUserPayloadJSON - * @property {number} version - payload version - * @property {Buffer} pubKeyId - * @property {string} userName - * @property {string} [payloadSig] - * @property {string} [payloadSigSize] - */ -export type BlockchainUserPayloadJSON = { - version: number; - pubKeyId: Buffer; - userName: string; - payloadSig?: string; - payloadSigSize?: string; -}; - -/** - * @class SubTxRegisterPayload - * @property {number} version - payload version - * @property {Buffer} pubKeyId - * @property {string} userName - * @property {string} [payloadSig] - * @property {string} [payloadSigSize] - */ -export class SubTxRegisterPayload { - /** - * Serialize blockchain user payload - * @param {BlockchainUserPayloadJSON} blockchainUserPayload - * @return {Buffer} serialized payload - */ - static serializeJSONToBuffer( - blockchainUserPayload: BlockchainUserPayloadJSON - ): Buffer; - - /** - * Parse raw blockchain user payload - * @param {Buffer} rawPayload - * @return {SubTxRegisterPayload} - */ - static fromBuffer(rawPayload: Buffer): SubTxRegisterPayload; - - /** - * Create new instance of payload from JSON - * @param {string|BlockchainUserPayloadJSON} payloadJson - * @return {SubTxRegisterPayload} - */ - static fromJSON( - payloadJson: string | BlockchainUserPayloadJSON - ): SubTxRegisterPayload; - - /** - * Validate payload - * @param {BlockchainUserPayloadJSON} blockchainUserPayload - * @return {boolean} - */ - static validatePayloadJSON( - blockchainUserPayload: BlockchainUserPayloadJSON - ): boolean; - - /** - * @param {string} userName - * @return {SubTxRegisterPayload} - */ - setUserName(userName: string): SubTxRegisterPayload; - - /** - * @param {Buffer} pubKeyId - * @return {SubTxRegisterPayload} - */ - setPubKeyId(pubKeyId: Buffer): SubTxRegisterPayload; - - /** - * Extracts and sets pubKeyId from private key - * @param {string|PrivateKey} privateKey - * @return {SubTxRegisterPayload} - */ - setPubKeyIdFromPrivateKey( - privateKey: string | PrivateKey - ): SubTxRegisterPayload; - - /** - * Serializes payload to JSON - * @param [options] - * @param {boolean} options.skipSignature - skip signature part. Needed for creating new signature - * @return {BlockchainUserPayloadJSON} - */ - toJSON(options?: { skipSignature: boolean }): BlockchainUserPayloadJSON; - - /** - * Serialize payload to buffer - * @param [options] - * @param {boolean} options.skipSignature - skip signature part. Needed for creating new signature - * @return {Buffer} - */ - toBuffer(options?: { skipSignature: boolean }): Buffer; - - /** - * payload version - */ - version: number; - pubKeyId: Buffer; - userName: string; - payloadSig?: string; - payloadSigSize?: string; -} diff --git a/typings/transaction/payload/SubTxResetKeyPayload.d.ts b/typings/transaction/payload/SubTxResetKeyPayload.d.ts deleted file mode 100644 index 9c96a2de0..000000000 --- a/typings/transaction/payload/SubTxResetKeyPayload.d.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { PrivateKey } from '../../PrivateKey'; - -/** - * @typedef {Object} SubTxResetKeyPayloadJSON - * @property {number} version - payload version - * @property {string} regTxHash - * @property {string} hashPrevSubTx - * @property {number} creditFee - fee to pay for transaction (duffs) - * @property {number} newPubKeySize - length of the new public key (not present in implementation) - * @property {Buffer} newPubKey - * @property {number} payloadSigSize - length of the signature (payloadSig) - * @property {string} payloadSig - signature of most recent pubkey - */ -export type SubTxResetKeyPayloadJSON = { - version: number; - regTxHash: string; - hashPrevSubTx: string; - creditFee: number; - newPubKeySize: number; - newPubKey: Buffer; - payloadSigSize: number; - payloadSig: string; -}; - -/** - * @class SubTxResetKeyPayload - * @property {number} version - payload version - * @property {string} regTxHash - * @property {string} hashPrevSubTx - * @property {number} creditFee - fee to pay for transaction (duffs) - * @property {number} newPubKeySize - length of the new public key (not present in implementation) - * @property {Buffer} newPubKey - * @property {number} payloadSigSize - length of the signature (payloadSig) - * @property {string} payloadSig - signature of most recent pubkey - */ -export class SubTxResetKeyPayload { - /** - * Parse raw transition payload - * @param {Buffer} rawPayload - * @return {SubTxResetKeyPayload} - */ - static fromBuffer(rawPayload: Buffer): SubTxResetKeyPayload; - - /** - * Create new instance of payload from JSON - * @param {string|SubTxResetKeyPayloadJSON} payloadJson - * @return {SubTxResetKeyPayload} - */ - static fromJSON( - payloadJson: string | SubTxResetKeyPayloadJSON - ): SubTxResetKeyPayload; - - /** - * Validates payload data - * @return {boolean} - */ - validate(): boolean; - - /** - * @param {string} regTxHash - * @return {SubTxResetKeyPayload} - */ - setRegTxHash(regTxHash: string): SubTxResetKeyPayload; - - /** - * @param {string} hashPrevSubTx - * @return {SubTxResetKeyPayload} - */ - setPrevSubTxHash(hashPrevSubTx: string): SubTxResetKeyPayload; - - /** - * @param {number} duffs - * @return {SubTxResetKeyPayload} - */ - setCreditFee(duffs: number): SubTxResetKeyPayload; - - /** - * @param {Buffer} pubKeyId - * @return {SubTxResetKeyPayload} - */ - setNewPubKeyId(pubKeyId: Buffer): SubTxResetKeyPayload; - - /** - * Extracts and sets pubKeyId from private key - * @param {string|PrivateKey} privateKey - * @return {SubTxResetKeyPayload} - */ - setPubKeyIdFromPrivateKey( - privateKey: string | PrivateKey - ): SubTxResetKeyPayload; - - /** - * Serializes payload to JSON - * @return {{version: *, regTxHash: *, hashPrevSubTx: *, creditFee: *, newPubKeySize: *, newPubKey: *, payloadSigSize: *, payloadSig: *}} - */ - toJSON(): any; - - /** - * Serialize payload to buffer - * @return {Buffer} - */ - toBuffer(): Buffer; - - /** - * payload version - */ - version: number; - regTxHash: string; - hashPrevSubTx: string; - /** - * fee to pay for transaction (duffs) - */ - creditFee: number; - /** - * length of the new public key (not present in implementation) - */ - newPubKeySize: number; - newPubKey: Buffer; - /** - * length of the signature (payloadSig) - */ - payloadSigSize: number; - /** - * signature of most recent pubkey - */ - payloadSig: string; -} diff --git a/typings/transaction/payload/SubTxTopupPayload.d.ts b/typings/transaction/payload/SubTxTopupPayload.d.ts deleted file mode 100644 index 04779b135..000000000 --- a/typings/transaction/payload/SubTxTopupPayload.d.ts +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @typedef {Object} SubTxTopupPayloadJSON - * @property {number} version - * @property {string} regTxHash - */ -export type SubTxTopupPayloadJSON = { - version: number; - regTxHash: string; -}; - -/** - * @class SubTxTopupPayload - * @property {number} version - * @property {string} regTxHash - */ -export class SubTxTopupPayload { - /** - * Parse raw transition payload - * @param {Buffer} rawPayload - * @return {SubTxTopupPayload} - */ - static fromBuffer(rawPayload: Buffer): SubTxTopupPayload; - - /** - * Create new instance of payload from JSON - * @param {string|SubTxTopupPayloadJSON} payloadJson - * @return {SubTxTopupPayload} - */ - static fromJSON( - payloadJson: string | SubTxTopupPayloadJSON - ): SubTxTopupPayload; - - /** - * Validates payload data - * @return {boolean} - */ - validate(): boolean; - - /** - * Serializes payload to JSON - * @return {SubTxTopupPayload} - */ - toJSON(): SubTxTopupPayload; - - /** - * Serialize payload to buffer - * @return {Buffer} - */ - toBuffer(): Buffer; - - /** - * Copy payload instance - * @return {SubTxTopupPayload} - */ - copy(): SubTxTopupPayload; - - /** - * @param {string} regTxHash - * @return {SubTxTopupPayload} - */ - setRegTxHash(regTxHash: string): SubTxTopupPayload; - - version: number; - regTxHash: string; -} diff --git a/typings/transaction/payload/SubTxTransitionPayload.d.ts b/typings/transaction/payload/SubTxTransitionPayload.d.ts deleted file mode 100644 index bb7808783..000000000 --- a/typings/transaction/payload/SubTxTransitionPayload.d.ts +++ /dev/null @@ -1,124 +0,0 @@ -/** - * @typedef {Object} TransitionPayloadJSON - * @property {Number} version - * @property {string} regTxId - * @property {string} hashPrevSubTx - * @property {Number} creditFee - * @property {string} hashSTPacket - * @property {string} [payloadSig] - * @property {string} [payloadSigSize] - */ -export type TransitionPayloadJSON = { - version: number; - regTxId: string; - hashPrevSubTx: string; - creditFee: number; - hashSTPacket: string; - payloadSig?: string; - payloadSigSize?: string; -}; - -/** - * @class SubTxTransitionPayload - * @property {number} version - * @property {string} regTxId - * @property {string} hashPrevSubTx - * @property {number} creditFee - * @property {string} hashSTPacket - * @property {string} [payloadSig] - * @property {string} [payloadSigSize] - */ -export class SubTxTransitionPayload { - /** - * Serialize transition payload - * @param {TransitionPayloadJSON} transitionPayload - * @return {Buffer} serialized payload - */ - static serializeJSONToBuffer( - transitionPayload: TransitionPayloadJSON - ): Buffer; - - /** - * Parse raw transition payload - * @param {Buffer} rawPayload - * @return {SubTxTransitionPayload} - */ - static fromBuffer(rawPayload: Buffer): SubTxTransitionPayload; - - /** - * Create new instance of payload from JSON - * @param {string|TransitionPayloadJSON} payloadJson - * @return {SubTxTransitionPayload} - */ - static fromJSON( - payloadJson: string | TransitionPayloadJSON - ): SubTxTransitionPayload; - - /** - * Validate payload - * @param {TransitionPayloadJSON} blockchainUserPayload - * @return {boolean} - */ - static validatePayloadJSON( - blockchainUserPayload: TransitionPayloadJSON - ): boolean; - - /** - * Validates payload data - * @return {boolean} - */ - validate(): boolean; - - /** - * @param {string} regTxId - Hex string - */ - setRegTxId(regTxId: string): void; - - /** - * @param {string} hashPrevSubTx - Hex string - * @return {SubTxTransitionPayload} - */ - setHashPrevSubTx(hashPrevSubTx: string): SubTxTransitionPayload; - - /** - * @param {string} hashSTPacket - Hex string - * @return {SubTxTransitionPayload} - */ - setHashSTPacket(hashSTPacket: string): SubTxTransitionPayload; - - /** - * @param {number} creditFee - * @return {SubTxTransitionPayload} - */ - setCreditFee(creditFee: number): SubTxTransitionPayload; - - /** - * Serializes payload to JSON - * @param [options] - * @param {boolean} options.skipSignature - skip signature part. Needed for creating new signature - * @return {TransitionPayloadJSON} - */ - toJSON(options?: { skipSignature: boolean }): TransitionPayloadJSON; - - /** - * Serialize payload to buffer - * @param [options] - * @param {boolean} options.skipSignature - skip signature part. Needed for creating new signature - * @return {Buffer} - */ - toBuffer(options?: { skipSignature: boolean }): Buffer; - - /** - * Copy payload instance - * @return {SubTxTransitionPayload} - */ - copy(): SubTxTransitionPayload; - - version: number; - regTxId: string; - hashPrevSubTx: string; - creditFee: number; - hashSTPacket: string; - payloadSig?: string; - payloadSigSize?: string; -}