mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-22 21:25:49 +00:00
add Issue type and tests for Asset/Asset2
This commit is contained in:
@@ -11,6 +11,7 @@ import { Currency } from './currency'
|
|||||||
import { Hash128 } from './hash-128'
|
import { Hash128 } from './hash-128'
|
||||||
import { Hash160 } from './hash-160'
|
import { Hash160 } from './hash-160'
|
||||||
import { Hash256 } from './hash-256'
|
import { Hash256 } from './hash-256'
|
||||||
|
import { Issue } from './issue'
|
||||||
import { PathSet } from './path-set'
|
import { PathSet } from './path-set'
|
||||||
import { STArray } from './st-array'
|
import { STArray } from './st-array'
|
||||||
import { STObject } from './st-object'
|
import { STObject } from './st-object'
|
||||||
@@ -28,6 +29,7 @@ const coreTypes = {
|
|||||||
Hash128,
|
Hash128,
|
||||||
Hash160,
|
Hash160,
|
||||||
Hash256,
|
Hash256,
|
||||||
|
Issue,
|
||||||
PathSet,
|
PathSet,
|
||||||
STArray,
|
STArray,
|
||||||
STObject,
|
STObject,
|
||||||
|
|||||||
96
packages/ripple-binary-codec/src/types/issue.ts
Normal file
96
packages/ripple-binary-codec/src/types/issue.ts
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
import { BinaryParser } from '../serdes/binary-parser'
|
||||||
|
|
||||||
|
import { AccountID } from './account-id'
|
||||||
|
import { Currency } from './currency'
|
||||||
|
import { JsonObject, SerializedType } from './serialized-type'
|
||||||
|
import { Buffer } from 'buffer/'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for JSON objects that represent amounts
|
||||||
|
*/
|
||||||
|
interface IssueObject extends JsonObject {
|
||||||
|
currency: string
|
||||||
|
issuer?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type guard for AmountObject
|
||||||
|
*/
|
||||||
|
function isIssueObject(arg): arg is IssueObject {
|
||||||
|
const keys = Object.keys(arg).sort()
|
||||||
|
if (keys.length === 1) {
|
||||||
|
return keys[0] === 'currency'
|
||||||
|
}
|
||||||
|
return keys.length === 2 && keys[0] === 'currency' && keys[1] === 'issuer'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for serializing/Deserializing Amounts
|
||||||
|
*/
|
||||||
|
class Issue extends SerializedType {
|
||||||
|
static readonly ZERO_ISSUED_CURRENCY: Issue = new Issue(Buffer.alloc(20))
|
||||||
|
|
||||||
|
constructor(bytes: Buffer) {
|
||||||
|
super(bytes ?? Issue.ZERO_ISSUED_CURRENCY.bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an amount from an IOU or string amount
|
||||||
|
*
|
||||||
|
* @param value An Amount, object representing an IOU, or a string
|
||||||
|
* representing an integer amount
|
||||||
|
* @returns An Amount object
|
||||||
|
*/
|
||||||
|
static from<T extends Issue | IssueObject | string>(value: T): Issue {
|
||||||
|
if (value instanceof Issue) {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isIssueObject(value)) {
|
||||||
|
const currency = Currency.from(value.currency).toBytes()
|
||||||
|
if (value.issuer == null) {
|
||||||
|
return new Issue(currency)
|
||||||
|
}
|
||||||
|
const issuer = AccountID.from(value.issuer).toBytes()
|
||||||
|
return new Issue(Buffer.concat([currency, issuer]))
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('Invalid type to construct an Amount')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read an amount from a BinaryParser
|
||||||
|
*
|
||||||
|
* @param parser BinaryParser to read the Amount from
|
||||||
|
* @returns An Amount object
|
||||||
|
*/
|
||||||
|
static fromParser(parser: BinaryParser): Issue {
|
||||||
|
const currency = parser.read(20)
|
||||||
|
if (new Currency(currency).toJSON() === 'XRP') {
|
||||||
|
return new Issue(currency)
|
||||||
|
}
|
||||||
|
const currencyAndIssuer = [currency, parser.read(20)]
|
||||||
|
return new Issue(Buffer.concat(currencyAndIssuer))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the JSON representation of this Amount
|
||||||
|
*
|
||||||
|
* @returns the JSON interpretation of this.bytes
|
||||||
|
*/
|
||||||
|
toJSON(): IssueObject {
|
||||||
|
const parser = new BinaryParser(this.toString())
|
||||||
|
const currency = Currency.fromParser(parser) as Currency
|
||||||
|
if (currency.toJSON() === 'XRP') {
|
||||||
|
return { currency: currency.toJSON() }
|
||||||
|
}
|
||||||
|
const issuer = AccountID.fromParser(parser) as AccountID
|
||||||
|
|
||||||
|
return {
|
||||||
|
currency: currency.toJSON(),
|
||||||
|
issuer: issuer.toJSON(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Issue, IssueObject }
|
||||||
@@ -1,7 +1,12 @@
|
|||||||
import { ValidationError } from '../../errors'
|
import { ValidationError } from '../../errors'
|
||||||
import { Amount, Issue } from '../common'
|
import { Amount, Issue } from '../common'
|
||||||
|
|
||||||
import { BaseTransaction, isAmount, validateBaseTransaction } from './common'
|
import {
|
||||||
|
BaseTransaction,
|
||||||
|
isAmount,
|
||||||
|
isIssue,
|
||||||
|
validateBaseTransaction,
|
||||||
|
} from './common'
|
||||||
|
|
||||||
const MAX_AUTH_ACCOUNTS = 4
|
const MAX_AUTH_ACCOUNTS = 4
|
||||||
|
|
||||||
@@ -61,6 +66,22 @@ export interface AMMBid extends BaseTransaction {
|
|||||||
export function validateAMMBid(tx: Record<string, unknown>): void {
|
export function validateAMMBid(tx: Record<string, unknown>): void {
|
||||||
validateBaseTransaction(tx)
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
|
if (tx.Asset == null) {
|
||||||
|
throw new ValidationError('AMMBid: missing field Asset')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isIssue(tx.Asset)) {
|
||||||
|
throw new ValidationError('AMMBid: Asset must be an Issue')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx.Asset2 == null) {
|
||||||
|
throw new ValidationError('AMMBid: missing field Asset2')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isIssue(tx.Asset2)) {
|
||||||
|
throw new ValidationError('AMMBid: Asset2 must be an Issue')
|
||||||
|
}
|
||||||
|
|
||||||
if (tx.BidMin != null && !isAmount(tx.BidMin)) {
|
if (tx.BidMin != null && !isAmount(tx.BidMin)) {
|
||||||
throw new ValidationError('AMMBid: BidMin must be an Amount')
|
throw new ValidationError('AMMBid: BidMin must be an Amount')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
BaseTransaction,
|
BaseTransaction,
|
||||||
GlobalFlags,
|
GlobalFlags,
|
||||||
isAmount,
|
isAmount,
|
||||||
|
isIssue,
|
||||||
isIssuedCurrency,
|
isIssuedCurrency,
|
||||||
validateBaseTransaction,
|
validateBaseTransaction,
|
||||||
} from './common'
|
} from './common'
|
||||||
@@ -88,6 +89,22 @@ export interface AMMDeposit extends BaseTransaction {
|
|||||||
export function validateAMMDeposit(tx: Record<string, unknown>): void {
|
export function validateAMMDeposit(tx: Record<string, unknown>): void {
|
||||||
validateBaseTransaction(tx)
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
|
if (tx.Asset == null) {
|
||||||
|
throw new ValidationError('AMMDeposit: missing field Asset')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isIssue(tx.Asset)) {
|
||||||
|
throw new ValidationError('AMMDeposit: Asset must be an Issue')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx.Asset2 == null) {
|
||||||
|
throw new ValidationError('AMMDeposit: missing field Asset2')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isIssue(tx.Asset2)) {
|
||||||
|
throw new ValidationError('AMMDeposit: Asset2 must be an Issue')
|
||||||
|
}
|
||||||
|
|
||||||
if (tx.Amount2 != null && tx.Amount == null) {
|
if (tx.Amount2 != null && tx.Amount == null) {
|
||||||
throw new ValidationError('AMMDeposit: must set Amount with Amount2')
|
throw new ValidationError('AMMDeposit: must set Amount with Amount2')
|
||||||
} else if (tx.EPrice != null && tx.Amount == null) {
|
} else if (tx.EPrice != null && tx.Amount == null) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { ValidationError } from '../../errors'
|
|||||||
import { Issue } from '../common'
|
import { Issue } from '../common'
|
||||||
|
|
||||||
import { AMM_MAX_TRADING_FEE } from './AMMCreate'
|
import { AMM_MAX_TRADING_FEE } from './AMMCreate'
|
||||||
import { BaseTransaction, validateBaseTransaction } from './common'
|
import { BaseTransaction, isIssue, validateBaseTransaction } from './common'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AMMVote is used for submitting a vote for the trading fee of an AMM Instance.
|
* AMMVote is used for submitting a vote for the trading fee of an AMM Instance.
|
||||||
@@ -41,6 +41,22 @@ export interface AMMVote extends BaseTransaction {
|
|||||||
export function validateAMMVote(tx: Record<string, unknown>): void {
|
export function validateAMMVote(tx: Record<string, unknown>): void {
|
||||||
validateBaseTransaction(tx)
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
|
if (tx.Asset == null) {
|
||||||
|
throw new ValidationError('AMMVote: missing field Asset')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isIssue(tx.Asset)) {
|
||||||
|
throw new ValidationError('AMMVote: Asset must be an Issue')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx.Asset2 == null) {
|
||||||
|
throw new ValidationError('AMMVote: missing field Asset2')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isIssue(tx.Asset2)) {
|
||||||
|
throw new ValidationError('AMMVote: Asset2 must be an Issue')
|
||||||
|
}
|
||||||
|
|
||||||
if (tx.TradingFee == null) {
|
if (tx.TradingFee == null) {
|
||||||
throw new ValidationError('AMMVote: missing field TradingFee')
|
throw new ValidationError('AMMVote: missing field TradingFee')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
BaseTransaction,
|
BaseTransaction,
|
||||||
GlobalFlags,
|
GlobalFlags,
|
||||||
isAmount,
|
isAmount,
|
||||||
|
isIssue,
|
||||||
isIssuedCurrency,
|
isIssuedCurrency,
|
||||||
validateBaseTransaction,
|
validateBaseTransaction,
|
||||||
} from './common'
|
} from './common'
|
||||||
@@ -94,6 +95,22 @@ export interface AMMWithdraw extends BaseTransaction {
|
|||||||
export function validateAMMWithdraw(tx: Record<string, unknown>): void {
|
export function validateAMMWithdraw(tx: Record<string, unknown>): void {
|
||||||
validateBaseTransaction(tx)
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
|
if (tx.Asset == null) {
|
||||||
|
throw new ValidationError('AMMWithdraw: missing field Asset')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isIssue(tx.Asset)) {
|
||||||
|
throw new ValidationError('AMMWithdraw: Asset must be an Issue')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx.Asset2 == null) {
|
||||||
|
throw new ValidationError('AMMWithdraw: missing field Asset2')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isIssue(tx.Asset2)) {
|
||||||
|
throw new ValidationError('AMMWithdraw: Asset2 must be an Issue')
|
||||||
|
}
|
||||||
|
|
||||||
if (tx.Amount2 != null && tx.Amount == null) {
|
if (tx.Amount2 != null && tx.Amount == null) {
|
||||||
throw new ValidationError('AMMWithdraw: must set Amount with Amount2')
|
throw new ValidationError('AMMWithdraw: must set Amount with Amount2')
|
||||||
} else if (tx.EPrice != null && tx.Amount == null) {
|
} else if (tx.EPrice != null && tx.Amount == null) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import { TRANSACTION_TYPES } from 'ripple-binary-codec'
|
import { TRANSACTION_TYPES } from 'ripple-binary-codec'
|
||||||
|
|
||||||
import { ValidationError } from '../../errors'
|
import { ValidationError } from '../../errors'
|
||||||
import { Amount, IssuedCurrencyAmount, Memo, Signer } from '../common'
|
import { Amount, Issue, IssuedCurrencyAmount, Memo, Signer } from '../common'
|
||||||
import { onlyHasFields } from '../utils'
|
import { onlyHasFields } from '../utils'
|
||||||
|
|
||||||
const MEMO_SIZE = 3
|
const MEMO_SIZE = 3
|
||||||
@@ -84,6 +84,25 @@ export function isAmount(amount: unknown): amount is Amount {
|
|||||||
return typeof amount === 'string' || isIssuedCurrency(amount)
|
return typeof amount === 'string' || isIssuedCurrency(amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of an Issue at runtime.
|
||||||
|
*
|
||||||
|
* @param input - The object to check the form and type of.
|
||||||
|
* @returns Whether the Issue is malformed.
|
||||||
|
*/
|
||||||
|
export function isIssue(input: unknown): input is Issue {
|
||||||
|
if (!isRecord(input)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const length = Object.keys(input).length
|
||||||
|
return (
|
||||||
|
(length === 1 && input.currency === 'XRP') ||
|
||||||
|
(length === 2 &&
|
||||||
|
typeof input.currency === 'string' &&
|
||||||
|
typeof input.issuer === 'string')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface -- no global flags right now, so this is fine
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface -- no global flags right now, so this is fine
|
||||||
export interface GlobalFlags {}
|
export interface GlobalFlags {}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,13 @@ describe('AMMBid', function () {
|
|||||||
bid = {
|
bid = {
|
||||||
TransactionType: 'AMMBid',
|
TransactionType: 'AMMBid',
|
||||||
Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm',
|
Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm',
|
||||||
|
Asset: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
Asset2: {
|
||||||
|
currency: 'ETH',
|
||||||
|
issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd',
|
||||||
|
},
|
||||||
BidMin: '5',
|
BidMin: '5',
|
||||||
BidMax: '10',
|
BidMax: '10',
|
||||||
AuthAccounts: [
|
AuthAccounts: [
|
||||||
@@ -45,6 +52,42 @@ describe('AMMBid', function () {
|
|||||||
assert.doesNotThrow(() => validate(bid))
|
assert.doesNotThrow(() => validate(bid))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it(`throws w/ missing field Asset`, function () {
|
||||||
|
delete bid.Asset
|
||||||
|
assert.throws(
|
||||||
|
() => validate(bid),
|
||||||
|
ValidationError,
|
||||||
|
'AMMBid: missing field Asset',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it(`throws w/ Asset must be an Issue`, function () {
|
||||||
|
bid.Asset = 1234
|
||||||
|
assert.throws(
|
||||||
|
() => validate(bid),
|
||||||
|
ValidationError,
|
||||||
|
'AMMBid: Asset must be an Issue',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it(`throws w/ missing field Asset2`, function () {
|
||||||
|
delete bid.Asset2
|
||||||
|
assert.throws(
|
||||||
|
() => validate(bid),
|
||||||
|
ValidationError,
|
||||||
|
'AMMBid: missing field Asset2',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it(`throws w/ Asset2 must be an Issue`, function () {
|
||||||
|
bid.Asset2 = 1234
|
||||||
|
assert.throws(
|
||||||
|
() => validate(bid),
|
||||||
|
ValidationError,
|
||||||
|
'AMMBid: Asset2 must be an Issue',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it(`throws w/ BidMin must be an Amount`, function () {
|
it(`throws w/ BidMin must be an Amount`, function () {
|
||||||
bid.BidMin = 5
|
bid.BidMin = 5
|
||||||
assert.throws(
|
assert.throws(
|
||||||
|
|||||||
@@ -19,6 +19,13 @@ describe('AMMDeposit', function () {
|
|||||||
deposit = {
|
deposit = {
|
||||||
TransactionType: 'AMMDeposit',
|
TransactionType: 'AMMDeposit',
|
||||||
Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm',
|
Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm',
|
||||||
|
Asset: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
Asset2: {
|
||||||
|
currency: 'ETH',
|
||||||
|
issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd',
|
||||||
|
},
|
||||||
Sequence: 1337,
|
Sequence: 1337,
|
||||||
Flags: 0,
|
Flags: 0,
|
||||||
} as any
|
} as any
|
||||||
@@ -38,7 +45,11 @@ describe('AMMDeposit', function () {
|
|||||||
|
|
||||||
it(`verifies valid AMMDeposit with Amount and Amount2`, function () {
|
it(`verifies valid AMMDeposit with Amount and Amount2`, function () {
|
||||||
deposit.Amount = '1000'
|
deposit.Amount = '1000'
|
||||||
deposit.Amount2 = '1000'
|
deposit.Amount2 = {
|
||||||
|
currency: 'ETH',
|
||||||
|
issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd',
|
||||||
|
value: '2.5',
|
||||||
|
}
|
||||||
deposit.Flags |= AMMDepositFlags.tfTwoAsset
|
deposit.Flags |= AMMDepositFlags.tfTwoAsset
|
||||||
assert.doesNotThrow(() => validate(deposit))
|
assert.doesNotThrow(() => validate(deposit))
|
||||||
})
|
})
|
||||||
@@ -57,6 +68,42 @@ describe('AMMDeposit', function () {
|
|||||||
assert.doesNotThrow(() => validate(deposit))
|
assert.doesNotThrow(() => validate(deposit))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it(`throws w/ missing field Asset`, function () {
|
||||||
|
delete deposit.Asset
|
||||||
|
assert.throws(
|
||||||
|
() => validate(deposit),
|
||||||
|
ValidationError,
|
||||||
|
'AMMDeposit: missing field Asset',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it(`throws w/ Asset must be an Issue`, function () {
|
||||||
|
deposit.Asset = 1234
|
||||||
|
assert.throws(
|
||||||
|
() => validate(deposit),
|
||||||
|
ValidationError,
|
||||||
|
'AMMDeposit: Asset must be an Issue',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it(`throws w/ missing field Asset2`, function () {
|
||||||
|
delete deposit.Asset2
|
||||||
|
assert.throws(
|
||||||
|
() => validate(deposit),
|
||||||
|
ValidationError,
|
||||||
|
'AMMDeposit: missing field Asset2',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it(`throws w/ Asset2 must be an Issue`, function () {
|
||||||
|
deposit.Asset2 = 1234
|
||||||
|
assert.throws(
|
||||||
|
() => validate(deposit),
|
||||||
|
ValidationError,
|
||||||
|
'AMMDeposit: Asset2 must be an Issue',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it(`throws w/ must set at least LPTokenOut or Amount`, function () {
|
it(`throws w/ must set at least LPTokenOut or Amount`, function () {
|
||||||
assert.throws(
|
assert.throws(
|
||||||
() => validate(deposit),
|
() => validate(deposit),
|
||||||
@@ -66,7 +113,11 @@ describe('AMMDeposit', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it(`throws w/ must set Amount with Amount2`, function () {
|
it(`throws w/ must set Amount with Amount2`, function () {
|
||||||
deposit.Amount2 = '500'
|
deposit.Amount2 = {
|
||||||
|
currency: 'ETH',
|
||||||
|
issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd',
|
||||||
|
value: '2.5',
|
||||||
|
}
|
||||||
assert.throws(
|
assert.throws(
|
||||||
() => validate(deposit),
|
() => validate(deposit),
|
||||||
ValidationError,
|
ValidationError,
|
||||||
|
|||||||
@@ -13,6 +13,13 @@ describe('AMMVote', function () {
|
|||||||
vote = {
|
vote = {
|
||||||
TransactionType: 'AMMVote',
|
TransactionType: 'AMMVote',
|
||||||
Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm',
|
Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm',
|
||||||
|
Asset: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
Asset2: {
|
||||||
|
currency: 'ETH',
|
||||||
|
issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd',
|
||||||
|
},
|
||||||
TradingFee: 25,
|
TradingFee: 25,
|
||||||
Sequence: 1337,
|
Sequence: 1337,
|
||||||
} as any
|
} as any
|
||||||
@@ -22,6 +29,42 @@ describe('AMMVote', function () {
|
|||||||
assert.doesNotThrow(() => validate(vote))
|
assert.doesNotThrow(() => validate(vote))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it(`throws w/ missing field Asset`, function () {
|
||||||
|
delete vote.Asset
|
||||||
|
assert.throws(
|
||||||
|
() => validate(vote),
|
||||||
|
ValidationError,
|
||||||
|
'AMMVote: missing field Asset',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it(`throws w/ Asset must be an Issue`, function () {
|
||||||
|
vote.Asset = 1234
|
||||||
|
assert.throws(
|
||||||
|
() => validate(vote),
|
||||||
|
ValidationError,
|
||||||
|
'AMMVote: Asset must be an Issue',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it(`throws w/ missing field Asset2`, function () {
|
||||||
|
delete vote.Asset2
|
||||||
|
assert.throws(
|
||||||
|
() => validate(vote),
|
||||||
|
ValidationError,
|
||||||
|
'AMMVote: missing field Asset2',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it(`throws w/ Asset2 must be an Issue`, function () {
|
||||||
|
vote.Asset2 = 1234
|
||||||
|
assert.throws(
|
||||||
|
() => validate(vote),
|
||||||
|
ValidationError,
|
||||||
|
'AMMVote: Asset2 must be an Issue',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it(`throws w/ missing field TradingFee`, function () {
|
it(`throws w/ missing field TradingFee`, function () {
|
||||||
delete vote.TradingFee
|
delete vote.TradingFee
|
||||||
assert.throws(
|
assert.throws(
|
||||||
|
|||||||
@@ -19,6 +19,13 @@ describe('AMMWithdraw', function () {
|
|||||||
withdraw = {
|
withdraw = {
|
||||||
TransactionType: 'AMMWithdraw',
|
TransactionType: 'AMMWithdraw',
|
||||||
Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm',
|
Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm',
|
||||||
|
Asset: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
Asset2: {
|
||||||
|
currency: 'ETH',
|
||||||
|
issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd',
|
||||||
|
},
|
||||||
Sequence: 1337,
|
Sequence: 1337,
|
||||||
Flags: 0,
|
Flags: 0,
|
||||||
} as any
|
} as any
|
||||||
@@ -37,7 +44,11 @@ describe('AMMWithdraw', function () {
|
|||||||
|
|
||||||
it(`verifies valid AMMWithdraw with Amount and Amount2`, function () {
|
it(`verifies valid AMMWithdraw with Amount and Amount2`, function () {
|
||||||
withdraw.Amount = '1000'
|
withdraw.Amount = '1000'
|
||||||
withdraw.Amount2 = '1000'
|
withdraw.Amount2 = {
|
||||||
|
currency: 'ETH',
|
||||||
|
issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd',
|
||||||
|
value: '2.5',
|
||||||
|
}
|
||||||
assert.doesNotThrow(() => validate(withdraw))
|
assert.doesNotThrow(() => validate(withdraw))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -53,6 +64,42 @@ describe('AMMWithdraw', function () {
|
|||||||
assert.doesNotThrow(() => validate(withdraw))
|
assert.doesNotThrow(() => validate(withdraw))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it(`throws w/ missing field Asset`, function () {
|
||||||
|
delete withdraw.Asset
|
||||||
|
assert.throws(
|
||||||
|
() => validate(withdraw),
|
||||||
|
ValidationError,
|
||||||
|
'AMMWithdraw: missing field Asset',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it(`throws w/ Asset must be an Issue`, function () {
|
||||||
|
withdraw.Asset = 1234
|
||||||
|
assert.throws(
|
||||||
|
() => validate(withdraw),
|
||||||
|
ValidationError,
|
||||||
|
'AMMWithdraw: Asset must be an Issue',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it(`throws w/ missing field Asset2`, function () {
|
||||||
|
delete withdraw.Asset2
|
||||||
|
assert.throws(
|
||||||
|
() => validate(withdraw),
|
||||||
|
ValidationError,
|
||||||
|
'AMMWithdraw: missing field Asset2',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it(`throws w/ Asset2 must be an Issue`, function () {
|
||||||
|
withdraw.Asset2 = 1234
|
||||||
|
assert.throws(
|
||||||
|
() => validate(withdraw),
|
||||||
|
ValidationError,
|
||||||
|
'AMMWithdraw: Asset2 must be an Issue',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it(`throws w/ must set at least LPTokenIn or Amount`, function () {
|
it(`throws w/ must set at least LPTokenIn or Amount`, function () {
|
||||||
assert.throws(
|
assert.throws(
|
||||||
() => validate(withdraw),
|
() => validate(withdraw),
|
||||||
@@ -62,7 +109,11 @@ describe('AMMWithdraw', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it(`throws w/ must set Amount with Amount2`, function () {
|
it(`throws w/ must set Amount with Amount2`, function () {
|
||||||
withdraw.Amount2 = '500'
|
withdraw.Amount2 = {
|
||||||
|
currency: 'ETH',
|
||||||
|
issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd',
|
||||||
|
value: '2.5',
|
||||||
|
}
|
||||||
assert.throws(
|
assert.throws(
|
||||||
() => validate(withdraw),
|
() => validate(withdraw),
|
||||||
ValidationError,
|
ValidationError,
|
||||||
|
|||||||
Reference in New Issue
Block a user