From b794f909ad1967b01d71145f0cc6e999840ceba9 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Fri, 19 Aug 2022 17:18:46 -0400 Subject: [PATCH] add AMMVote --- .../xrpl/src/models/transactions/AMMVote.ts | 55 ++++++++++++ .../xrpl/src/models/transactions/index.ts | 1 + .../src/models/transactions/transaction.ts | 6 ++ packages/xrpl/test/models/AMMVote.ts | 83 +++++++++++++++++++ 4 files changed, 145 insertions(+) create mode 100644 packages/xrpl/src/models/transactions/AMMVote.ts create mode 100644 packages/xrpl/test/models/AMMVote.ts diff --git a/packages/xrpl/src/models/transactions/AMMVote.ts b/packages/xrpl/src/models/transactions/AMMVote.ts new file mode 100644 index 00000000..d1d73720 --- /dev/null +++ b/packages/xrpl/src/models/transactions/AMMVote.ts @@ -0,0 +1,55 @@ +import { ValidationError } from '../../errors' + +import { + BaseTransaction, + validateBaseTransaction, +} from './common' + +/** + * AMMVote is used for submitting a vote for the trading fee of an AMM Instance. + * + * Any XRPL account that holds LPToken for an AMM instance may submit this + * transaction to vote for the trading fee for that instance. + */ +export interface AMMVote extends BaseTransaction { + TransactionType: 'AMMVote' + + /** + * A hash that uniquely identifies the AMM instance. This field is required. + */ + AMMID: string + + /** + * Specifies the fee, in basis point. + * Valid values for this field are between 0 and 65000 inclusive. + * A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee + * between 0% and 65%. This field is required. + */ + FeeVal: number +} + +/** + * Verify the form and type of an AMMVote at runtime. + * + * @param tx - An AMMVote Transaction. + * @throws When the AMMVote is Malformed. + */ +export function validateAMMVote(tx: Record): void { + validateBaseTransaction(tx) + + if (tx.AMMID == null) { + throw new ValidationError('AMMVote: missing field AMMID') + } + + if (typeof tx.AMMID !== 'string') { + throw new ValidationError('AMMVote: AMMID must be a string') + } + + if (tx.FeeVal == null) { + throw new ValidationError('AMMVote: missing field FeeVal') + } + + if (typeof tx.FeeVal !== 'number') { + throw new ValidationError('AMMVote: FeeVal must be a number') + } +} diff --git a/packages/xrpl/src/models/transactions/index.ts b/packages/xrpl/src/models/transactions/index.ts index 2fc23622..a6ebf054 100644 --- a/packages/xrpl/src/models/transactions/index.ts +++ b/packages/xrpl/src/models/transactions/index.ts @@ -9,6 +9,7 @@ export { export { AccountDelete } from './accountDelete' export { AMMDeposit } from './AMMDeposit' export { AMMInstanceCreate } from './AMMInstanceCreate' +export { AMMVote } from './AMMVote' export { AMMWithdraw } from './AMMWithdraw' export { CheckCancel } from './checkCancel' export { CheckCash } from './checkCash' diff --git a/packages/xrpl/src/models/transactions/transaction.ts b/packages/xrpl/src/models/transactions/transaction.ts index 06a70323..d17a800a 100644 --- a/packages/xrpl/src/models/transactions/transaction.ts +++ b/packages/xrpl/src/models/transactions/transaction.ts @@ -14,6 +14,7 @@ import { AMMInstanceCreate, validateAMMInstanceCreate, } from './AMMInstanceCreate' +import { AMMVote, validateAMMVote } from './AMMVote' import { AMMWithdraw, validateAMMWithdraw } from './AMMWithdraw' import { CheckCancel, validateCheckCancel } from './checkCancel' import { CheckCash, validateCheckCash } from './checkCash' @@ -65,6 +66,7 @@ export type Transaction = | AccountSet | AMMDeposit | AMMInstanceCreate + | AMMVote | AMMWithdraw | CheckCancel | CheckCash @@ -132,6 +134,10 @@ export function validate(transaction: Record): void { validateAMMInstanceCreate(tx) break + case 'AMMVote': + validateAMMVote(tx) + break + case 'AMMWithdraw': validateAMMWithdraw(tx) break diff --git a/packages/xrpl/test/models/AMMVote.ts b/packages/xrpl/test/models/AMMVote.ts new file mode 100644 index 00000000..b704c349 --- /dev/null +++ b/packages/xrpl/test/models/AMMVote.ts @@ -0,0 +1,83 @@ +import { assert } from 'chai' +import { validate, ValidationError } from 'xrpl-local' + +/** + * AMMVote Transaction Verification Testing. + * + * Providing runtime verification testing for each specific transaction type. + */ +describe('AMMVote', function () { + it(`verifies valid AMMVote`, function () { + const validTx = { + TransactionType: 'AMMVote', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + FeeVal: 25, + Sequence: 1337, + } as any + + assert.doesNotThrow(() => validate(validTx)) + }) + + it(`throws w/ missing field AMMID`, function () { + const invalid = { + TransactionType: 'AMMVote', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + FeeVal: 25, + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMVote: missing field AMMID', + ) + }) + + it(`throws w/ AMMID must be a string`, function () { + const invalid = { + TransactionType: 'AMMVote', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: 1234, + FeeVal: 25, + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMVote: AMMID must be a string', + ) + }) + + it(`throws w/ missing field FeeVal`, function () { + const invalid = { + TransactionType: 'AMMVote', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMVote: missing field FeeVal', + ) + }) + + it(`throws w/ FeeVal must be a number`, function () { + const invalid = { + TransactionType: 'AMMVote', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + FeeVal: '25', + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMVote: FeeVal must be a number', + ) + }) +})