diff --git a/src/models/transactions/escrowCreate.ts b/src/models/transactions/escrowCreate.ts new file mode 100644 index 00000000..10c5038d --- /dev/null +++ b/src/models/transactions/escrowCreate.ts @@ -0,0 +1,53 @@ +import { ValidationError } from "../../common/errors" +import { BaseTransaction, verifyBaseTransaction } from "./common" + +export interface EscrowCreate extends BaseTransaction { + TransactionType: "EscrowCreate" + Amount: string + Destination: string + CancelAfter?: number + FinishAfter?: number + Condition?: string + DestinationTag?: number +} + +/** + * Verify the form and type of an EscrowCreate at runtime. + * + * @param tx - An EscrowCreate Transaction + * @returns - Void. + * @throws - When the EscrowCreate is Malformed. + */ + export function verifyEscrowCreate(tx: EscrowCreate): void { + verifyBaseTransaction(tx) + + if (tx.Amount === undefined) + throw new ValidationError("EscrowCreate: missing field Amount") + + if (typeof tx.Amount !== 'string') + throw new ValidationError("EscrowCreate: Amount must be a string") + + if (tx.Destination === undefined) + throw new ValidationError("EscrowCreate: missing field Destination") + + if (typeof tx.Destination !== 'string') + throw new ValidationError("EscrowCreate: Destination must be a string") + + if (tx.CancelAfter === undefined && tx.FinishAfter === undefined) + throw new ValidationError("EscrowCreate: Either CancelAfter or FinishAfter must be specified") + + if (tx.FinishAfter === undefined && tx.Condition === undefined) + throw new ValidationError("EscrowCreate: Either Condition or FinishAfter must be specified") + + if (tx.CancelAfter !== undefined && typeof tx.CancelAfter !== 'number') + throw new ValidationError("EscrowCreate: CancelAfter must be a number") + + if (tx.FinishAfter !== undefined && typeof tx.FinishAfter !== 'number') + throw new ValidationError("EscrowCreate: FinishAfter must be a number") + + if (tx.Condition !== undefined && typeof tx.Condition !== 'string') + throw new ValidationError("EscrowCreate: Condition must be a string") + + if (tx.DestinationTag !== undefined && typeof tx.DestinationTag !== 'number') + throw new ValidationError("EscrowCreate: DestinationTag must be a number") +} \ No newline at end of file diff --git a/src/models/transactions/index.ts b/src/models/transactions/index.ts index c8225f8e..866eb34b 100644 --- a/src/models/transactions/index.ts +++ b/src/models/transactions/index.ts @@ -4,10 +4,9 @@ export * from './accountDelete' export * from './checkCancel' export * from './checkCash' export * from './checkCreate' -export * from './signerListSet' -export * from './ticketCreate' export * from './depositPreauth' export * from './escrowCancel' +export * from './escrowCreate' export * from './escrowFinish' export * from './offerCancel' export * from './offerCreate' @@ -15,4 +14,5 @@ export * from './paymentTransaction' export * from './paymentChannelClaim' export * from './paymentChannelCreate' export * from './signerListSet' +export * from './ticketCreate' export * from './trustSet' diff --git a/src/models/transactions/transaction.ts b/src/models/transactions/transaction.ts index 69097c58..8907a227 100644 --- a/src/models/transactions/transaction.ts +++ b/src/models/transactions/transaction.ts @@ -5,6 +5,7 @@ import { CheckCancel } from "./checkCancel"; import { CheckCash } from "./checkCash"; import { CheckCreate } from "./checkCreate"; import { DepositPreauth } from "./depositPreauth" +import { EscrowCreate } from "./escrowCreate" import { EscrowCancel } from './escrowCancel' import { EscrowFinish } from "./escrowFinish" import { OfferCancel } from "./offerCancel" @@ -24,7 +25,7 @@ export type Transaction = | CheckCreate | DepositPreauth | EscrowCancel -// | EscrowCreate + | EscrowCreate | EscrowFinish | OfferCancel | OfferCreate diff --git a/test/models/escrowCreate.ts b/test/models/escrowCreate.ts new file mode 100644 index 00000000..3ad4d3d5 --- /dev/null +++ b/test/models/escrowCreate.ts @@ -0,0 +1,132 @@ +import { ValidationError } from 'xrpl-local/common/errors' +import { verifyEscrowCreate } from './../../src/models/transactions/escrowCreate' +import { assert } from 'chai' + +/** + * EscrowCreate Transaction Verification Testing + * + * Providing runtime verification testing for each specific transaction type + */ +describe('EscrowCreate Transaction Verification', function () { + let escrow + + beforeEach(() => { + escrow = { + Account: "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn", + TransactionType: "EscrowCreate", + Amount: "10000", + Destination: "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW", + CancelAfter: 533257958, + FinishAfter: 533171558, + Condition: "A0258020E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855810100", + DestinationTag: 23480, + SourceTag: 11747 + } + }) + + it (`verifies valid EscrowCreate`, () => { + assert.doesNotThrow(() => verifyEscrowCreate(escrow)) + }) + + it (`Missing amount`, () => { + delete escrow.Amount + + assert.throws( + () => verifyEscrowCreate(escrow), + ValidationError, + "EscrowCreate: missing field Amount" + ) + }) + + it (`Missing destination`, () => { + delete escrow.Destination + + assert.throws( + () => verifyEscrowCreate(escrow), + ValidationError, + "EscrowCreate: missing field Destination" + ) + }) + + it (`throws w/ invalid Destination`, () => { + escrow.Destination = 10 + + assert.throws( + () => verifyEscrowCreate(escrow), + ValidationError, + "EscrowCreate: Destination must be a string" + ) + }) + + it (`throws w/ invalid Amount`, () => { + escrow.Amount = 1000 + + assert.throws( + () => verifyEscrowCreate(escrow), + ValidationError, + "EscrowCreate: Amount must be a string" + ) + }) + + it (`invalid CancelAfter`, () => { + escrow.CancelAfter = "100" + + assert.throws( + () => verifyEscrowCreate(escrow), + ValidationError, + "EscrowCreate: CancelAfter must be a number" + ) + }) + + it (`invalid FinishAfter`, () => { + escrow.FinishAfter = "1000" + + assert.throws( + () => verifyEscrowCreate(escrow), + ValidationError, + "EscrowCreate: FinishAfter must be a number" + ) + }) + + it (`invalid Condition`, () => { + escrow.Condition = 0x141243 + + assert.throws( + () => verifyEscrowCreate(escrow), + ValidationError, + "EscrowCreate: Condition must be a string" + ) + }) + + it (`invalid DestinationTag`, () => { + escrow.DestinationTag = "100" + + assert.throws( + () => verifyEscrowCreate(escrow), + ValidationError, + "EscrowCreate: DestinationTag must be a number" + ) + }) + + it (`Missing both CancelAfter and FinishAfter`, () => { + delete escrow.CancelAfter + delete escrow.FinishAfter + + assert.throws( + () => verifyEscrowCreate(escrow), + ValidationError, + "EscrowCreate: Either CancelAfter or FinishAfter must be specified" + ) + }) + + it (`Missing both Condition and FinishAfter`, () => { + delete escrow.Condition + delete escrow.FinishAfter + + assert.throws( + () => verifyEscrowCreate(escrow), + ValidationError, + "EscrowCreate: Either Condition or FinishAfter must be specified" + ) + }) +}) \ No newline at end of file