diff --git a/src/core/Invoice.ts b/src/core/Invoice.ts index 2f7dcfb9..ef3a82b1 100644 --- a/src/core/Invoice.ts +++ b/src/core/Invoice.ts @@ -3,23 +3,42 @@ import { Buffer } from "buffer"; const RLP = require("rlp"); /** - * Used to know whether a transaction succeeded or failed. + * An Invoice is used to know whether a transaction or a parcel succeeded or + * failed. */ export class Invoice { readonly success: boolean; + /** + * @param success Whether a transaction or a parcel succeeded or failed. + */ constructor(success: boolean) { this.success = !!success; } + // FIXME: any + /** + * Create an Invoice from an Invoice JSON object. + * @param data An Invoice JSON object. + * @returns An Invoice. + */ static fromJSON(data: any) { return new this(data === "Success"); } + /** + * Convert to an Invoice JSON object. + * @returns An Invoice JSON object. + */ toJSON() { return this.success ? "Success" : "Failed"; } + /** + * Decode RLP bytes to an Invoice. + * @param buffer RLP bytes. + * @returns An Invoice. + */ static fromBytes(buffer: Buffer): Invoice { const bytes = Array.from(buffer.values()); if (bytes.length !== 1 || bytes[0] > 0x01) { @@ -28,10 +47,17 @@ export class Invoice { return new Invoice(RLP.decode(buffer)[0]); } + /** + * Convert to an object for RLP encoding. + */ toEncodeObject(): boolean { return this.success; } + /** + * Convert to RLP bytes + * @returns RLP bytes + */ rlpBytes(): Buffer { return Buffer.from([this.toEncodeObject() ? 0x01 : 0x00]); } diff --git a/src/core/SignedParcel.ts b/src/core/SignedParcel.ts index c1cdb13d..1365434e 100644 --- a/src/core/SignedParcel.ts +++ b/src/core/SignedParcel.ts @@ -12,7 +12,7 @@ const RLP = require("rlp"); /** * A [Parcel](parcel.html) signed by a private key. It is possible to request - * processing on the CodeChain network with the + * the CodeChain network to process this parcel with the * [sendSignedParcel](chainrpc.html#sendsignedparcel) function. * * Parcels signed with a regular key has the same effect as those signed with @@ -20,17 +20,9 @@ const RLP = require("rlp"); * the regular key. * * If any of the following is true, the Parcel will not be processed: - * the Parcel's processing fee is less than 10, network ID is not identical, or - * the nonce is not identical. - * - * - When including a Payment transaction, the payment's sender and the parcel's - * signer must be identical. - * - When including a SetRegularKey transaction, the transaction's address and - * the parcel's signer must be identical. - * - If the asset type that is being transferred from AssetTransferTransaction - * has a registrar, the registrar must be identical to the parcel's signer. - * If any of the transactions above have an invalid signer for any of the - * conditions, then individual transactions will fail. + * - The Parcel's processing fee is less than 10. + * - A network ID is not identical. + * - A nonce is not identical to the signer's nonce. */ export class SignedParcel { unsigned: Parcel; @@ -41,6 +33,13 @@ export class SignedParcel { blockHash: H256 | null; parcelIndex: number | null; + /** + * @param unsigned A Parcel. + * @param sig An ECDSA signature which is a 65 byte hexadecimal string. + * @param blockNumber The block number of the block that contains the parcel. + * @param blockHash The hash of the block that contains the parcel. + * @param parcelIndex The index(location) of the parcel within the block. + */ constructor(unsigned: Parcel, sig: string, blockNumber?: number, blockHash?: H256, parcelIndex?: number) { this.unsigned = unsigned; const { r, s, v } = SignedParcel.convertSignatureStringToRsv(sig); @@ -52,11 +51,17 @@ export class SignedParcel { this.parcelIndex = parcelIndex === undefined ? null : parcelIndex; } + /** + * Get the signature of a parcel. + */ signature() { const { v, r, s } = this; return { v, r, s }; } + /** + * Convert to an object for RLP encoding. + */ toEncodeObject(): Array { const { unsigned: { nonce, fee, action, networkId }, v, r, s } = this; const sig = `0x${_.padStart(r.value.toString(16), 64, "0")}${_.padStart(s.value.toString(16), 64, "0")}${_.padStart(v.toString(16), 2, "0")}`; @@ -72,14 +77,25 @@ export class SignedParcel { ]; } + /** + * Convert to RLP bytes. + */ rlpBytes(): Buffer { return RLP.encode(this.toEncodeObject()); } + /** + * Get the hash of a parcel. + * @returns A parcel hash. + */ hash(): H256 { return new H256(blake256(this.rlpBytes())); } + /** + * Get the account ID of a parcel's signer. + * @returns An account ID. + */ getSignerAccountId(): H160 { const { r, s, v, unsigned } = this; const publicKey = recoverEcdsa(unsigned.hash().value, { @@ -90,10 +106,20 @@ export class SignedParcel { return new H160(ripemd160(blake256(publicKey))); } + /** + * Get the platform address of a parcel's signer. + * @returns A PlatformAddress. + */ getSignerAddress(): PlatformAddress { return PlatformAddress.fromAccountId(this.getSignerAccountId()); } + // FIXME: any + /** + * Create a SignedParcel from a SignedParcel JSON object. + * @param data A SignedParcel JSON object. + * @returns A SignedParcel. + */ static fromJSON(data: any) { const { sig, blockNumber, blockHash, parcelIndex } = data; if (typeof sig !== "string") { @@ -106,6 +132,10 @@ export class SignedParcel { } } + /** + * Convert to a SignedParcel JSON object. + * @returns A SignedParcel JSON object. + */ toJSON() { const { blockNumber, blockHash, parcelIndex, unsigned: { nonce, fee, networkId, action }, v, r, s } = this; @@ -137,6 +167,13 @@ export class SignedParcel { return { r, s, v }; } + /** + * Convert r, s, v values of an ECDSA signature to a string. + * @param params.r The r value of an ECDSA signature, which is up to 32 bytes of hexadecimal string. + * @param params.s The s value of an ECDSA signature, which is up to 32 bytes of hexadecimal string. + * @param params.v The recovery parameter of an ECDSA signature. + * @returns A 65 byte hexadecimal string. + */ static convertRsvToSignatureString(params: { r: string, s: string, v: number }) { const { r, s, v } = params; return `0x${_.padStart(r, 64, "0")}${_.padStart(s, 64, "0")}${_.padStart(v.toString(16), 2, "0")}`; diff --git a/src/core/transaction/AssetMintTransaction.ts b/src/core/transaction/AssetMintTransaction.ts index 2ced0d2f..63481b57 100644 --- a/src/core/transaction/AssetMintTransaction.ts +++ b/src/core/transaction/AssetMintTransaction.ts @@ -26,12 +26,16 @@ export type AssetMintTransactionData = { /** * Creates a new asset type and that asset itself. * - * The owner of the new asset created can be assigned by lockScriptHash and parameters. - * - metadata is a string that explains the asset's type. - * - amount defines the quantity of asset to be created. If set as null, it will be set as the maximum value of a 64-bit unsigned integer by default. - * - If registrar exists, the registrar must be the Signer of the Parcel when sending the created asset through AssetTransferTransaction. - * - Transaction hash can be changed by changing nonce. - * - If an identical transaction hash already exists, then the change fails. In this situation, a transaction can be created again by arbitrarily changing the nonce. + * The owner of the new asset created can be assigned by a lock script hash and parameters. + * - A metadata is a string that explains the asset's type. + * - Amount defines the quantity of asset to be created. If set as null, it + * will be set as the maximum value of a 64-bit unsigned integer by default. + * - If registrar exists, the registrar must be the Signer of the Parcel when + * sending the created asset through AssetTransferTransaction. + * - A transaction hash can be changed by changing nonce. + * - If an identical transaction hash already exists, then the change fails. In + * this situation, a transaction can be created again by arbitrarily changing + * the nonce. */ export class AssetMintTransaction { readonly networkId: number; @@ -46,6 +50,16 @@ export class AssetMintTransaction { readonly nonce: number; readonly type = "assetMint"; + /** + * @param data.networkId A network ID of the transaction. + * @param data.shardId A shard ID of the transaction. + * @param data.metadata A metadata of the asset. + * @param data.output.lockScriptHash A lock script hash of the output. + * @param data.output.parameters Parameters of the output. + * @param data.output.amount Asset amount of the output. + * @param data.registrar A registrar of the asset. + * @param data.nonce A nonce of the transaction. + */ constructor(data: AssetMintTransactionData) { const { networkId, shardId, metadata, output, registrar, nonce } = data; this.networkId = networkId; @@ -56,8 +70,13 @@ export class AssetMintTransaction { this.nonce = nonce; } - static fromJSON(obj: any) { - const { data: { networkId, shardId, metadata, output: { lockScriptHash, parameters, amount }, registrar, nonce } } = obj; + /** + * Create an AssetMintTransaction from an AssetMintTransaction JSON object. + * @param data An AssetMintTransaction JSON object. + * @returns An AssetMintTransaction. + */ + static fromJSON(data: any) { + const { data: { networkId, shardId, metadata, output: { lockScriptHash, parameters, amount }, registrar, nonce } } = data; return new this({ networkId, shardId, @@ -72,6 +91,10 @@ export class AssetMintTransaction { }); } + /** + * Convert to an AssetMintTransaction JSON object. + * @returns An AssetMintTransaction JSON object. + */ toJSON() { const { networkId, shardId, metadata, output: { lockScriptHash, parameters, amount }, registrar, nonce } = this; return { @@ -91,6 +114,9 @@ export class AssetMintTransaction { }; } + /** + * Convert to an object for RLP encoding. + */ toEncodeObject() { const { networkId, shardId, metadata, output: { lockScriptHash, parameters, amount }, registrar, nonce } = this; return [ @@ -106,14 +132,25 @@ export class AssetMintTransaction { ]; } + /** + * Convert to RLP bytes. + */ rlpBytes(): Buffer { return RLP.encode(this.toEncodeObject()); } + /** + * Get the hash of an AssetMintTransaction. + * @returns A transaction hash. + */ hash(): H256 { return new H256(blake256(this.rlpBytes())); } + /** + * Get the output of this transaction. + * @returns An Asset. + */ getMintedAsset(): Asset { const { lockScriptHash, parameters, amount } = this.output; // FIXME: need U64 to be implemented or use U256 @@ -130,6 +167,10 @@ export class AssetMintTransaction { }); } + /** + * Get the asset scheme of this transaction. + * @return An AssetScheme. + */ getAssetScheme(): AssetScheme { const { networkId, shardId, metadata, output: { amount }, registrar } = this; // FIXME: need U64 to be implemented or use U256 @@ -145,6 +186,11 @@ export class AssetMintTransaction { }); } + /** + * Get the address of the asset scheme. An asset scheme address equals to an + * asset type value. + * @returns An asset scheme address which is H256. + */ getAssetSchemeAddress(): H256 { const { shardId } = this; const blake = blake256WithKey(this.hash().value, new Uint8Array([ @@ -157,6 +203,10 @@ export class AssetMintTransaction { return new H256(blake.replace(new RegExp(`^.{${prefix.length}}`), prefix)); } + /** + * Get the asset address of the output. + * @returns An asset address which is H256. + */ getAssetAddress(): H256 { const { shardId } = this; const blake = blake256WithKey(this.hash().value, new Uint8Array([ diff --git a/src/core/transaction/AssetOutPoint.ts b/src/core/transaction/AssetOutPoint.ts index a34f9478..94708edd 100644 --- a/src/core/transaction/AssetOutPoint.ts +++ b/src/core/transaction/AssetOutPoint.ts @@ -24,6 +24,14 @@ export class AssetOutPoint { readonly lockScriptHash?: H256; readonly parameters?: Buffer[]; + /** + * @param data.transactionHash A transaction hash where the Asset is created. + * @param data.index The index in the output of the transaction. + * @param data.assetType The asset type of the asset that it points to. + * @param data.amount The asset amount of the asset that it points to. + * @param data.lockScriptHash The lock script hash of the asset. + * @param data.parameters The parameters of the asset. + */ constructor(data: AssetOutPointData) { const { transactionHash, index, assetType, amount, lockScriptHash, parameters } = data; this.transactionHash = transactionHash; @@ -34,11 +42,19 @@ export class AssetOutPoint { this.parameters = parameters; } + /** + * Convert to an object for RLP encoding. + */ toEncodeObject() { const { transactionHash, index, assetType, amount } = this; return [transactionHash.toEncodeObject(), index, assetType.toEncodeObject(), amount]; } + /** + * Create an AssetOutPoint from an AssetOutPoint JSON object. + * @param data An AssetOutPoint JSON object. + * @returns An AssetOutPoint. + */ static fromJSON(data: any) { const { transactionHash, index, assetType, amount } = data; return new this({ @@ -49,6 +65,10 @@ export class AssetOutPoint { }); } + /** + * Convert to an AssetOutPoint JSON object. + * @returns An AssetOutPoint JSON object. + */ toJSON() { const { transactionHash, index, assetType, amount } = this; return { diff --git a/src/core/transaction/AssetTransferInput.ts b/src/core/transaction/AssetTransferInput.ts index 238c8ea6..aaf97927 100644 --- a/src/core/transaction/AssetTransferInput.ts +++ b/src/core/transaction/AssetTransferInput.ts @@ -7,19 +7,24 @@ export type AssetTransferInputData = { lockScript?: Buffer; unlockScript?: Buffer; }; + /** - * AssetTransferInput consists of the following: - * - * - AssetOutPoint, which points to the asset to be spent. - * - lockScript and unlockScript, that prove ownership of the asset - * - The hashed value(blake256) of lockScript must be identical to that of the pointed asset's lockScriptHash. - * - The results of running the script must return successful in order for the Asset's Input to be valid. + * An AssetTransferInput consists of the following: + * - An AssetOutPoint, which points to the asset to be spent. + * - A lock script and an unlock script, that prove ownership of the asset + * - The hashed value(blake256) of a lock script must be identical to that of the pointed asset's lock script hash. + * - The results of running the script must return successful in order for the Asset's input to be valid. */ export class AssetTransferInput { readonly prevOut: AssetOutPoint; lockScript: Buffer; unlockScript: Buffer; + /** + * @param data.prevOut An AssetOutPoint of the input. + * @param data.lockScript A lock script of the input. + * @param data.unlockScript A unlock script of the input. + */ constructor(data: AssetTransferInputData) { const { prevOut, lockScript = Buffer.from([]), unlockScript = Buffer.from([]) } = data; this.prevOut = prevOut; @@ -27,11 +32,19 @@ export class AssetTransferInput { this.unlockScript = Buffer.from(unlockScript); } + /** + * Convert to an object for RLP encoding. + */ toEncodeObject() { const { prevOut, lockScript, unlockScript } = this; return [prevOut.toEncodeObject(), lockScript, unlockScript]; } + /** + * Create an AssetTransferInput from an AssetTransferInput JSON object. + * @param data An AssetTransferInput JSON object. + * @returns An AssetTransferInput. + */ static fromJSON(data: any) { const { prevOut, lockScript, unlockScript } = data; return new this({ @@ -41,6 +54,10 @@ export class AssetTransferInput { }); } + /** + * Convert to an AssetTransferInput JSON object. + * @returns An AssetTransferInput JSON object. + */ toJSON() { const { prevOut, lockScript, unlockScript } = this; return { @@ -50,6 +67,11 @@ export class AssetTransferInput { }; } + /** + * Clone a new AssetTransferInput that has empty lock script and empty + * unlock script. The cloned object is used to sign a transaction. + * @returns An AssetTransferInput. + */ withoutScript() { const { prevOut } = this; return new AssetTransferInput({ @@ -59,10 +81,18 @@ export class AssetTransferInput { }); } + /** + * Set a lock script. + * @param lockScript A lock script. + */ setLockScript(lockScript: Buffer) { this.lockScript = lockScript; } + /** + * Set a unlock script. + * @param unlockScript A unlock script. + */ setUnlockScript(unlockScript: Buffer) { this.unlockScript = unlockScript; } diff --git a/src/core/transaction/AssetTransferOutput.ts b/src/core/transaction/AssetTransferOutput.ts index 294e805c..13d9680a 100644 --- a/src/core/transaction/AssetTransferOutput.ts +++ b/src/core/transaction/AssetTransferOutput.ts @@ -9,7 +9,9 @@ export type AssetTransferOutputData = { amount: number; }; /** - * AssetTransferOutput consists of lockScriptHash and parameters, which mark ownership of the asset, and asset type and amount, which indicate the asset's type and quantity. + * An AssetTransferOutput consists of: + * - A lock script hash and parameters, which mark ownership of the asset. + * - An asset type and amount, which indicate the asset's type and quantity. */ export class AssetTransferOutput { readonly lockScriptHash: H256; @@ -17,6 +19,12 @@ export class AssetTransferOutput { readonly assetType: H256; readonly amount: number; + /** + * @param data.lockScriptHash A lock script hash of the output. + * @param data.parameters Parameters of the output. + * @param data.assetType An asset type of the output. + * @param data.amount An asset amount of the output. + */ constructor(data: AssetTransferOutputData) { const { lockScriptHash, parameters, assetType, amount } = data; this.lockScriptHash = lockScriptHash; @@ -25,6 +33,9 @@ export class AssetTransferOutput { this.amount = amount; } + /** + * Convert to an object for RLP encoding. + */ toEncodeObject() { const { lockScriptHash, parameters, assetType, amount } = this; return [ @@ -35,6 +46,11 @@ export class AssetTransferOutput { ]; } + /** + * Create an AssetTransferOutput from an AssetTransferOutput JSON object. + * @param data An AssetTransferOutput JSON object. + * @returns An AssetTransferOutput. + */ static fromJSON(data: any) { const { lockScriptHash, parameters, assetType, amount } = data; return new this({ @@ -45,6 +61,10 @@ export class AssetTransferOutput { }); } + /** + * Convert to an AssetTransferOutput JSON object. + * @returns An AssetTransferOutput JSON object. + */ toJSON() { const { lockScriptHash, parameters, assetType, amount } = this; return { @@ -55,6 +75,10 @@ export class AssetTransferOutput { }; } + /** + * Get the shard ID. + * @returns A shard ID. + */ shardId(): number { const { assetType } = this; return parseInt(assetType.value.slice(4, 8), 16); diff --git a/src/core/transaction/AssetTransferTransaction.ts b/src/core/transaction/AssetTransferTransaction.ts index 985f131b..a6efaa2a 100644 --- a/src/core/transaction/AssetTransferTransaction.ts +++ b/src/core/transaction/AssetTransferTransaction.ts @@ -27,11 +27,18 @@ export type AssetTransferTransactionData = { /** * Spends the existing asset and creates a new asset. Ownership can be transferred during this process. * - * - AssetTransfer consists of AssetTransferInput's list to spend and AssetTransferOutput's list to create. - * - All inputs must be valid for the transaction to be valid. - * - When each asset types' amount have been summed, the sum of inputs and the sum of outputs must be identical. - * - It contains the network ID. This must be identical to the network ID to which the transaction is being sent to. - * - If an identical transaction hash already exists, then the change fails. In this situation, a transaction can be created again by arbitrarily changing the nonce. + * An AssetTransferTransaction consists of: + * - A list of AssetTransferInput to burn. + * - A list of AssetTransferInput to spend. + * - A list of AssetTransferOutput to create. + * - A network ID. This must be identical to the network ID of which the + * transaction is being sent to. + * + * All inputs must be valid for the transaction to be valid. When each asset + * types' amount have been summed, the sum of inputs and the sum of outputs + * must be identical. If an identical transaction hash already exists, then the + * change fails. In this situation, a transaction can be created again by + * arbitrarily changing the nonce. */ export class AssetTransferTransaction { readonly burns: AssetTransferInput[]; @@ -41,7 +48,15 @@ export class AssetTransferTransaction { readonly nonce: number; readonly type = "assetTransfer"; - constructor({ burns, inputs, outputs, networkId, nonce }: AssetTransferTransactionData) { + /** + * @param params.burns An array of AssetTransferInput to burn. + * @param params.inputs An array of AssetTransferInput to spend. + * @param params.outputs An array of AssetTransferOutput to create. + * @param params.networkId A network ID of the transaction. + * @param params.nonce A nonce of the transaction. + */ + constructor(params: AssetTransferTransactionData) { + const { burns, inputs, outputs, networkId, nonce } = params; this.burns = burns; this.inputs = inputs; this.outputs = outputs; @@ -49,6 +64,9 @@ export class AssetTransferTransaction { this.nonce = nonce || 0; } + /** + * Convert to an object for RLP encoding. + */ toEncodeObject() { return [ 4, @@ -60,14 +78,26 @@ export class AssetTransferTransaction { ]; } + /** + * Convert to RLP bytes. + */ rlpBytes(): Buffer { return RLP.encode(this.toEncodeObject()); } + /** + * Get the hash of an AssetTransferTransaction. + * @returns A transaction hash. + */ hash(): H256 { return new H256(blake256(this.rlpBytes())); } + /** + * Add an AssetTransferInput to burn. + * @param burns An array of either an AssetTransferInput or an Asset. + * @returns The AssetTransferTransaction, which is modified by adding them. + */ addBurns(...burns: (AssetTransferInput | Asset)[]): AssetTransferTransaction { burns.forEach(burn => { if (burn instanceof AssetTransferInput) { @@ -79,6 +109,11 @@ export class AssetTransferTransaction { return this; } + /** + * Add an AssetTransferInput to spend. + * @param inputs An array of either an AssetTransferInput or an Asset. + * @returns The AssetTransferTransaction, which is modified by adding them. + */ addInputs(...inputs: (AssetTransferInput | Asset)[]): AssetTransferTransaction { inputs.forEach(input => { if (input instanceof AssetTransferInput) { @@ -90,6 +125,14 @@ export class AssetTransferTransaction { return this; } + /** + * Add an AssetTransferOutput to create. + * @param outputs An array of either an AssetTransferOutput or an object + * that has amount, assetType and recipient values. + * @param output.amount Asset amount of the output. + * @param output.assetType An asset type of the output. + * @param output.recipient A recipient of the output. + */ addOutputs(...outputs: (AssetTransferOutput | { amount: number, assetType: H256 | string @@ -110,6 +153,11 @@ export class AssetTransferTransaction { return this; } + /** + * Get the output of the given index, of this transaction. + * @param index An index indicating an output. + * @returns An Asset. + */ getTransferredAsset(index: number): Asset { if (index >= this.outputs.length) { throw "invalid output index"; @@ -126,10 +174,19 @@ export class AssetTransferTransaction { }); } + /** + * Get the outputs of this transaction. + * @returns An array of an Asset. + */ getTransferredAssets(): Asset[] { return _.range(this.outputs.length).map(i => this.getTransferredAsset(i)); } + /** + * Get a hash of the transaction that doesn't contain the scripts. The hash + * is used as a message to create a signature for a transaction. + * @returns A hash. + */ hashWithoutScript(): H256 { const { networkId, burns, inputs, outputs, nonce } = this; return new H256(blake256(new AssetTransferTransaction({ @@ -141,6 +198,13 @@ export class AssetTransferTransaction { }).rlpBytes())); } + /** + * Set an input's lock script and an input's unlock script so that the + * input become spendable. + * @param index An index indicating the input to sign. + * @param params.signer A TransactionSigner. Currently, P2PKH is available. + * @returns A promise that resolves when setting is done. + */ async sign(index: number, params: { signer: TransactionSigner }): Promise { const { signer } = params; if (index >= this.inputs.length) { @@ -151,6 +215,11 @@ export class AssetTransferTransaction { this.setUnlockScript(index, unlockScript); } + /** + * Set the input's lock script. + * @param index An index indicating the input. + * @param lockScript A lock script. + */ setLockScript(index: number, lockScript: Buffer): void { if (index < 0 || this.inputs.length <= index) { throw "Invalid index"; @@ -158,6 +227,11 @@ export class AssetTransferTransaction { this.inputs[index].setLockScript(lockScript); } + /** + * Set the input's unlock script. + * @param index An index indicating the input. + * @param unlockScript An unlock script. + */ setUnlockScript(index: number, unlockScript: Buffer): void { if (index < 0 || this.inputs.length <= index) { throw "Invalid index"; @@ -165,6 +239,11 @@ export class AssetTransferTransaction { this.inputs[index].setUnlockScript(unlockScript); } + /** + * Get the asset address of an output. + * @param index An index indicating the output. + * @returns An asset address which is H256. + */ getAssetAddress(index: number): H256 { const iv = new Uint8Array([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -180,6 +259,10 @@ export class AssetTransferTransaction { return new H256(blake.replace(new RegExp(`^.{${prefix.length}}`), prefix)); } + /** Create an AssetTransferTransaction from an AssetTransferTransaction JSON object. + * @param obj An AssetTransferTransaction JSON object. + * @returns An AssetTransferTransaction. + */ static fromJSON(obj: any) { const { data: { networkId, burns, inputs, outputs, nonce } } = obj; return new this({ @@ -191,6 +274,10 @@ export class AssetTransferTransaction { }); } + /** + * Convert to an AssetTransferTransaction JSON object. + * @returns An AssetTransferTransaction JSON object. + */ toJSON() { const { networkId, burns, inputs, outputs, nonce } = this; return { diff --git a/src/core/transaction/Transaction.ts b/src/core/transaction/Transaction.ts index 9fb05812..33e97ab2 100644 --- a/src/core/transaction/Transaction.ts +++ b/src/core/transaction/Transaction.ts @@ -5,13 +5,19 @@ export type Transaction = AssetMintTransaction | AssetTransferTransaction; -export const getTransactionFromJSON = (obj: { type: string, data: object }) => { - const { type } = obj; +/** + * Create a transaction from either an AssetMintTransaction JSON object or an + * AssetTransferTransaction JSON object. + * @param params Either an AssetMintTransaction JSON object or an AssetTransferTransaction JSON object. + * @returns A Transaction. + */ +export const getTransactionFromJSON = (params: { type: string, data: object }) => { + const { type } = params; switch (type) { case "assetMint": - return AssetMintTransaction.fromJSON(obj); + return AssetMintTransaction.fromJSON(params); case "assetTransfer": - return AssetTransferTransaction.fromJSON(obj); + return AssetTransferTransaction.fromJSON(params); default: throw new Error(`Unexpected transaction type: ${type}`); }