From 25bdb692cbae830526aecfabe6e24a9bed61e35c Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 16 Aug 2022 14:57:07 -0400 Subject: [PATCH 01/61] update definitions.json --- .../src/enums/definitions.json | 319 +++++++++++++++++- 1 file changed, 318 insertions(+), 1 deletion(-) diff --git a/packages/ripple-binary-codec/src/enums/definitions.json b/packages/ripple-binary-codec/src/enums/definitions.json index 317e1feb..605dd2a2 100644 --- a/packages/ripple-binary-codec/src/enums/definitions.json +++ b/packages/ripple-binary-codec/src/enums/definitions.json @@ -44,6 +44,7 @@ "NegativeUNL": 78, "NFTokenPage": 80, "NFTokenOffer": 55, + "Amm": 121, "Any": -3, "Child": -2, "Nickname": 110, @@ -271,6 +272,16 @@ "type": "UInt16" } ], + [ + "TradingFee", + { + "nth": 5, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt16" + } + ], [ "Version", { @@ -761,6 +772,46 @@ "type": "UInt32" } ], + [ + "FeeVal", + { + "nth": 47, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "VoteWeight", + { + "nth": 48, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "TimeStamp", + { + "nth": 49, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], + [ + "DiscountedFee", + { + "nth": 50, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "UInt32" + } + ], [ "IndexNext", { @@ -981,6 +1032,26 @@ "type": "Hash160" } ], + [ + "TokenCurrency", + { + "nth": 5, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Hash160" + } + ], + [ + "TokenIssuer", + { + "nth": 6, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Hash160" + } + ], [ "LedgerHash", { @@ -1111,6 +1182,16 @@ "type": "Hash256" } ], + [ + "AMMID", + { + "nth": 14, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Hash256" + } + ], [ "BookDirectory", { @@ -1381,6 +1462,46 @@ "type": "Amount" } ], + [ + "Asset1", + { + "nth": 11, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "Asset2", + { + "nth": 12, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "MinSlotPrice", + { + "nth": 13, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "MaxSlotPrice", + { + "nth": 14, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], [ "MinimumOffer", { @@ -1421,6 +1542,86 @@ "type": "Amount" } ], + [ + "Asset1In", + { + "nth": 20, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "Asset2In", + { + "nth": 21, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "Asset1Out", + { + "nth": 22, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "Asset2Out", + { + "nth": 23, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "LPTokens", + { + "nth": 24, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "EPrice", + { + "nth": 25, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "Price", + { + "nth": 26, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], + [ + "LPTokenBalance", + { + "nth": 27, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Amount" + } + ], [ "PublicKey", { @@ -1751,6 +1952,16 @@ "type": "AccountID" } ], + [ + "AMMAccount", + { + "nth": 11, + "isVLEncoded": true, + "isSerialized": true, + "isSigningField": true, + "type": "AccountID" + } + ], [ "HookAccount", { @@ -1941,6 +2152,16 @@ "type": "STObject" } ], + [ + "AMM", + { + "nth": 15, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], [ "Signer", { @@ -2021,6 +2242,66 @@ "type": "STObject" } ], + [ + "VoteEntry", + { + "nth": 25, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], + [ + "AuctionSlot", + { + "nth": 27, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], + [ + "AuthAccount", + { + "nth": 28, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], + [ + "AMMToken", + { + "nth": 29, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], + [ + "Token1", + { + "nth": 30, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], + [ + "Token2", + { + "nth": 31, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STObject" + } + ], [ "Signers", { @@ -2111,6 +2392,26 @@ "type": "STArray" } ], + [ + "VoteSlots", + { + "nth": 14, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STArray" + } + ], + [ + "AuthAccounts", + { + "nth": 21, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STArray" + } + ], [ "Majorities", { @@ -2215,6 +2516,8 @@ "temUNKNOWN": -264, "temSEQ_AND_TICKET": -263, "temBAD_NFTOKEN_TRANSFER_FEE": -262, + "temBAD_AMM_OPTIONS": -261, + "temBAD_AMM_TOKENS": -260, "tefFAILURE": -199, "tefALREADY": -198, @@ -2298,7 +2601,16 @@ "tecCANT_ACCEPT_OWN_NFTOKEN_OFFER": 158, "tecINSUFFICIENT_FUNDS": 159, "tecOBJECT_NOT_FOUND": 160, - "tecINSUFFICIENT_PAYMENT": 161 + "tecINSUFFICIENT_PAYMENT": 161, + "tecUNFUNDED_AMM": 162, + "tecAMM_BALANCE": 163, + "tecAMM_FAILED_DEPOSIT": 164, + "tecAMM_FAILED_WITHDRAW": 165, + "tecAMM_INVALID_TOKENS": 166, + "tecAMM_EXISTS": 167, + "tecAMM_FAILED_BID": 168, + "tecAMM_DIRECT_PAYMENT": 169, + "tecAMM_FAILED_VOTE": 170 }, "TRANSACTION_TYPES": { "Invalid": -1, @@ -2330,6 +2642,11 @@ "NFTokenCreateOffer": 27, "NFTokenCancelOffer": 28, "NFTokenAcceptOffer": 29, + "AMMInstanceCreate": 35, + "AMMDeposit": 36, + "AMMWithdraw": 37, + "AMMVote": 38, + "AMMBid": 39, "EnableAmendment": 100, "SetFee": 101, "UNLModify": 102 From 2680c34689b34a3dc4f93b4046de18d9115e3321 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 17 Aug 2022 22:38:31 -0400 Subject: [PATCH 02/61] add AMMInstanceCreate --- .../models/transactions/AMMInstanceCreate.ts | 76 ++++++++ .../xrpl/src/models/transactions/index.ts | 1 + .../src/models/transactions/transaction.ts | 9 + .../xrpl/test/models/AMMInstanceCreate.ts | 166 ++++++++++++++++++ 4 files changed, 252 insertions(+) create mode 100644 packages/xrpl/src/models/transactions/AMMInstanceCreate.ts create mode 100644 packages/xrpl/test/models/AMMInstanceCreate.ts diff --git a/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts b/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts new file mode 100644 index 00000000..5ffec4d6 --- /dev/null +++ b/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts @@ -0,0 +1,76 @@ +import { ValidationError } from '../../errors' +import { Amount } from '../common' + +import { BaseTransaction, isAmount, validateBaseTransaction } from './common' + +const MAX_TRADING_FEE: number = 65000 + +/** + * AMMInstanceCreate is used to create AccountRoot and the corresponding + * AMM ledger entries. + * + * This allows for the creation of only one AMM instance per unique asset pair. + */ +export interface AMMInstanceCreate extends BaseTransaction { + TransactionType: 'AMMInstanceCreate' + + /** + * Specifies one of the pool assets (XRP or token) of the AMM instance. + */ + Asset1: Amount + + /** + * Specifies the other pool asset of the AMM instance. + */ + Asset2: Amount + + /** + * Specifies the fee, in basis point, to be charged + * to the traders for the trades executed against the AMM instance. + * Trading fee is a percentage of the trading volume. + * 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%. + */ + TradingFee: number +} + +/** + * Verify the form and type of an AMMInstanceCreate at runtime. + * + * @param tx - An AMMInstanceCreate Transaction. + * @throws When the AMMInstanceCreate is Malformed. + */ +export function validateAMMInstanceCreate(tx: Record): void { + validateBaseTransaction(tx) + + if (tx.Asset1 === undefined) { + throw new ValidationError('AMMInstanceCreate: missing field Asset1') + } + + if (!isAmount(tx.Asset1)) { + throw new ValidationError('AMMInstanceCreate: Asset1 must be an Amount') + } + + if (tx.Asset2 === undefined) { + throw new ValidationError('AMMInstanceCreate: missing field Asset2') + } + + if (!isAmount(tx.Asset2)) { + throw new ValidationError('AMMInstanceCreate: Asset2 must be an Amount') + } + + if (tx.TradingFee === undefined) { + throw new ValidationError('AMMInstanceCreate: missing field TradingFee') + } + + if (typeof tx.TradingFee !== 'number') { + throw new ValidationError('AMMInstanceCreate: TradingFee must be a number') + } + + if (tx.TradingFee > MAX_TRADING_FEE) { + throw new ValidationError( + `AMMInstanceCreate: TradingFee must not be greater than ${MAX_TRADING_FEE}`, + ) + } +} diff --git a/packages/xrpl/src/models/transactions/index.ts b/packages/xrpl/src/models/transactions/index.ts index 49944424..e8d20b62 100644 --- a/packages/xrpl/src/models/transactions/index.ts +++ b/packages/xrpl/src/models/transactions/index.ts @@ -7,6 +7,7 @@ export { AccountSet, } from './accountSet' export { AccountDelete } from './accountDelete' +export { AMMInstanceCreate } from './AMMInstanceCreate' export { CheckCancel } from './checkCancel' export { CheckCash } from './checkCash' export { CheckCreate } from './checkCreate' diff --git a/packages/xrpl/src/models/transactions/transaction.ts b/packages/xrpl/src/models/transactions/transaction.ts index e5a26b8f..16bd4de4 100644 --- a/packages/xrpl/src/models/transactions/transaction.ts +++ b/packages/xrpl/src/models/transactions/transaction.ts @@ -9,6 +9,10 @@ import { setTransactionFlagsToNumber } from '../utils/flags' import { AccountDelete, validateAccountDelete } from './accountDelete' import { AccountSet, validateAccountSet } from './accountSet' +import { + AMMInstanceCreate, + validateAMMInstanceCreate, +} from './AMMInstanceCreate' import { CheckCancel, validateCheckCancel } from './checkCancel' import { CheckCash, validateCheckCash } from './checkCash' import { CheckCreate, validateCheckCreate } from './checkCreate' @@ -57,6 +61,7 @@ import { TrustSet, validateTrustSet } from './trustSet' export type Transaction = | AccountDelete | AccountSet + | AMMInstanceCreate | CheckCancel | CheckCash | CheckCreate @@ -115,6 +120,10 @@ export function validate(transaction: Record): void { validateAccountSet(tx) break + case 'AMMInstanceCreate': + validateAMMInstanceCreate(tx) + break + case 'CheckCancel': validateCheckCancel(tx) break diff --git a/packages/xrpl/test/models/AMMInstanceCreate.ts b/packages/xrpl/test/models/AMMInstanceCreate.ts new file mode 100644 index 00000000..6e9fbde6 --- /dev/null +++ b/packages/xrpl/test/models/AMMInstanceCreate.ts @@ -0,0 +1,166 @@ +import { assert } from 'chai' +import { validate, ValidationError } from 'xrpl-local' + +/** + * NFTokenMint Transaction Verification Testing. + * + * Providing runtime verification testing for each specific transaction type. + */ +describe('AMMInstanceCreate', function () { + it(`verifies valid AMMInstanceCreate`, function () { + const validTx = { + TransactionType: 'AMMInstanceCreate', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset1: '1000', + Asset2: { + currency: 'USD', + issuer: 'rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9', + value: '1000', + }, + TradingFee: 12, + Sequence: 1337, + } as any + + assert.doesNotThrow(() => validate(validTx)) + }) + + it(`throws w/ missing Asset1`, function () { + const invalid = { + TransactionType: 'AMMInstanceCreate', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset2: { + currency: 'USD', + issuer: 'rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9', + value: '1000', + }, + TradingFee: 12, + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMInstanceCreate: missing field Asset1', + ) + }) + + it(`throws w/ Asset1 must be an Amount`, function () { + const invalidAsset1 = 1000 + const invalidTx = { + TransactionType: 'AMMInstanceCreate', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset1: invalidAsset1, + Asset2: { + currency: 'USD', + issuer: 'rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9', + value: '1000', + }, + TradingFee: 12, + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalidTx), + ValidationError, + 'AMMInstanceCreate: Asset1 must be an Amount', + ) + }) + + it(`throws w/ missing Asset2`, function () { + const invalid = { + TransactionType: 'AMMInstanceCreate', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset1: '1000', + TradingFee: 12, + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMInstanceCreate: missing field Asset2', + ) + }) + + it(`throws w/ Asset2 must be an Amount`, function () { + const invalidAsset2 = 1000 + const invalidTx = { + TransactionType: 'AMMInstanceCreate', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset1: '1000', + Asset2: invalidAsset2, + TradingFee: 12, + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalidTx), + ValidationError, + 'AMMInstanceCreate: Asset2 must be an Amount', + ) + }) + + it(`throws w/ missing TradingFee`, function () { + const invalid = { + TransactionType: 'AMMInstanceCreate', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset1: '1000', + Asset2: { + currency: 'USD', + issuer: 'rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9', + value: '1000', + }, + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMInstanceCreate: missing field TradingFee', + ) + }) + + it(`throws w/ TradingFee must be a number`, function () { + const invalidTradingFee = '12' + const invalidTx = { + TransactionType: 'AMMInstanceCreate', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset1: '1000', + Asset2: { + currency: 'USD', + issuer: 'rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9', + value: '1000', + }, + TradingFee: invalidTradingFee, + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalidTx), + ValidationError, + 'AMMInstanceCreate: TradingFee must be a number', + ) + }) + + it(`throws w/ TradingFee must not be greater than 65000`, function () { + const invalidTradingFee = 65001 + const invalidTx = { + TransactionType: 'AMMInstanceCreate', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset1: '1000', + Asset2: { + currency: 'USD', + issuer: 'rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9', + value: '1000', + }, + TradingFee: invalidTradingFee, + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalidTx), + ValidationError, + `AMMInstanceCreate: TradingFee must not be greater than 65000`, + ) + }) +}) From 6bcfc2be3236157c6fc5d37f3381cd5bc382ba08 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 18 Aug 2022 13:38:44 -0400 Subject: [PATCH 03/61] renamed LPTokens to LPToken in definitions.json --- packages/ripple-binary-codec/src/enums/definitions.json | 2 +- packages/xrpl/src/models/transactions/AMMInstanceCreate.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ripple-binary-codec/src/enums/definitions.json b/packages/ripple-binary-codec/src/enums/definitions.json index 605dd2a2..ce449a51 100644 --- a/packages/ripple-binary-codec/src/enums/definitions.json +++ b/packages/ripple-binary-codec/src/enums/definitions.json @@ -1583,7 +1583,7 @@ } ], [ - "LPTokens", + "LPToken", { "nth": 24, "isVLEncoded": false, diff --git a/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts b/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts index 5ffec4d6..637f9c25 100644 --- a/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts +++ b/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts @@ -3,7 +3,7 @@ import { Amount } from '../common' import { BaseTransaction, isAmount, validateBaseTransaction } from './common' -const MAX_TRADING_FEE: number = 65000 +const MAX_TRADING_FEE = 65000 /** * AMMInstanceCreate is used to create AccountRoot and the corresponding From ff60b547e3097a4495657540245c9198824146a5 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 18 Aug 2022 14:14:30 -0400 Subject: [PATCH 04/61] update HISTORY.md --- packages/xrpl/HISTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/xrpl/HISTORY.md b/packages/xrpl/HISTORY.md index 98bd07c2..1ee6990e 100644 --- a/packages/xrpl/HISTORY.md +++ b/packages/xrpl/HISTORY.md @@ -8,6 +8,9 @@ Subscribe to [the **xrpl-announce** mailing list](https://groups.google.com/g/xr * `Wallet.fromMnemonic` detects when an invalid encoding is provided, and throws an error * Made unexpected errors in `submitAndWait` more verbose to make them easier to debug. +### Added +* Support for Automated Market Maker (AMM). + ## 2.3.1 (2022-06-27) ### Fixed * Signing tx with standard currency codes with lowercase and allowed symbols causing an error on decode. From 3461fcc929f1c4a79a4960dfe8e0dbbd8d58f9bf Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 18 Aug 2022 16:00:25 -0400 Subject: [PATCH 05/61] add amm_info RPC command --- packages/xrpl/src/client/index.ts | 4 + packages/xrpl/src/models/methods/ammInfo.ts | 81 +++++++++++++++++++++ packages/xrpl/src/models/methods/index.ts | 5 ++ 3 files changed, 90 insertions(+) create mode 100644 packages/xrpl/src/models/methods/ammInfo.ts diff --git a/packages/xrpl/src/client/index.ts b/packages/xrpl/src/client/index.ts index ef64d8c5..9dd00f81 100644 --- a/packages/xrpl/src/client/index.ts +++ b/packages/xrpl/src/client/index.ts @@ -24,6 +24,9 @@ import { AccountOffersResponse, AccountTxRequest, AccountTxResponse, + // AMM methods + AMMInfoRequest, + AMMInfoResponse, GatewayBalancesRequest, GatewayBalancesResponse, NoRippleCheckRequest, @@ -298,6 +301,7 @@ class Client extends EventEmitter { ): Promise public async request(r: AccountOffersRequest): Promise public async request(r: AccountTxRequest): Promise + public async request(r: AMMInfoRequest): Promise public async request(r: BookOffersRequest): Promise public async request(r: ChannelVerifyRequest): Promise public async request( diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts new file mode 100644 index 00000000..afb58e0a --- /dev/null +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -0,0 +1,81 @@ +import { Amount, IssuedCurrencyAmount } from '../common' + +import { BaseRequest, BaseResponse } from './baseMethod' + +/** + * The `amm_info` command retrieves information about an AMM instance. + * Returns an {@link AMMInfoResponse}. + * + * @category Requests + */ +export interface AMMInfoRequest extends BaseRequest { + command: 'amm_info' + + /** + * A hash that uniquely identifies the AMM instance. + */ + amm_id?: string + + /** + * Specifies one of the pool assets (XRP or token) of the AMM instance. + */ + asset1?: Amount + + /** + * Specifies the other pool asset of the AMM instance. + */ + asset2?: Amount +} + +/** + * Response expected from an {@link AMMInfoRequest}. + * + * @category Responses + */ +export interface AMMInfoResponse extends BaseResponse { + result: { + /** + * The account that tracks the balance of LPTokens between the AMM instance via Trustline. + */ + AMMAccount: string + + /** + * Specifies one of the pool assets (XRP or token) of the AMM instance. + */ + Asset1: Amount + + /** + * Specifies the other pool asset of the AMM instance. + */ + Asset2: Amount + + /** + * Represents the liquidity providers' shares of the AMM instance's pools. + * LPTokens are tokens on XRPL. Each LPToken represents a proportional share of each pool of the AMM instance. + * The AMM instance account issues the LPTokens to LPs upon liquidity provision. + * LPTokens are balanced in the LPs trustline upon liquidity removal. + */ + LPToken: IssuedCurrencyAmount + + /** + * Specifies the fee, in basis point, to be charged to the traders for the trades + * executed against the AMM instance. Trading fee is a percentage of the trading volume. + * 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. + */ + TradingFee: number + + /** + * The ledger index of the current in-progress ledger, which was used when + * retrieving this information. + */ + ledger_current_index?: number + + /** + * True if this data is from a validated ledger version; if omitted or set + * to false, this data is not final. + */ + validated?: boolean + } +} diff --git a/packages/xrpl/src/models/methods/index.ts b/packages/xrpl/src/models/methods/index.ts index 7c5aee39..7f40a5d8 100644 --- a/packages/xrpl/src/models/methods/index.ts +++ b/packages/xrpl/src/models/methods/index.ts @@ -16,6 +16,7 @@ import { AccountOffersResponse, } from './accountOffers' import { AccountTxRequest, AccountTxResponse } from './accountTx' +import { AMMInfoRequest, AMMInfoResponse } from './ammInfo' import { ErrorResponse } from './baseMethod' import { BookOffersRequest, BookOffer, BookOffersResponse } from './bookOffers' import { ChannelVerifyRequest, ChannelVerifyResponse } from './channelVerify' @@ -87,6 +88,7 @@ type Request = | AccountObjectsRequest | AccountOffersRequest | AccountTxRequest + | AMMInfoRequest | GatewayBalancesRequest | NoRippleCheckRequest // ledger methods @@ -137,6 +139,7 @@ type Response = | AccountObjectsResponse | AccountOffersResponse | AccountTxResponse + | AMMInfoResponse | GatewayBalancesResponse | NoRippleCheckResponse // ledger methods @@ -195,6 +198,8 @@ export { AccountOffersResponse, AccountTxRequest, AccountTxResponse, + AMMInfoRequest, + AMMInfoResponse, GatewayBalancesRequest, GatewayBalancesResponse, NoRippleCheckRequest, From e64a668ef6212fb30a0f27d28b703a3f02f29753 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 18 Aug 2022 22:19:50 -0400 Subject: [PATCH 06/61] add AMMDeposit --- .../src/models/transactions/AMMDeposit.ts | 99 ++++++++++++ .../xrpl/src/models/transactions/index.ts | 1 + .../src/models/transactions/transaction.ts | 6 + packages/xrpl/test/models/AMMDeposit.ts | 145 ++++++++++++++++++ .../xrpl/test/models/AMMInstanceCreate.ts | 2 +- 5 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 packages/xrpl/src/models/transactions/AMMDeposit.ts create mode 100644 packages/xrpl/test/models/AMMDeposit.ts diff --git a/packages/xrpl/src/models/transactions/AMMDeposit.ts b/packages/xrpl/src/models/transactions/AMMDeposit.ts new file mode 100644 index 00000000..fca1ae4c --- /dev/null +++ b/packages/xrpl/src/models/transactions/AMMDeposit.ts @@ -0,0 +1,99 @@ +/* eslint-disable complexity -- required for validateAMMDeposit */ +import { ValidationError } from '../../errors' +import { Amount, IssuedCurrencyAmount } from '../common' + +import { + BaseTransaction, + isAmount, + isIssuedCurrency, + validateBaseTransaction, +} from './common' + +/** + * AMMDeposit is the deposit transaction used to add liquidity to the AMM instance pool, + * thus obtaining some share of the instance's pools in the form of LPToken. + * + * The following are the recommended valid combinations: + * - LPToken + * - Asset1In + * - Asset1In and Asset2In + * - Asset1In and LPToken + * - Asset1In and EPrice + */ +export interface AMMDeposit extends BaseTransaction { + TransactionType: 'AMMDeposit' + + /** + * A hash that uniquely identifies the AMM instance. This field is required. + */ + AMMID: string + + /** + * Specifies the amount of shares of the AMM instance pools that the trader + * wants to redeem or trade in. + */ + LPToken?: IssuedCurrencyAmount + + /** + * Specifies one of the pool assets (XRP or token) of the AMM instance to + * deposit more of its value. + */ + Asset1In?: Amount + + /** + * Specifies the other pool asset of the AMM instance to deposit more of + * its value. + */ + Asset2In?: Amount + + /** + * Specifies the maximum effective-price that LPToken can be traded out. + */ + EPrice?: number +} + +/** + * Verify the form and type of an AMMDeposit at runtime. + * + * @param tx - An AMMDeposit Transaction. + * @throws When the AMMDeposit is Malformed. + */ +export function validateAMMDeposit(tx: Record): void { + validateBaseTransaction(tx) + + if (tx.AMMID === undefined) { + throw new ValidationError('AMMDeposit: missing field AMMID') + } + + if (typeof tx.AMMID !== 'string') { + throw new ValidationError('AMMDeposit: AMMID must be a string') + } + + if (tx.Asset2In !== undefined && tx.Asset1In === undefined) { + throw new ValidationError('AMMDeposit: must set Asset1In with Asset2In') + } else if (tx.EPrice !== undefined && tx.Asset1In === undefined) { + throw new ValidationError('AMMDeposit: must set Asset1In with EPrice') + } else if (tx.LPToken === undefined && tx.Asset1In === undefined) { + throw new ValidationError( + 'AMMDeposit: must set either or both LPToken with Asset1In', + ) + } + + if (tx.LPToken !== undefined && !isIssuedCurrency(tx.LPToken)) { + throw new ValidationError( + 'AMMDeposit: LPToken must be an IssuedCurrencyAmount', + ) + } + + if (tx.Asset1In !== undefined && !isAmount(tx.Asset1In)) { + throw new ValidationError('AMMDeposit: Asset1In must be an Amount') + } + + if (tx.Asset2In !== undefined && !isAmount(tx.Asset2In)) { + throw new ValidationError('AMMDeposit: Asset2In must be an Amount') + } + + if (tx.EPrice !== undefined && typeof tx.EPrice !== 'string') { + throw new ValidationError('AMMDeposit: EPrice must be a string') + } +} diff --git a/packages/xrpl/src/models/transactions/index.ts b/packages/xrpl/src/models/transactions/index.ts index e8d20b62..77d2e19a 100644 --- a/packages/xrpl/src/models/transactions/index.ts +++ b/packages/xrpl/src/models/transactions/index.ts @@ -7,6 +7,7 @@ export { AccountSet, } from './accountSet' export { AccountDelete } from './accountDelete' +export { AMMDeposit } from './AMMDeposit' export { AMMInstanceCreate } from './AMMInstanceCreate' 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 16bd4de4..6fb89dc3 100644 --- a/packages/xrpl/src/models/transactions/transaction.ts +++ b/packages/xrpl/src/models/transactions/transaction.ts @@ -9,6 +9,7 @@ import { setTransactionFlagsToNumber } from '../utils/flags' import { AccountDelete, validateAccountDelete } from './accountDelete' import { AccountSet, validateAccountSet } from './accountSet' +import { AMMDeposit, validateAMMDeposit } from './AMMDeposit' import { AMMInstanceCreate, validateAMMInstanceCreate, @@ -61,6 +62,7 @@ import { TrustSet, validateTrustSet } from './trustSet' export type Transaction = | AccountDelete | AccountSet + | AMMDeposit | AMMInstanceCreate | CheckCancel | CheckCash @@ -120,6 +122,10 @@ export function validate(transaction: Record): void { validateAccountSet(tx) break + case 'AMMDeposit': + validateAMMDeposit(tx) + break + case 'AMMInstanceCreate': validateAMMInstanceCreate(tx) break diff --git a/packages/xrpl/test/models/AMMDeposit.ts b/packages/xrpl/test/models/AMMDeposit.ts new file mode 100644 index 00000000..535ca216 --- /dev/null +++ b/packages/xrpl/test/models/AMMDeposit.ts @@ -0,0 +1,145 @@ +import { assert } from 'chai' +import { validate, ValidationError } from 'xrpl-local' + +/** + * AMMDeposit Transaction Verification Testing. + * + * Providing runtime verification testing for each specific transaction type. + */ +describe('AMMDeposit', function () { + it(`verifies valid AMMDeposit with LPToken`, function () { + const validTx = { + TransactionType: 'AMMDeposit', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + LPToken: { + currency: 'B3813FCAB4EE68B3D0D735D6849465A9113EE048', + issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', + value: '1000', + }, + Sequence: 1337, + } as any + + assert.doesNotThrow(() => validate(validTx)) + }) + + it(`verifies valid AMMDeposit with Asset1In`, function () { + const validTx = { + TransactionType: 'AMMDeposit', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + Asset1In: '1000', + Sequence: 1337, + } as any + + assert.doesNotThrow(() => validate(validTx)) + }) + + it(`verifies valid AMMDeposit with Asset1In and LPToken`, function () { + const validTx = { + TransactionType: 'AMMDeposit', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + Asset1In: '1000', + LPToken: { + currency: 'B3813FCAB4EE68B3D0D735D6849465A9113EE048', + issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', + value: '1000', + }, + Sequence: 1337, + } as any + + assert.doesNotThrow(() => validate(validTx)) + }) + + it(`verifies valid AMMDeposit with Asset1In and EPrice`, function () { + const validTx = { + TransactionType: 'AMMDeposit', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + Asset1In: '1000', + EPrice: '25', + Sequence: 1337, + } as any + + assert.doesNotThrow(() => validate(validTx)) + }) + + it(`throws w/ missing AMMID`, function () { + const invalid = { + TransactionType: 'AMMDeposit', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset1In: '1000', + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMDeposit: missing field AMMID', + ) + }) + + it(`throws w/ AMMID must be a string`, function () { + const invalid = { + TransactionType: 'AMMDeposit', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: 1234, + Asset1In: '1000', + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMDeposit: AMMID must be a string', + ) + }) + + it(`throws w/ must set either or both LPToken with Asset1In`, function () { + const invalid = { + TransactionType: 'AMMDeposit', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMDeposit: must set either or both LPToken with Asset1In', + ) + }) + + it(`throws w/ must set Asset1In with Asset2In`, function () { + const invalid = { + TransactionType: 'AMMDeposit', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + Asset2In: '500', + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMDeposit: must set Asset1In with Asset2In', + ) + }) + + it(`throws w/ must set Asset1In with EPrice`, function () { + const invalid = { + TransactionType: 'AMMDeposit', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + EPrice: '25', + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMDeposit: must set Asset1In with EPrice', + ) + }) +}) diff --git a/packages/xrpl/test/models/AMMInstanceCreate.ts b/packages/xrpl/test/models/AMMInstanceCreate.ts index 6e9fbde6..6ed798be 100644 --- a/packages/xrpl/test/models/AMMInstanceCreate.ts +++ b/packages/xrpl/test/models/AMMInstanceCreate.ts @@ -2,7 +2,7 @@ import { assert } from 'chai' import { validate, ValidationError } from 'xrpl-local' /** - * NFTokenMint Transaction Verification Testing. + * AMMInstanceCreate Transaction Verification Testing. * * Providing runtime verification testing for each specific transaction type. */ From 35fef6512f6358f74aa0aba09ca0483f0d8e1a48 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 18 Aug 2022 23:11:24 -0400 Subject: [PATCH 07/61] use null check for missing fields --- .../xrpl/src/models/transactions/AMMDeposit.ts | 16 ++++++++-------- .../src/models/transactions/AMMInstanceCreate.ts | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMDeposit.ts b/packages/xrpl/src/models/transactions/AMMDeposit.ts index fca1ae4c..d01a5b3b 100644 --- a/packages/xrpl/src/models/transactions/AMMDeposit.ts +++ b/packages/xrpl/src/models/transactions/AMMDeposit.ts @@ -61,7 +61,7 @@ export interface AMMDeposit extends BaseTransaction { export function validateAMMDeposit(tx: Record): void { validateBaseTransaction(tx) - if (tx.AMMID === undefined) { + if (tx.AMMID == null) { throw new ValidationError('AMMDeposit: missing field AMMID') } @@ -69,31 +69,31 @@ export function validateAMMDeposit(tx: Record): void { throw new ValidationError('AMMDeposit: AMMID must be a string') } - if (tx.Asset2In !== undefined && tx.Asset1In === undefined) { + if (tx.Asset2In != null && tx.Asset1In == null) { throw new ValidationError('AMMDeposit: must set Asset1In with Asset2In') - } else if (tx.EPrice !== undefined && tx.Asset1In === undefined) { + } else if (tx.EPrice != null && tx.Asset1In == null) { throw new ValidationError('AMMDeposit: must set Asset1In with EPrice') - } else if (tx.LPToken === undefined && tx.Asset1In === undefined) { + } else if (tx.LPToken == null && tx.Asset1In == null) { throw new ValidationError( 'AMMDeposit: must set either or both LPToken with Asset1In', ) } - if (tx.LPToken !== undefined && !isIssuedCurrency(tx.LPToken)) { + if (tx.LPToken != null && !isIssuedCurrency(tx.LPToken)) { throw new ValidationError( 'AMMDeposit: LPToken must be an IssuedCurrencyAmount', ) } - if (tx.Asset1In !== undefined && !isAmount(tx.Asset1In)) { + if (tx.Asset1In != null && !isAmount(tx.Asset1In)) { throw new ValidationError('AMMDeposit: Asset1In must be an Amount') } - if (tx.Asset2In !== undefined && !isAmount(tx.Asset2In)) { + if (tx.Asset2In != null && !isAmount(tx.Asset2In)) { throw new ValidationError('AMMDeposit: Asset2In must be an Amount') } - if (tx.EPrice !== undefined && typeof tx.EPrice !== 'string') { + if (tx.EPrice != null && typeof tx.EPrice !== 'string') { throw new ValidationError('AMMDeposit: EPrice must be a string') } } diff --git a/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts b/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts index 637f9c25..3ac676b4 100644 --- a/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts +++ b/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts @@ -44,7 +44,7 @@ export interface AMMInstanceCreate extends BaseTransaction { export function validateAMMInstanceCreate(tx: Record): void { validateBaseTransaction(tx) - if (tx.Asset1 === undefined) { + if (tx.Asset1 == null) { throw new ValidationError('AMMInstanceCreate: missing field Asset1') } @@ -52,7 +52,7 @@ export function validateAMMInstanceCreate(tx: Record): void { throw new ValidationError('AMMInstanceCreate: Asset1 must be an Amount') } - if (tx.Asset2 === undefined) { + if (tx.Asset2 == null) { throw new ValidationError('AMMInstanceCreate: missing field Asset2') } @@ -60,7 +60,7 @@ export function validateAMMInstanceCreate(tx: Record): void { throw new ValidationError('AMMInstanceCreate: Asset2 must be an Amount') } - if (tx.TradingFee === undefined) { + if (tx.TradingFee == null) { throw new ValidationError('AMMInstanceCreate: missing field TradingFee') } From 3617487c321afc25bf29ac71e4f660fa247c9718 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 18 Aug 2022 23:51:16 -0400 Subject: [PATCH 08/61] add AMMWithdraw --- .../src/models/transactions/AMMWithdraw.ts | 101 ++++++++++++ .../xrpl/src/models/transactions/index.ts | 1 + .../src/models/transactions/transaction.ts | 6 + packages/xrpl/test/models/AMMWithdraw.ts | 145 ++++++++++++++++++ 4 files changed, 253 insertions(+) create mode 100644 packages/xrpl/src/models/transactions/AMMWithdraw.ts create mode 100644 packages/xrpl/test/models/AMMWithdraw.ts diff --git a/packages/xrpl/src/models/transactions/AMMWithdraw.ts b/packages/xrpl/src/models/transactions/AMMWithdraw.ts new file mode 100644 index 00000000..00aa78df --- /dev/null +++ b/packages/xrpl/src/models/transactions/AMMWithdraw.ts @@ -0,0 +1,101 @@ +/* eslint-disable complexity -- required for validateAMMWithdraw */ +import { ValidationError } from '../../errors' +import { Amount, IssuedCurrencyAmount } from '../common' + +import { + BaseTransaction, + isAmount, + isIssuedCurrency, + validateBaseTransaction, +} from './common' + +/** + * AMMWithdraw is the withdraw transaction used to remove liquidity from the AMM + * instance pool, thus redeeming some share of the pools that one owns in the form + * of LPToken. + * + * The following are the recommended valid combinations: + * - LPToken + * - Asset1Out + * - Asset1Out and Asset2Out + * - Asset1Out and LPToken + * - Asset1Out and EPrice + */ +export interface AMMWithdraw extends BaseTransaction { + TransactionType: 'AMMWithdraw' + + /** + * A hash that uniquely identifies the AMM instance. This field is required. + */ + AMMID: string + + /** + * Specifies the amount of shares of the AMM instance pools that the trader + * wants to redeem or trade in. + */ + LPToken?: IssuedCurrencyAmount + + /** + * Specifies one of the pools assets that the trader wants to remove. + * If the asset is XRP, then the Asset1Out is a string specifying the number of drops. + * Otherwise it is an IssuedCurrencyAmount object. + */ + Asset1Out?: Amount + + /** + * Specifies the other pool asset that the trader wants to remove. + */ + Asset2Out?: Amount + + /** + * Specifies the effective-price of the token out after successful execution of + * the transaction. + */ + EPrice?: number +} + +/** + * Verify the form and type of an AMMWithdraw at runtime. + * + * @param tx - An AMMWithdraw Transaction. + * @throws When the AMMWithdraw is Malformed. + */ +export function validateAMMWithdraw(tx: Record): void { + validateBaseTransaction(tx) + + if (tx.AMMID == null) { + throw new ValidationError('AMMWithdraw: missing field AMMID') + } + + if (typeof tx.AMMID !== 'string') { + throw new ValidationError('AMMWithdraw: AMMID must be a string') + } + + if (tx.Asset2Out != null && tx.Asset1Out == null) { + throw new ValidationError('AMMWithdraw: must set Asset1Out with Asset2Out') + } else if (tx.EPrice != null && tx.Asset1Out == null) { + throw new ValidationError('AMMWithdraw: must set Asset1Out with EPrice') + } else if (tx.LPToken == null && tx.Asset1Out == null) { + throw new ValidationError( + 'AMMWithdraw: must set either or both LPToken with Asset1Out', + ) + } + + if (tx.LPToken != null && !isIssuedCurrency(tx.LPToken)) { + throw new ValidationError( + 'AMMWithdraw: LPToken must be an IssuedCurrencyAmount', + ) + } + + if (tx.Asset1Out != null && !isAmount(tx.Asset1Out)) { + throw new ValidationError('AMMWithdraw: Asset1Out must be an Amount') + } + + if (tx.Asset2Out != null && !isAmount(tx.Asset2Out)) { + throw new ValidationError('AMMWithdraw: Asset2Out must be an Amount') + } + + if (tx.EPrice != null && typeof tx.EPrice !== 'string') { + throw new ValidationError('AMMWithdraw: EPrice must be a string') + } +} diff --git a/packages/xrpl/src/models/transactions/index.ts b/packages/xrpl/src/models/transactions/index.ts index 77d2e19a..2fc23622 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 { AMMWithdraw } from './AMMWithdraw' export { CheckCancel } from './checkCancel' export { CheckCash } from './checkCash' export { CheckCreate } from './checkCreate' diff --git a/packages/xrpl/src/models/transactions/transaction.ts b/packages/xrpl/src/models/transactions/transaction.ts index 6fb89dc3..06a70323 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 { AMMWithdraw, validateAMMWithdraw } from './AMMWithdraw' import { CheckCancel, validateCheckCancel } from './checkCancel' import { CheckCash, validateCheckCash } from './checkCash' import { CheckCreate, validateCheckCreate } from './checkCreate' @@ -64,6 +65,7 @@ export type Transaction = | AccountSet | AMMDeposit | AMMInstanceCreate + | AMMWithdraw | CheckCancel | CheckCash | CheckCreate @@ -130,6 +132,10 @@ export function validate(transaction: Record): void { validateAMMInstanceCreate(tx) break + case 'AMMWithdraw': + validateAMMWithdraw(tx) + break + case 'CheckCancel': validateCheckCancel(tx) break diff --git a/packages/xrpl/test/models/AMMWithdraw.ts b/packages/xrpl/test/models/AMMWithdraw.ts new file mode 100644 index 00000000..f12d819e --- /dev/null +++ b/packages/xrpl/test/models/AMMWithdraw.ts @@ -0,0 +1,145 @@ +import { assert } from 'chai' +import { validate, ValidationError } from 'xrpl-local' + +/** + * AMMWithdraw Transaction Verification Testing. + * + * Providing runtime verification testing for each specific transaction type. + */ +describe('AMMWithdraw', function () { + it(`verifies valid AMMWithdraw with LPToken`, function () { + const validTx = { + TransactionType: 'AMMWithdraw', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + LPToken: { + currency: 'B3813FCAB4EE68B3D0D735D6849465A9113EE048', + issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', + value: '1000', + }, + Sequence: 1337, + } as any + + assert.doesNotThrow(() => validate(validTx)) + }) + + it(`verifies valid AMMWithdraw with Asset1Out`, function () { + const validTx = { + TransactionType: 'AMMWithdraw', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + Asset1Out: '1000', + Sequence: 1337, + } as any + + assert.doesNotThrow(() => validate(validTx)) + }) + + it(`verifies valid AMMWithdraw with Asset1Out and LPToken`, function () { + const validTx = { + TransactionType: 'AMMWithdraw', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + Asset1Out: '1000', + LPToken: { + currency: 'B3813FCAB4EE68B3D0D735D6849465A9113EE048', + issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', + value: '1000', + }, + Sequence: 1337, + } as any + + assert.doesNotThrow(() => validate(validTx)) + }) + + it(`verifies valid AMMWithdraw with Asset1Out and EPrice`, function () { + const validTx = { + TransactionType: 'AMMWithdraw', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + Asset1Out: '1000', + EPrice: '25', + Sequence: 1337, + } as any + + assert.doesNotThrow(() => validate(validTx)) + }) + + it(`throws w/ missing AMMID`, function () { + const invalid = { + TransactionType: 'AMMWithdraw', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset1Out: '1000', + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMWithdraw: missing field AMMID', + ) + }) + + it(`throws w/ AMMID must be a string`, function () { + const invalid = { + TransactionType: 'AMMWithdraw', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: 1234, + Asset1Out: '1000', + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMWithdraw: AMMID must be a string', + ) + }) + + it(`throws w/ must set either or both LPToken with Asset1Out`, function () { + const invalid = { + TransactionType: 'AMMWithdraw', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMWithdraw: must set either or both LPToken with Asset1Out', + ) + }) + + it(`throws w/ must set Asset1Out with Asset2Out`, function () { + const invalid = { + TransactionType: 'AMMWithdraw', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + Asset2Out: '500', + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMWithdraw: must set Asset1Out with Asset2Out', + ) + }) + + it(`throws w/ must set Asset1Out with EPrice`, function () { + const invalid = { + TransactionType: 'AMMWithdraw', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + EPrice: '25', + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMWithdraw: must set Asset1Out with EPrice', + ) + }) +}) From b794f909ad1967b01d71145f0cc6e999840ceba9 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Fri, 19 Aug 2022 17:18:46 -0400 Subject: [PATCH 09/61] 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', + ) + }) +}) From e79dcb5d2f1c57a7f0869b2a5ae3077500e4f8e9 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Fri, 19 Aug 2022 17:20:23 -0400 Subject: [PATCH 10/61] fix lint error --- packages/xrpl/src/models/transactions/AMMVote.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMVote.ts b/packages/xrpl/src/models/transactions/AMMVote.ts index d1d73720..560bbd2a 100644 --- a/packages/xrpl/src/models/transactions/AMMVote.ts +++ b/packages/xrpl/src/models/transactions/AMMVote.ts @@ -1,9 +1,6 @@ import { ValidationError } from '../../errors' -import { - BaseTransaction, - validateBaseTransaction, -} from './common' +import { BaseTransaction, validateBaseTransaction } from './common' /** * AMMVote is used for submitting a vote for the trading fee of an AMM Instance. From db6d32f98bc8a04cd50a9a1743827ba0bb8af091 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Fri, 19 Aug 2022 21:48:26 -0400 Subject: [PATCH 11/61] add max trading fee check to AMMVote --- packages/xrpl/src/models/transactions/AMMVote.ts | 8 ++++++++ packages/xrpl/test/models/AMMVote.ts | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/packages/xrpl/src/models/transactions/AMMVote.ts b/packages/xrpl/src/models/transactions/AMMVote.ts index 560bbd2a..e226f041 100644 --- a/packages/xrpl/src/models/transactions/AMMVote.ts +++ b/packages/xrpl/src/models/transactions/AMMVote.ts @@ -2,6 +2,8 @@ import { ValidationError } from '../../errors' import { BaseTransaction, validateBaseTransaction } from './common' +const MAX_TRADING_FEE = 65000 + /** * AMMVote is used for submitting a vote for the trading fee of an AMM Instance. * @@ -49,4 +51,10 @@ export function validateAMMVote(tx: Record): void { if (typeof tx.FeeVal !== 'number') { throw new ValidationError('AMMVote: FeeVal must be a number') } + + if (tx.FeeVal > MAX_TRADING_FEE) { + throw new ValidationError( + `AMMVote: FeeVal must not be greater than ${MAX_TRADING_FEE}`, + ) + } } diff --git a/packages/xrpl/test/models/AMMVote.ts b/packages/xrpl/test/models/AMMVote.ts index b704c349..6c0e03fd 100644 --- a/packages/xrpl/test/models/AMMVote.ts +++ b/packages/xrpl/test/models/AMMVote.ts @@ -80,4 +80,20 @@ describe('AMMVote', function () { 'AMMVote: FeeVal must be a number', ) }) + + it(`throws w/ FeeVal must not be greater than 65000`, function () { + const invalid = { + TransactionType: 'AMMVote', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + FeeVal: 65001, + Sequence: 1337, + } as any + + assert.throws( + () => validate(invalid), + ValidationError, + 'AMMVote: FeeVal must not be greater than 65000', + ) + }) }) From 78e0a866cdff7a4e7e35e9210ef11d5bbcc4806f Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Fri, 19 Aug 2022 21:59:30 -0400 Subject: [PATCH 12/61] refactor MAX_TRADING_FEE to be in one place --- packages/xrpl/src/models/transactions/AMMInstanceCreate.ts | 6 +++--- packages/xrpl/src/models/transactions/AMMVote.ts | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts b/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts index 3ac676b4..dec294e9 100644 --- a/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts +++ b/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts @@ -3,7 +3,7 @@ import { Amount } from '../common' import { BaseTransaction, isAmount, validateBaseTransaction } from './common' -const MAX_TRADING_FEE = 65000 +export const AMM_MAX_TRADING_FEE = 65000 /** * AMMInstanceCreate is used to create AccountRoot and the corresponding @@ -68,9 +68,9 @@ export function validateAMMInstanceCreate(tx: Record): void { throw new ValidationError('AMMInstanceCreate: TradingFee must be a number') } - if (tx.TradingFee > MAX_TRADING_FEE) { + if (tx.TradingFee > AMM_MAX_TRADING_FEE) { throw new ValidationError( - `AMMInstanceCreate: TradingFee must not be greater than ${MAX_TRADING_FEE}`, + `AMMInstanceCreate: TradingFee must not be greater than ${AMM_MAX_TRADING_FEE}`, ) } } diff --git a/packages/xrpl/src/models/transactions/AMMVote.ts b/packages/xrpl/src/models/transactions/AMMVote.ts index e226f041..621ce232 100644 --- a/packages/xrpl/src/models/transactions/AMMVote.ts +++ b/packages/xrpl/src/models/transactions/AMMVote.ts @@ -1,9 +1,8 @@ import { ValidationError } from '../../errors' +import { AMM_MAX_TRADING_FEE } from './AMMInstanceCreate' import { BaseTransaction, validateBaseTransaction } from './common' -const MAX_TRADING_FEE = 65000 - /** * AMMVote is used for submitting a vote for the trading fee of an AMM Instance. * @@ -52,9 +51,9 @@ export function validateAMMVote(tx: Record): void { throw new ValidationError('AMMVote: FeeVal must be a number') } - if (tx.FeeVal > MAX_TRADING_FEE) { + if (tx.FeeVal > AMM_MAX_TRADING_FEE) { throw new ValidationError( - `AMMVote: FeeVal must not be greater than ${MAX_TRADING_FEE}`, + `AMMVote: FeeVal must not be greater than ${AMM_MAX_TRADING_FEE}`, ) } } From 7a035afca1ee59710d30c93e86ae3c07022d5f9a Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Sat, 20 Aug 2022 09:33:53 -0400 Subject: [PATCH 13/61] add AMMBid --- .../xrpl/src/models/transactions/AMMBid.ts | 79 +++++++++++++++ .../xrpl/src/models/transactions/index.ts | 1 + .../src/models/transactions/transaction.ts | 6 ++ packages/xrpl/test/models/AMMBid.ts | 98 +++++++++++++++++++ 4 files changed, 184 insertions(+) create mode 100644 packages/xrpl/src/models/transactions/AMMBid.ts create mode 100644 packages/xrpl/test/models/AMMBid.ts diff --git a/packages/xrpl/src/models/transactions/AMMBid.ts b/packages/xrpl/src/models/transactions/AMMBid.ts new file mode 100644 index 00000000..d88fd6c0 --- /dev/null +++ b/packages/xrpl/src/models/transactions/AMMBid.ts @@ -0,0 +1,79 @@ +import { ValidationError } from '../../errors' +import { Amount } from '../common' + +import { BaseTransaction, isAmount, validateBaseTransaction } from './common' + +const MAX_AUTH_ACCOUNTS = 4 + +/** + * AMMBid 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 AMMBid extends BaseTransaction { + TransactionType: 'AMMBid' + + /** + * A hash that uniquely identifies the AMM instance. This field is required. + */ + AMMID: string + + /** + * This field represents the minimum price that the bidder wants to pay for the slot. + * It is specified in units of LPToken. If specified let MinSlotPrice be X and let + * the slot-price computed by price scheduling algorithm be Y, then bidder always pays + * the max(X, Y). + */ + MinSlotPrice?: Amount + + /** + * This field represents the maximum price that the bidder wants to pay for the slot. + * It is specified in units of LPToken. + */ + MaxSlotPrice?: Amount + + /** + * This field represents an array of XRPL account IDs that are authorized to trade + * at the discounted fee against the AMM instance. + * A maximum of four accounts can be provided. + */ + AuthAccounts?: string[] +} + +/** + * Verify the form and type of an AMMBid at runtime. + * + * @param tx - An AMMBid Transaction. + * @throws When the AMMBid is Malformed. + */ +export function validateAMMBid(tx: Record): void { + validateBaseTransaction(tx) + + if (tx.AMMID == null) { + throw new ValidationError('AMMBid: missing field AMMID') + } + + if (typeof tx.AMMID !== 'string') { + throw new ValidationError('AMMBid: AMMID must be a string') + } + + if (tx.MinSlotPrice != null && !isAmount(tx.MinSlotPrice)) { + throw new ValidationError('AMMBid: MinSlotPrice must be an Amount') + } + + if (tx.MaxSlotPrice != null && !isAmount(tx.MaxSlotPrice)) { + throw new ValidationError('AMMBid: MaxSlotPrice must be an Amount') + } + + if (tx.AuthAccounts != null) { + if (!Array.isArray(tx.AuthAccounts)) { + throw new ValidationError(`AMMBid: AuthAccounts must be a string array`) + } + if (tx.AuthAccounts.length > MAX_AUTH_ACCOUNTS) { + throw new ValidationError( + `AMMBid: AuthAccounts length must not be greater than ${MAX_AUTH_ACCOUNTS}`, + ) + } + } +} diff --git a/packages/xrpl/src/models/transactions/index.ts b/packages/xrpl/src/models/transactions/index.ts index a6ebf054..187b308e 100644 --- a/packages/xrpl/src/models/transactions/index.ts +++ b/packages/xrpl/src/models/transactions/index.ts @@ -7,6 +7,7 @@ export { AccountSet, } from './accountSet' export { AccountDelete } from './accountDelete' +export { AMMBid } from './AMMBid' export { AMMDeposit } from './AMMDeposit' export { AMMInstanceCreate } from './AMMInstanceCreate' export { AMMVote } from './AMMVote' diff --git a/packages/xrpl/src/models/transactions/transaction.ts b/packages/xrpl/src/models/transactions/transaction.ts index d17a800a..1b5c6624 100644 --- a/packages/xrpl/src/models/transactions/transaction.ts +++ b/packages/xrpl/src/models/transactions/transaction.ts @@ -9,6 +9,7 @@ import { setTransactionFlagsToNumber } from '../utils/flags' import { AccountDelete, validateAccountDelete } from './accountDelete' import { AccountSet, validateAccountSet } from './accountSet' +import { AMMBid, validateAMMBid } from './AMMBid' import { AMMDeposit, validateAMMDeposit } from './AMMDeposit' import { AMMInstanceCreate, @@ -64,6 +65,7 @@ import { TrustSet, validateTrustSet } from './trustSet' export type Transaction = | AccountDelete | AccountSet + | AMMBid | AMMDeposit | AMMInstanceCreate | AMMVote @@ -126,6 +128,10 @@ export function validate(transaction: Record): void { validateAccountSet(tx) break + case 'AMMBid': + validateAMMBid(tx) + break + case 'AMMDeposit': validateAMMDeposit(tx) break diff --git a/packages/xrpl/test/models/AMMBid.ts b/packages/xrpl/test/models/AMMBid.ts new file mode 100644 index 00000000..ece8b692 --- /dev/null +++ b/packages/xrpl/test/models/AMMBid.ts @@ -0,0 +1,98 @@ +import { assert } from 'chai' +import { validate, ValidationError } from 'xrpl-local' + +/** + * AMMBid Transaction Verification Testing. + * + * Providing runtime verification testing for each specific transaction type. + */ +describe('AMMBid', function () { + let bid + + beforeEach(function () { + bid = { + TransactionType: 'AMMBid', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', + MinSlotPrice: '5', + MaxSlotPrice: '10', + AuthAccounts: [ + { + AuthAccount: { + Account: 'rNZdsTBP5tH1M6GHC6bTreHAp6ouP8iZSh', + }, + }, + { + AuthAccount: { + Account: 'rfpFv97Dwu89FTyUwPjtpZBbuZxTqqgTmH', + }, + }, + { + AuthAccount: { + Account: 'rzzYHPGb8Pa64oqxCzmuffm122bitq3Vb', + }, + }, + { + AuthAccount: { + Account: 'rhwxHxaHok86fe4LykBom1jSJ3RYQJs1h4', + }, + }, + ], + Sequence: 1337, + } as any + }) + + it(`verifies valid AMMBid`, function () { + assert.doesNotThrow(() => validate(bid)) + }) + + it(`throws w/ missing field AMMID`, function () { + delete bid.AMMID + assert.throws( + () => validate(bid), + ValidationError, + 'AMMBid: missing field AMMID', + ) + }) + + it(`throws w/ AMMID must be a string`, function () { + bid.AMMID = 1234 + assert.throws( + () => validate(bid), + ValidationError, + 'AMMBid: AMMID must be a string', + ) + }) + + it(`throws w/ MinSlotPrice must be an Amount`, function () { + bid.MinSlotPrice = 5 + assert.throws( + () => validate(bid), + ValidationError, + 'AMMBid: MinSlotPrice must be an Amount', + ) + }) + + it(`throws w/ MaxSlotPrice must be an Amount`, function () { + bid.MaxSlotPrice = 10 + assert.throws( + () => validate(bid), + ValidationError, + 'AMMBid: MaxSlotPrice must be an Amount', + ) + }) + + it(`throws w/ AuthAccounts length must not be greater than 4`, function () { + bid.AuthAccounts.push({ + AuthAccount: { + Account: 'r3X6noRsvaLapAKCG78zAtWcbhB3sggS1s', + }, + }) + + assert.throws( + () => validate(bid), + ValidationError, + 'AMMBid: AuthAccounts length must not be greater than 4', + ) + }) +}) From 4b18f06dbb7d9def8c75f156025f3790d89200d5 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Sat, 20 Aug 2022 09:43:33 -0400 Subject: [PATCH 14/61] add AuthAccount interface to AMMBid --- packages/xrpl/src/models/transactions/AMMBid.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/xrpl/src/models/transactions/AMMBid.ts b/packages/xrpl/src/models/transactions/AMMBid.ts index d88fd6c0..94a26569 100644 --- a/packages/xrpl/src/models/transactions/AMMBid.ts +++ b/packages/xrpl/src/models/transactions/AMMBid.ts @@ -5,6 +5,12 @@ import { BaseTransaction, isAmount, validateBaseTransaction } from './common' const MAX_AUTH_ACCOUNTS = 4 +interface AuthAccount { + AuthAccount: { + Account: string + } +} + /** * AMMBid is used for submitting a vote for the trading fee of an AMM Instance. * @@ -38,7 +44,7 @@ export interface AMMBid extends BaseTransaction { * at the discounted fee against the AMM instance. * A maximum of four accounts can be provided. */ - AuthAccounts?: string[] + AuthAccounts?: AuthAccount[] } /** From 835dc6776717c6b92b6abe6727cd750e7d88532b Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Sat, 20 Aug 2022 10:54:14 -0400 Subject: [PATCH 15/61] refactor tests --- packages/xrpl/test/models/AMMDeposit.ts | 114 +++++------------ .../xrpl/test/models/AMMInstanceCreate.ts | 115 ++++-------------- packages/xrpl/test/models/AMMVote.ts | 63 +++------- packages/xrpl/test/models/AMMWithdraw.ts | 114 +++++------------ 4 files changed, 98 insertions(+), 308 deletions(-) diff --git a/packages/xrpl/test/models/AMMDeposit.ts b/packages/xrpl/test/models/AMMDeposit.ts index 535ca216..ea81e8cf 100644 --- a/packages/xrpl/test/models/AMMDeposit.ts +++ b/packages/xrpl/test/models/AMMDeposit.ts @@ -7,137 +7,83 @@ import { validate, ValidationError } from 'xrpl-local' * Providing runtime verification testing for each specific transaction type. */ describe('AMMDeposit', function () { - it(`verifies valid AMMDeposit with LPToken`, function () { - const validTx = { + const LPToken = { + currency: 'B3813FCAB4EE68B3D0D735D6849465A9113EE048', + issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', + value: '1000', + } + let deposit + + beforeEach(function () { + deposit = { TransactionType: 'AMMDeposit', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - LPToken: { - currency: 'B3813FCAB4EE68B3D0D735D6849465A9113EE048', - issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', - value: '1000', - }, Sequence: 1337, } as any + }) - assert.doesNotThrow(() => validate(validTx)) + it(`verifies valid AMMDeposit with LPToken`, function () { + deposit.LPToken = LPToken + assert.doesNotThrow(() => validate(deposit)) }) it(`verifies valid AMMDeposit with Asset1In`, function () { - const validTx = { - TransactionType: 'AMMDeposit', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - Asset1In: '1000', - Sequence: 1337, - } as any - - assert.doesNotThrow(() => validate(validTx)) + deposit.Asset1In = '1000' + assert.doesNotThrow(() => validate(deposit)) }) it(`verifies valid AMMDeposit with Asset1In and LPToken`, function () { - const validTx = { - TransactionType: 'AMMDeposit', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - Asset1In: '1000', - LPToken: { - currency: 'B3813FCAB4EE68B3D0D735D6849465A9113EE048', - issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', - value: '1000', - }, - Sequence: 1337, - } as any - - assert.doesNotThrow(() => validate(validTx)) + deposit.Asset1In = '1000' + deposit.LPToken = LPToken + assert.doesNotThrow(() => validate(deposit)) }) it(`verifies valid AMMDeposit with Asset1In and EPrice`, function () { - const validTx = { - TransactionType: 'AMMDeposit', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - Asset1In: '1000', - EPrice: '25', - Sequence: 1337, - } as any - - assert.doesNotThrow(() => validate(validTx)) + deposit.Asset1In = '1000' + deposit.EPrice = '25' + assert.doesNotThrow(() => validate(deposit)) }) it(`throws w/ missing AMMID`, function () { - const invalid = { - TransactionType: 'AMMDeposit', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - Asset1In: '1000', - Sequence: 1337, - } as any - + delete deposit.AMMID assert.throws( - () => validate(invalid), + () => validate(deposit), ValidationError, 'AMMDeposit: missing field AMMID', ) }) it(`throws w/ AMMID must be a string`, function () { - const invalid = { - TransactionType: 'AMMDeposit', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: 1234, - Asset1In: '1000', - Sequence: 1337, - } as any - + deposit.AMMID = 1234 assert.throws( - () => validate(invalid), + () => validate(deposit), ValidationError, 'AMMDeposit: AMMID must be a string', ) }) it(`throws w/ must set either or both LPToken with Asset1In`, function () { - const invalid = { - TransactionType: 'AMMDeposit', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - Sequence: 1337, - } as any - assert.throws( - () => validate(invalid), + () => validate(deposit), ValidationError, 'AMMDeposit: must set either or both LPToken with Asset1In', ) }) it(`throws w/ must set Asset1In with Asset2In`, function () { - const invalid = { - TransactionType: 'AMMDeposit', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - Asset2In: '500', - Sequence: 1337, - } as any - + deposit.Asset2In = '500' assert.throws( - () => validate(invalid), + () => validate(deposit), ValidationError, 'AMMDeposit: must set Asset1In with Asset2In', ) }) it(`throws w/ must set Asset1In with EPrice`, function () { - const invalid = { - TransactionType: 'AMMDeposit', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - EPrice: '25', - Sequence: 1337, - } as any - + deposit.EPrice = '25' assert.throws( - () => validate(invalid), + () => validate(deposit), ValidationError, 'AMMDeposit: must set Asset1In with EPrice', ) diff --git a/packages/xrpl/test/models/AMMInstanceCreate.ts b/packages/xrpl/test/models/AMMInstanceCreate.ts index 6ed798be..04d2a677 100644 --- a/packages/xrpl/test/models/AMMInstanceCreate.ts +++ b/packages/xrpl/test/models/AMMInstanceCreate.ts @@ -7,8 +7,10 @@ import { validate, ValidationError } from 'xrpl-local' * Providing runtime verification testing for each specific transaction type. */ describe('AMMInstanceCreate', function () { - it(`verifies valid AMMInstanceCreate`, function () { - const validTx = { + let instanceCreate + + beforeEach(function () { + instanceCreate = { TransactionType: 'AMMInstanceCreate', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', Asset1: '1000', @@ -20,145 +22,70 @@ describe('AMMInstanceCreate', function () { TradingFee: 12, Sequence: 1337, } as any + }) - assert.doesNotThrow(() => validate(validTx)) + it(`verifies valid AMMInstanceCreate`, function () { + assert.doesNotThrow(() => validate(instanceCreate)) }) it(`throws w/ missing Asset1`, function () { - const invalid = { - TransactionType: 'AMMInstanceCreate', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - Asset2: { - currency: 'USD', - issuer: 'rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9', - value: '1000', - }, - TradingFee: 12, - Sequence: 1337, - } as any - + delete instanceCreate.Asset1 assert.throws( - () => validate(invalid), + () => validate(instanceCreate), ValidationError, 'AMMInstanceCreate: missing field Asset1', ) }) it(`throws w/ Asset1 must be an Amount`, function () { - const invalidAsset1 = 1000 - const invalidTx = { - TransactionType: 'AMMInstanceCreate', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - Asset1: invalidAsset1, - Asset2: { - currency: 'USD', - issuer: 'rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9', - value: '1000', - }, - TradingFee: 12, - Sequence: 1337, - } as any - + instanceCreate.Asset1 = 1000 assert.throws( - () => validate(invalidTx), + () => validate(instanceCreate), ValidationError, 'AMMInstanceCreate: Asset1 must be an Amount', ) }) it(`throws w/ missing Asset2`, function () { - const invalid = { - TransactionType: 'AMMInstanceCreate', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - Asset1: '1000', - TradingFee: 12, - Sequence: 1337, - } as any - + delete instanceCreate.Asset2 assert.throws( - () => validate(invalid), + () => validate(instanceCreate), ValidationError, 'AMMInstanceCreate: missing field Asset2', ) }) it(`throws w/ Asset2 must be an Amount`, function () { - const invalidAsset2 = 1000 - const invalidTx = { - TransactionType: 'AMMInstanceCreate', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - Asset1: '1000', - Asset2: invalidAsset2, - TradingFee: 12, - Sequence: 1337, - } as any - + instanceCreate.Asset2 = 1000 assert.throws( - () => validate(invalidTx), + () => validate(instanceCreate), ValidationError, 'AMMInstanceCreate: Asset2 must be an Amount', ) }) it(`throws w/ missing TradingFee`, function () { - const invalid = { - TransactionType: 'AMMInstanceCreate', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - Asset1: '1000', - Asset2: { - currency: 'USD', - issuer: 'rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9', - value: '1000', - }, - Sequence: 1337, - } as any - + delete instanceCreate.TradingFee assert.throws( - () => validate(invalid), + () => validate(instanceCreate), ValidationError, 'AMMInstanceCreate: missing field TradingFee', ) }) it(`throws w/ TradingFee must be a number`, function () { - const invalidTradingFee = '12' - const invalidTx = { - TransactionType: 'AMMInstanceCreate', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - Asset1: '1000', - Asset2: { - currency: 'USD', - issuer: 'rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9', - value: '1000', - }, - TradingFee: invalidTradingFee, - Sequence: 1337, - } as any - + instanceCreate.TradingFee = '12' assert.throws( - () => validate(invalidTx), + () => validate(instanceCreate), ValidationError, 'AMMInstanceCreate: TradingFee must be a number', ) }) it(`throws w/ TradingFee must not be greater than 65000`, function () { - const invalidTradingFee = 65001 - const invalidTx = { - TransactionType: 'AMMInstanceCreate', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - Asset1: '1000', - Asset2: { - currency: 'USD', - issuer: 'rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9', - value: '1000', - }, - TradingFee: invalidTradingFee, - Sequence: 1337, - } as any - + instanceCreate.TradingFee = 65001 assert.throws( - () => validate(invalidTx), + () => validate(instanceCreate), ValidationError, `AMMInstanceCreate: TradingFee must not be greater than 65000`, ) diff --git a/packages/xrpl/test/models/AMMVote.ts b/packages/xrpl/test/models/AMMVote.ts index 6c0e03fd..9e7d6c09 100644 --- a/packages/xrpl/test/models/AMMVote.ts +++ b/packages/xrpl/test/models/AMMVote.ts @@ -7,91 +7,62 @@ import { validate, ValidationError } from 'xrpl-local' * Providing runtime verification testing for each specific transaction type. */ describe('AMMVote', function () { - it(`verifies valid AMMVote`, function () { - const validTx = { + let vote + + beforeEach(function () { + vote = { TransactionType: 'AMMVote', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', FeeVal: 25, Sequence: 1337, } as any + }) - assert.doesNotThrow(() => validate(validTx)) + it(`verifies valid AMMVote`, function () { + assert.doesNotThrow(() => validate(vote)) }) it(`throws w/ missing field AMMID`, function () { - const invalid = { - TransactionType: 'AMMVote', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - FeeVal: 25, - Sequence: 1337, - } as any - + delete vote.AMMID assert.throws( - () => validate(invalid), + () => validate(vote), 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 - + vote.AMMID = 1234 assert.throws( - () => validate(invalid), + () => validate(vote), 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 - + delete vote.FeeVal assert.throws( - () => validate(invalid), + () => validate(vote), 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 - + vote.FeeVal = '25' assert.throws( - () => validate(invalid), + () => validate(vote), ValidationError, 'AMMVote: FeeVal must be a number', ) }) it(`throws w/ FeeVal must not be greater than 65000`, function () { - const invalid = { - TransactionType: 'AMMVote', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - FeeVal: 65001, - Sequence: 1337, - } as any - + vote.FeeVal = 65001 assert.throws( - () => validate(invalid), + () => validate(vote), ValidationError, 'AMMVote: FeeVal must not be greater than 65000', ) diff --git a/packages/xrpl/test/models/AMMWithdraw.ts b/packages/xrpl/test/models/AMMWithdraw.ts index f12d819e..1f5e6c20 100644 --- a/packages/xrpl/test/models/AMMWithdraw.ts +++ b/packages/xrpl/test/models/AMMWithdraw.ts @@ -7,137 +7,83 @@ import { validate, ValidationError } from 'xrpl-local' * Providing runtime verification testing for each specific transaction type. */ describe('AMMWithdraw', function () { - it(`verifies valid AMMWithdraw with LPToken`, function () { - const validTx = { + const LPToken = { + currency: 'B3813FCAB4EE68B3D0D735D6849465A9113EE048', + issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', + value: '1000', + } + let withdraw + + beforeEach(function () { + withdraw = { TransactionType: 'AMMWithdraw', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - LPToken: { - currency: 'B3813FCAB4EE68B3D0D735D6849465A9113EE048', - issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', - value: '1000', - }, Sequence: 1337, } as any + }) - assert.doesNotThrow(() => validate(validTx)) + it(`verifies valid AMMWithdraw with LPToken`, function () { + withdraw.LPToken = LPToken + assert.doesNotThrow(() => validate(withdraw)) }) it(`verifies valid AMMWithdraw with Asset1Out`, function () { - const validTx = { - TransactionType: 'AMMWithdraw', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - Asset1Out: '1000', - Sequence: 1337, - } as any - - assert.doesNotThrow(() => validate(validTx)) + withdraw.Asset1Out = '1000' + assert.doesNotThrow(() => validate(withdraw)) }) it(`verifies valid AMMWithdraw with Asset1Out and LPToken`, function () { - const validTx = { - TransactionType: 'AMMWithdraw', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - Asset1Out: '1000', - LPToken: { - currency: 'B3813FCAB4EE68B3D0D735D6849465A9113EE048', - issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', - value: '1000', - }, - Sequence: 1337, - } as any - - assert.doesNotThrow(() => validate(validTx)) + withdraw.Asset1Out = '1000' + withdraw.LPToken = LPToken + assert.doesNotThrow(() => validate(withdraw)) }) it(`verifies valid AMMWithdraw with Asset1Out and EPrice`, function () { - const validTx = { - TransactionType: 'AMMWithdraw', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - Asset1Out: '1000', - EPrice: '25', - Sequence: 1337, - } as any - - assert.doesNotThrow(() => validate(validTx)) + withdraw.Asset1Out = '1000' + withdraw.EPrice = '25' + assert.doesNotThrow(() => validate(withdraw)) }) it(`throws w/ missing AMMID`, function () { - const invalid = { - TransactionType: 'AMMWithdraw', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - Asset1Out: '1000', - Sequence: 1337, - } as any - + delete withdraw.AMMID assert.throws( - () => validate(invalid), + () => validate(withdraw), ValidationError, 'AMMWithdraw: missing field AMMID', ) }) it(`throws w/ AMMID must be a string`, function () { - const invalid = { - TransactionType: 'AMMWithdraw', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: 1234, - Asset1Out: '1000', - Sequence: 1337, - } as any - + withdraw.AMMID = 1234 assert.throws( - () => validate(invalid), + () => validate(withdraw), ValidationError, 'AMMWithdraw: AMMID must be a string', ) }) it(`throws w/ must set either or both LPToken with Asset1Out`, function () { - const invalid = { - TransactionType: 'AMMWithdraw', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - Sequence: 1337, - } as any - assert.throws( - () => validate(invalid), + () => validate(withdraw), ValidationError, 'AMMWithdraw: must set either or both LPToken with Asset1Out', ) }) it(`throws w/ must set Asset1Out with Asset2Out`, function () { - const invalid = { - TransactionType: 'AMMWithdraw', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - Asset2Out: '500', - Sequence: 1337, - } as any - + withdraw.Asset2Out = '500' assert.throws( - () => validate(invalid), + () => validate(withdraw), ValidationError, 'AMMWithdraw: must set Asset1Out with Asset2Out', ) }) it(`throws w/ must set Asset1Out with EPrice`, function () { - const invalid = { - TransactionType: 'AMMWithdraw', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - EPrice: '25', - Sequence: 1337, - } as any - + withdraw.EPrice = '25' assert.throws( - () => validate(invalid), + () => validate(withdraw), ValidationError, 'AMMWithdraw: must set Asset1Out with EPrice', ) From c95f8afc21f65734e026c292b74adbce0902a333 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Sun, 28 Aug 2022 14:04:13 -0400 Subject: [PATCH 16/61] add AMMID to AMMInfoResponse --- packages/xrpl/src/models/methods/ammInfo.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index afb58e0a..37383403 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -39,6 +39,11 @@ export interface AMMInfoResponse extends BaseResponse { */ AMMAccount: string + /** + * A hash that uniquely identifies the AMM instance. This field is required. + */ + AMMID: string + /** * Specifies one of the pool assets (XRP or token) of the AMM instance. */ From b8e4f2405a680673bbd866b8c9a286a9b772d4aa Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 10:59:03 -0400 Subject: [PATCH 17/61] update amm_info docstrings --- packages/xrpl/src/models/methods/ammInfo.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 37383403..93755a2d 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -18,11 +18,13 @@ export interface AMMInfoRequest extends BaseRequest { /** * Specifies one of the pool assets (XRP or token) of the AMM instance. + * Both asset1 and asset2 must be defined to specify an AMM instance. */ asset1?: Amount /** * Specifies the other pool asset of the AMM instance. + * Both asset1 and asset2 must be defined to specify an AMM instance. */ asset2?: Amount } @@ -40,7 +42,7 @@ export interface AMMInfoResponse extends BaseResponse { AMMAccount: string /** - * A hash that uniquely identifies the AMM instance. This field is required. + * A hash that uniquely identifies the AMM instance. */ AMMID: string From ed7760c55525aaf462dde1c0012b0096792a668d Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 16:29:49 -0400 Subject: [PATCH 18/61] fix EPrice type to be Amount --- packages/xrpl/src/models/transactions/AMMDeposit.ts | 2 +- packages/xrpl/src/models/transactions/AMMWithdraw.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMDeposit.ts b/packages/xrpl/src/models/transactions/AMMDeposit.ts index d01a5b3b..d74620ad 100644 --- a/packages/xrpl/src/models/transactions/AMMDeposit.ts +++ b/packages/xrpl/src/models/transactions/AMMDeposit.ts @@ -49,7 +49,7 @@ export interface AMMDeposit extends BaseTransaction { /** * Specifies the maximum effective-price that LPToken can be traded out. */ - EPrice?: number + EPrice?: Amount } /** diff --git a/packages/xrpl/src/models/transactions/AMMWithdraw.ts b/packages/xrpl/src/models/transactions/AMMWithdraw.ts index 00aa78df..2556e0e3 100644 --- a/packages/xrpl/src/models/transactions/AMMWithdraw.ts +++ b/packages/xrpl/src/models/transactions/AMMWithdraw.ts @@ -51,7 +51,7 @@ export interface AMMWithdraw extends BaseTransaction { * Specifies the effective-price of the token out after successful execution of * the transaction. */ - EPrice?: number + EPrice?: Amount } /** From 0de755bb0bf7df2bf4e54a9108fe634b84d51555 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 16:49:48 -0400 Subject: [PATCH 19/61] update EPrice validation error message and add missing tests --- .../src/models/transactions/AMMDeposit.ts | 2 +- .../src/models/transactions/AMMWithdraw.ts | 2 +- packages/xrpl/test/models/AMMDeposit.ts | 38 +++++++++++++++++++ packages/xrpl/test/models/AMMWithdraw.ts | 38 +++++++++++++++++++ 4 files changed, 78 insertions(+), 2 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMDeposit.ts b/packages/xrpl/src/models/transactions/AMMDeposit.ts index d74620ad..086381e0 100644 --- a/packages/xrpl/src/models/transactions/AMMDeposit.ts +++ b/packages/xrpl/src/models/transactions/AMMDeposit.ts @@ -94,6 +94,6 @@ export function validateAMMDeposit(tx: Record): void { } if (tx.EPrice != null && typeof tx.EPrice !== 'string') { - throw new ValidationError('AMMDeposit: EPrice must be a string') + throw new ValidationError('AMMDeposit: EPrice must be an Amount') } } diff --git a/packages/xrpl/src/models/transactions/AMMWithdraw.ts b/packages/xrpl/src/models/transactions/AMMWithdraw.ts index 2556e0e3..1c777f78 100644 --- a/packages/xrpl/src/models/transactions/AMMWithdraw.ts +++ b/packages/xrpl/src/models/transactions/AMMWithdraw.ts @@ -96,6 +96,6 @@ export function validateAMMWithdraw(tx: Record): void { } if (tx.EPrice != null && typeof tx.EPrice !== 'string') { - throw new ValidationError('AMMWithdraw: EPrice must be a string') + throw new ValidationError('AMMWithdraw: EPrice must be an Amount') } } diff --git a/packages/xrpl/test/models/AMMDeposit.ts b/packages/xrpl/test/models/AMMDeposit.ts index ea81e8cf..e926646a 100644 --- a/packages/xrpl/test/models/AMMDeposit.ts +++ b/packages/xrpl/test/models/AMMDeposit.ts @@ -88,4 +88,42 @@ describe('AMMDeposit', function () { 'AMMDeposit: must set Asset1In with EPrice', ) }) + + it(`throws w/ LPToken must be an IssuedCurrencyAmount`, function () { + deposit.LPToken = 1234 + assert.throws( + () => validate(deposit), + ValidationError, + 'AMMDeposit: LPToken must be an IssuedCurrencyAmount', + ) + }) + + it(`throws w/ Asset1In must be an Amount`, function () { + deposit.Asset1In = 1234 + assert.throws( + () => validate(deposit), + ValidationError, + 'AMMDeposit: Asset1In must be an Amount', + ) + }) + + it(`throws w/ Asset2In must be an Amount`, function () { + deposit.Asset1In = '1000' + deposit.Asset2In = 1234 + assert.throws( + () => validate(deposit), + ValidationError, + 'AMMDeposit: Asset2In must be an Amount', + ) + }) + + it(`throws w/ EPrice must be an Amount`, function () { + deposit.Asset1In = '1000' + deposit.EPrice = 1234 + assert.throws( + () => validate(deposit), + ValidationError, + 'AMMDeposit: EPrice must be an Amount', + ) + }) }) diff --git a/packages/xrpl/test/models/AMMWithdraw.ts b/packages/xrpl/test/models/AMMWithdraw.ts index 1f5e6c20..5f8eca42 100644 --- a/packages/xrpl/test/models/AMMWithdraw.ts +++ b/packages/xrpl/test/models/AMMWithdraw.ts @@ -88,4 +88,42 @@ describe('AMMWithdraw', function () { 'AMMWithdraw: must set Asset1Out with EPrice', ) }) + + it(`throws w/ LPToken must be an IssuedCurrencyAmount`, function () { + withdraw.LPToken = 1234 + assert.throws( + () => validate(withdraw), + ValidationError, + 'AMMWithdraw: LPToken must be an IssuedCurrencyAmount', + ) + }) + + it(`throws w/ Asset1Out must be an Amount`, function () { + withdraw.Asset1Out = 1234 + assert.throws( + () => validate(withdraw), + ValidationError, + 'AMMWithdraw: Asset1Out must be an Amount', + ) + }) + + it(`throws w/ Asset2Out must be an Amount`, function () { + withdraw.Asset1Out = '1000' + withdraw.Asset2Out = 1234 + assert.throws( + () => validate(withdraw), + ValidationError, + 'AMMWithdraw: Asset2Out must be an Amount', + ) + }) + + it(`throws w/ EPrice must be an Amount`, function () { + withdraw.Asset1Out = '1000' + withdraw.EPrice = 1234 + assert.throws( + () => validate(withdraw), + ValidationError, + 'AMMWithdraw: EPrice must be an Amount', + ) + }) }) From e13b27e43fccab023326d40b939b7fb4fb93d3d5 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 17:45:22 -0400 Subject: [PATCH 20/61] update definitions to fix AMM in LEDGER_ENTRY_TYPES --- packages/ripple-binary-codec/src/enums/definitions.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ripple-binary-codec/src/enums/definitions.json b/packages/ripple-binary-codec/src/enums/definitions.json index ce449a51..cc0fc1d0 100644 --- a/packages/ripple-binary-codec/src/enums/definitions.json +++ b/packages/ripple-binary-codec/src/enums/definitions.json @@ -44,7 +44,7 @@ "NegativeUNL": 78, "NFTokenPage": 80, "NFTokenOffer": 55, - "Amm": 121, + "AMM": 121, "Any": -3, "Child": -2, "Nickname": 110, From 2796c2aeeff92538287148ffc942fbfca31c52bc Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 18:07:22 -0400 Subject: [PATCH 21/61] add missing test case Asset1In and Asset2In valid --- packages/xrpl/test/models/AMMDeposit.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/xrpl/test/models/AMMDeposit.ts b/packages/xrpl/test/models/AMMDeposit.ts index e926646a..dbe4035a 100644 --- a/packages/xrpl/test/models/AMMDeposit.ts +++ b/packages/xrpl/test/models/AMMDeposit.ts @@ -33,6 +33,12 @@ describe('AMMDeposit', function () { assert.doesNotThrow(() => validate(deposit)) }) + it(`verifies valid AMMDeposit with Asset1In adn Asset2In`, function () { + deposit.Asset1In = '1000' + deposit.Asset2In = '1000' + assert.doesNotThrow(() => validate(deposit)) + }) + it(`verifies valid AMMDeposit with Asset1In and LPToken`, function () { deposit.Asset1In = '1000' deposit.LPToken = LPToken From 6150d33a61d6c220dbb1316af3e62a4257a46bd8 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 18:10:40 -0400 Subject: [PATCH 22/61] add missing test case Asset1Out and Asset2Out valid --- packages/xrpl/test/models/AMMDeposit.ts | 2 +- packages/xrpl/test/models/AMMWithdraw.ts | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/xrpl/test/models/AMMDeposit.ts b/packages/xrpl/test/models/AMMDeposit.ts index dbe4035a..d10eb64c 100644 --- a/packages/xrpl/test/models/AMMDeposit.ts +++ b/packages/xrpl/test/models/AMMDeposit.ts @@ -33,7 +33,7 @@ describe('AMMDeposit', function () { assert.doesNotThrow(() => validate(deposit)) }) - it(`verifies valid AMMDeposit with Asset1In adn Asset2In`, function () { + it(`verifies valid AMMDeposit with Asset1In and Asset2In`, function () { deposit.Asset1In = '1000' deposit.Asset2In = '1000' assert.doesNotThrow(() => validate(deposit)) diff --git a/packages/xrpl/test/models/AMMWithdraw.ts b/packages/xrpl/test/models/AMMWithdraw.ts index 5f8eca42..a2fc2d9f 100644 --- a/packages/xrpl/test/models/AMMWithdraw.ts +++ b/packages/xrpl/test/models/AMMWithdraw.ts @@ -33,6 +33,12 @@ describe('AMMWithdraw', function () { assert.doesNotThrow(() => validate(withdraw)) }) + it(`verifies valid AMMWithdraw with Asset1Out and Asset2Out`, function () { + withdraw.Asset1Out = '1000' + withdraw.Asset2Out = '1000' + assert.doesNotThrow(() => validate(withdraw)) + }) + it(`verifies valid AMMWithdraw with Asset1Out and LPToken`, function () { withdraw.Asset1Out = '1000' withdraw.LPToken = LPToken From 8ef2483e151fb648445a8a7ccd6f1da693c42ff8 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 18:45:34 -0400 Subject: [PATCH 23/61] add negative FeeVal check --- packages/xrpl/src/models/transactions/AMMVote.ts | 4 ++-- packages/xrpl/test/models/AMMVote.ts | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMVote.ts b/packages/xrpl/src/models/transactions/AMMVote.ts index 621ce232..270a4141 100644 --- a/packages/xrpl/src/models/transactions/AMMVote.ts +++ b/packages/xrpl/src/models/transactions/AMMVote.ts @@ -51,9 +51,9 @@ export function validateAMMVote(tx: Record): void { throw new ValidationError('AMMVote: FeeVal must be a number') } - if (tx.FeeVal > AMM_MAX_TRADING_FEE) { + if (tx.FeeVal < 0 || tx.FeeVal > AMM_MAX_TRADING_FEE) { throw new ValidationError( - `AMMVote: FeeVal must not be greater than ${AMM_MAX_TRADING_FEE}`, + `AMMVote: FeeVal must be between 0 and ${AMM_MAX_TRADING_FEE}`, ) } } diff --git a/packages/xrpl/test/models/AMMVote.ts b/packages/xrpl/test/models/AMMVote.ts index 9e7d6c09..b7ae2852 100644 --- a/packages/xrpl/test/models/AMMVote.ts +++ b/packages/xrpl/test/models/AMMVote.ts @@ -59,12 +59,21 @@ describe('AMMVote', function () { ) }) - it(`throws w/ FeeVal must not be greater than 65000`, function () { + it(`throws when FeeVal is greater than AMM_MAX_TRADING_FEE`, function () { vote.FeeVal = 65001 assert.throws( () => validate(vote), ValidationError, - 'AMMVote: FeeVal must not be greater than 65000', + 'AMMVote: FeeVal must be between 0 and 65000', + ) + }) + + it(`throws when FeeVal is a negative number`, function () { + vote.FeeVal = -1 + assert.throws( + () => validate(vote), + ValidationError, + 'AMMVote: FeeVal must be between 0 and 65000', ) }) }) From e9778ebcdbbc3a67aa636cf65df74c28983bbb52 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 18:48:54 -0400 Subject: [PATCH 24/61] update HISTORY.md to specify XLS-30 --- packages/xrpl/HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/xrpl/HISTORY.md b/packages/xrpl/HISTORY.md index 1ee6990e..52d9b44c 100644 --- a/packages/xrpl/HISTORY.md +++ b/packages/xrpl/HISTORY.md @@ -9,7 +9,7 @@ Subscribe to [the **xrpl-announce** mailing list](https://groups.google.com/g/xr * Made unexpected errors in `submitAndWait` more verbose to make them easier to debug. ### Added -* Support for Automated Market Maker (AMM). +* Support for Automated Market Maker (AMM) transactions and requests as defined in XLS-30. ## 2.3.1 (2022-06-27) ### Fixed From 6a06412b2d9f08c1909054b1d80c93405f22b267 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 19:01:08 -0400 Subject: [PATCH 25/61] update wording on AMMDeposit & AMMWithdraw validation errors --- packages/xrpl/src/models/transactions/AMMDeposit.ts | 2 +- packages/xrpl/src/models/transactions/AMMWithdraw.ts | 2 +- packages/xrpl/test/models/AMMDeposit.ts | 4 ++-- packages/xrpl/test/models/AMMWithdraw.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMDeposit.ts b/packages/xrpl/src/models/transactions/AMMDeposit.ts index 086381e0..b28ca0ae 100644 --- a/packages/xrpl/src/models/transactions/AMMDeposit.ts +++ b/packages/xrpl/src/models/transactions/AMMDeposit.ts @@ -75,7 +75,7 @@ export function validateAMMDeposit(tx: Record): void { throw new ValidationError('AMMDeposit: must set Asset1In with EPrice') } else if (tx.LPToken == null && tx.Asset1In == null) { throw new ValidationError( - 'AMMDeposit: must set either or both LPToken with Asset1In', + 'AMMDeposit: must set at least LPToken or Asset1In', ) } diff --git a/packages/xrpl/src/models/transactions/AMMWithdraw.ts b/packages/xrpl/src/models/transactions/AMMWithdraw.ts index 1c777f78..9e222e04 100644 --- a/packages/xrpl/src/models/transactions/AMMWithdraw.ts +++ b/packages/xrpl/src/models/transactions/AMMWithdraw.ts @@ -77,7 +77,7 @@ export function validateAMMWithdraw(tx: Record): void { throw new ValidationError('AMMWithdraw: must set Asset1Out with EPrice') } else if (tx.LPToken == null && tx.Asset1Out == null) { throw new ValidationError( - 'AMMWithdraw: must set either or both LPToken with Asset1Out', + 'AMMWithdraw: must set at least LPToken or Asset1Out', ) } diff --git a/packages/xrpl/test/models/AMMDeposit.ts b/packages/xrpl/test/models/AMMDeposit.ts index d10eb64c..1d54ba25 100644 --- a/packages/xrpl/test/models/AMMDeposit.ts +++ b/packages/xrpl/test/models/AMMDeposit.ts @@ -69,11 +69,11 @@ describe('AMMDeposit', function () { ) }) - it(`throws w/ must set either or both LPToken with Asset1In`, function () { + it(`throws w/ must set at least LPToken or Asset1In`, function () { assert.throws( () => validate(deposit), ValidationError, - 'AMMDeposit: must set either or both LPToken with Asset1In', + 'AMMDeposit: must set at least LPToken or Asset1In', ) }) diff --git a/packages/xrpl/test/models/AMMWithdraw.ts b/packages/xrpl/test/models/AMMWithdraw.ts index a2fc2d9f..68fdd314 100644 --- a/packages/xrpl/test/models/AMMWithdraw.ts +++ b/packages/xrpl/test/models/AMMWithdraw.ts @@ -69,11 +69,11 @@ describe('AMMWithdraw', function () { ) }) - it(`throws w/ must set either or both LPToken with Asset1Out`, function () { + it(`throws w/ must set at least LPToken or Asset1Out`, function () { assert.throws( () => validate(withdraw), ValidationError, - 'AMMWithdraw: must set either or both LPToken with Asset1Out', + 'AMMWithdraw: must set at least LPToken or Asset1Out', ) }) From 85b8a3930b3b4c3a506f41cf5bcc18413bc9e0db Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 30 Aug 2022 19:09:55 -0400 Subject: [PATCH 26/61] add negative TradingFee check --- .../src/models/transactions/AMMInstanceCreate.ts | 4 ++-- packages/xrpl/test/models/AMMInstanceCreate.ts | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts b/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts index dec294e9..23faa330 100644 --- a/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts +++ b/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts @@ -68,9 +68,9 @@ export function validateAMMInstanceCreate(tx: Record): void { throw new ValidationError('AMMInstanceCreate: TradingFee must be a number') } - if (tx.TradingFee > AMM_MAX_TRADING_FEE) { + if (tx.TradingFee < 0 || tx.TradingFee > AMM_MAX_TRADING_FEE) { throw new ValidationError( - `AMMInstanceCreate: TradingFee must not be greater than ${AMM_MAX_TRADING_FEE}`, + `AMMInstanceCreate: TradingFee must be between 0 and ${AMM_MAX_TRADING_FEE}`, ) } } diff --git a/packages/xrpl/test/models/AMMInstanceCreate.ts b/packages/xrpl/test/models/AMMInstanceCreate.ts index 04d2a677..8e4f1597 100644 --- a/packages/xrpl/test/models/AMMInstanceCreate.ts +++ b/packages/xrpl/test/models/AMMInstanceCreate.ts @@ -82,12 +82,21 @@ describe('AMMInstanceCreate', function () { ) }) - it(`throws w/ TradingFee must not be greater than 65000`, function () { + it(`throws when TradingFee is greater than 65000`, function () { instanceCreate.TradingFee = 65001 assert.throws( () => validate(instanceCreate), ValidationError, - `AMMInstanceCreate: TradingFee must not be greater than 65000`, + `AMMInstanceCreate: TradingFee must be between 0 and 65000`, + ) + }) + + it(`throws when TradingFee is a negative number`, function () { + instanceCreate.TradingFee = -1 + assert.throws( + () => validate(instanceCreate), + ValidationError, + `AMMInstanceCreate: TradingFee must be between 0 and 65000`, ) }) }) From a174d09489c532e2ade183f86b925e9ff1da3da0 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 1 Sep 2022 23:13:13 -0400 Subject: [PATCH 27/61] fix ammInfo response --- packages/xrpl/src/models/methods/ammInfo.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 93755a2d..ea36096d 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -41,11 +41,6 @@ export interface AMMInfoResponse extends BaseResponse { */ AMMAccount: string - /** - * A hash that uniquely identifies the AMM instance. - */ - AMMID: string - /** * Specifies one of the pool assets (XRP or token) of the AMM instance. */ From 533c8ab9ac9efa7299d5dd5159d9ee7ef44674d7 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Fri, 2 Sep 2022 00:05:48 -0400 Subject: [PATCH 28/61] add AMMID as optional param in ammInfo response --- packages/xrpl/src/models/methods/ammInfo.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index ea36096d..0fb1e60d 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -68,6 +68,11 @@ export interface AMMInfoResponse extends BaseResponse { */ TradingFee: number + /** + * A hash that uniquely identifies the AMM instance. + */ + AMMID?: string + /** * The ledger index of the current in-progress ledger, which was used when * retrieving this information. From c0e0c15fc17dc9c87a3ff8c72c5e9c1352ea8fca Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Fri, 2 Sep 2022 00:18:45 -0400 Subject: [PATCH 29/61] fix EPrice validation checks in AMMDeposit & AMMWithdraw --- packages/xrpl/src/models/transactions/AMMDeposit.ts | 2 +- packages/xrpl/src/models/transactions/AMMWithdraw.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMDeposit.ts b/packages/xrpl/src/models/transactions/AMMDeposit.ts index b28ca0ae..0b62664a 100644 --- a/packages/xrpl/src/models/transactions/AMMDeposit.ts +++ b/packages/xrpl/src/models/transactions/AMMDeposit.ts @@ -93,7 +93,7 @@ export function validateAMMDeposit(tx: Record): void { throw new ValidationError('AMMDeposit: Asset2In must be an Amount') } - if (tx.EPrice != null && typeof tx.EPrice !== 'string') { + if (tx.EPrice != null && typeof !isAmount(tx.EPrice)) { throw new ValidationError('AMMDeposit: EPrice must be an Amount') } } diff --git a/packages/xrpl/src/models/transactions/AMMWithdraw.ts b/packages/xrpl/src/models/transactions/AMMWithdraw.ts index 9e222e04..8fdf059d 100644 --- a/packages/xrpl/src/models/transactions/AMMWithdraw.ts +++ b/packages/xrpl/src/models/transactions/AMMWithdraw.ts @@ -95,7 +95,7 @@ export function validateAMMWithdraw(tx: Record): void { throw new ValidationError('AMMWithdraw: Asset2Out must be an Amount') } - if (tx.EPrice != null && typeof tx.EPrice !== 'string') { + if (tx.EPrice != null && typeof !isAmount(tx.EPrice)) { throw new ValidationError('AMMWithdraw: EPrice must be an Amount') } } From 56b70aa8453e4d9485dee782e9eecae8eff5aa4d Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 5 Sep 2022 14:35:19 -0400 Subject: [PATCH 30/61] add VoteSlots as optional param in AMMInfoResponse --- packages/xrpl/src/models/methods/ammInfo.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 0fb1e60d..529c2a86 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -29,6 +29,14 @@ export interface AMMInfoRequest extends BaseRequest { asset2?: Amount } +interface VoteEntry { + VoteEntry: { + Account: string + FeeVal: number + VoteWeight: number + } +} + /** * Response expected from an {@link AMMInfoRequest}. * @@ -73,6 +81,11 @@ export interface AMMInfoResponse extends BaseResponse { */ AMMID?: string + /** + * Keeps a track of up to eight active votes for the instance. + */ + VoteSlots?: VoteEntry[] + /** * The ledger index of the current in-progress ledger, which was used when * retrieving this information. From aed4353c6cb057ba052d455fa167f5281b99c9a2 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 5 Sep 2022 14:46:47 -0400 Subject: [PATCH 31/61] update VoteEntry interface --- packages/xrpl/src/models/methods/ammInfo.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 529c2a86..8e70e3ad 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -30,11 +30,8 @@ export interface AMMInfoRequest extends BaseRequest { } interface VoteEntry { - VoteEntry: { - Account: string - FeeVal: number - VoteWeight: number - } + FeeVal: number + VoteWeight: number } /** From 220d9fb1b0e913dbdd86c2152aa09a88f42d693d Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Tue, 13 Sep 2022 13:53:44 -0400 Subject: [PATCH 32/61] fix deposit and withdraw tests --- packages/xrpl/src/models/transactions/AMMDeposit.ts | 2 +- packages/xrpl/src/models/transactions/AMMWithdraw.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMDeposit.ts b/packages/xrpl/src/models/transactions/AMMDeposit.ts index 0b62664a..66616d08 100644 --- a/packages/xrpl/src/models/transactions/AMMDeposit.ts +++ b/packages/xrpl/src/models/transactions/AMMDeposit.ts @@ -93,7 +93,7 @@ export function validateAMMDeposit(tx: Record): void { throw new ValidationError('AMMDeposit: Asset2In must be an Amount') } - if (tx.EPrice != null && typeof !isAmount(tx.EPrice)) { + if (tx.EPrice != null && !isAmount(tx.EPrice)) { throw new ValidationError('AMMDeposit: EPrice must be an Amount') } } diff --git a/packages/xrpl/src/models/transactions/AMMWithdraw.ts b/packages/xrpl/src/models/transactions/AMMWithdraw.ts index 8fdf059d..ae997466 100644 --- a/packages/xrpl/src/models/transactions/AMMWithdraw.ts +++ b/packages/xrpl/src/models/transactions/AMMWithdraw.ts @@ -95,7 +95,7 @@ export function validateAMMWithdraw(tx: Record): void { throw new ValidationError('AMMWithdraw: Asset2Out must be an Amount') } - if (tx.EPrice != null && typeof !isAmount(tx.EPrice)) { + if (tx.EPrice != null && !isAmount(tx.EPrice)) { throw new ValidationError('AMMWithdraw: EPrice must be an Amount') } } From a80f159e013773074ce6c7eb1660d78f2c48acc2 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 14 Sep 2022 21:52:54 -0400 Subject: [PATCH 33/61] fix AMMBid ValidationError --- packages/xrpl/src/models/transactions/AMMBid.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/xrpl/src/models/transactions/AMMBid.ts b/packages/xrpl/src/models/transactions/AMMBid.ts index 94a26569..e02c3cc2 100644 --- a/packages/xrpl/src/models/transactions/AMMBid.ts +++ b/packages/xrpl/src/models/transactions/AMMBid.ts @@ -74,7 +74,9 @@ export function validateAMMBid(tx: Record): void { if (tx.AuthAccounts != null) { if (!Array.isArray(tx.AuthAccounts)) { - throw new ValidationError(`AMMBid: AuthAccounts must be a string array`) + throw new ValidationError( + `AMMBid: AuthAccounts must be an AuthAccount array`, + ) } if (tx.AuthAccounts.length > MAX_AUTH_ACCOUNTS) { throw new ValidationError( From a2bce8f51371b9ad2ba1eacb3440d2d9a4c26555 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 15 Sep 2022 15:24:42 -0400 Subject: [PATCH 34/61] update definitions.json with different AuthAccounts number --- .../src/enums/definitions.json | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/ripple-binary-codec/src/enums/definitions.json b/packages/ripple-binary-codec/src/enums/definitions.json index cc0fc1d0..2c3b655c 100644 --- a/packages/ripple-binary-codec/src/enums/definitions.json +++ b/packages/ripple-binary-codec/src/enums/definitions.json @@ -2402,16 +2402,6 @@ "type": "STArray" } ], - [ - "AuthAccounts", - { - "nth": 21, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STArray" - } - ], [ "Majorities", { @@ -2461,6 +2451,16 @@ "isSigningField": true, "type": "STArray" } + ], + [ + "AuthAccounts", + { + "nth": 26, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "STArray" + } ] ], "TRANSACTION_RESULTS": { From a76aeb223316d5723383c4261ea3c18a2ab30189 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 31 Oct 2022 13:55:50 -0400 Subject: [PATCH 35/61] Change amm_info asset parameters to Currency type --- packages/xrpl/src/models/methods/ammInfo.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 8e70e3ad..4d51ccdd 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -1,4 +1,4 @@ -import { Amount, IssuedCurrencyAmount } from '../common' +import { Amount, Currency, IssuedCurrencyAmount } from '../common' import { BaseRequest, BaseResponse } from './baseMethod' @@ -20,13 +20,13 @@ export interface AMMInfoRequest extends BaseRequest { * Specifies one of the pool assets (XRP or token) of the AMM instance. * Both asset1 and asset2 must be defined to specify an AMM instance. */ - asset1?: Amount + asset1?: Currency /** * Specifies the other pool asset of the AMM instance. * Both asset1 and asset2 must be defined to specify an AMM instance. */ - asset2?: Amount + asset2?: Currency } interface VoteEntry { From acdfbd55e56bec1ea4d2b9db8095ded7610de694 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 10:07:39 -0500 Subject: [PATCH 36/61] API name changes with updated definitions.json --- .../src/enums/definitions.json | 147 ++++-------------- .../xrpl/src/models/transactions/AMMBid.ts | 14 +- .../{AMMInstanceCreate.ts => AMMCreate.ts} | 40 ++--- .../src/models/transactions/AMMDeposit.ts | 44 +++--- .../xrpl/src/models/transactions/AMMVote.ts | 16 +- .../src/models/transactions/AMMWithdraw.ts | 44 +++--- .../xrpl/src/models/transactions/index.ts | 2 +- .../src/models/transactions/transaction.ts | 11 +- packages/xrpl/test/models/AMMBid.ts | 16 +- packages/xrpl/test/models/AMMCreate.ts | 102 ++++++++++++ packages/xrpl/test/models/AMMDeposit.ts | 62 ++++---- .../xrpl/test/models/AMMInstanceCreate.ts | 102 ------------ packages/xrpl/test/models/AMMVote.ts | 26 ++-- packages/xrpl/test/models/AMMWithdraw.ts | 62 ++++---- 14 files changed, 303 insertions(+), 385 deletions(-) rename packages/xrpl/src/models/transactions/{AMMInstanceCreate.ts => AMMCreate.ts} (50%) create mode 100644 packages/xrpl/test/models/AMMCreate.ts delete mode 100644 packages/xrpl/test/models/AMMInstanceCreate.ts diff --git a/packages/ripple-binary-codec/src/enums/definitions.json b/packages/ripple-binary-codec/src/enums/definitions.json index 2c3b655c..55bbac88 100644 --- a/packages/ripple-binary-codec/src/enums/definitions.json +++ b/packages/ripple-binary-codec/src/enums/definitions.json @@ -21,6 +21,7 @@ "UInt192": 21, "UInt384": 22, "UInt512": 23, + "Issue": 24, "Transaction": 10001, "LedgerEntry": 10002, "Validation": 10003, @@ -773,7 +774,7 @@ } ], [ - "FeeVal", + "VoteWeight", { "nth": 47, "isVLEncoded": false, @@ -782,30 +783,10 @@ "type": "UInt32" } ], - [ - "VoteWeight", - { - "nth": 48, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], - [ - "TimeStamp", - { - "nth": 49, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "UInt32" - } - ], [ "DiscountedFee", { - "nth": 50, + "nth": 48, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1463,7 +1444,7 @@ } ], [ - "Asset1", + "Amount2", { "nth": 11, "isVLEncoded": false, @@ -1473,7 +1454,7 @@ } ], [ - "Asset2", + "MinBidPrice", { "nth": 12, "isVLEncoded": false, @@ -1483,7 +1464,7 @@ } ], [ - "MinSlotPrice", + "MaxBidPrice", { "nth": 13, "isVLEncoded": false, @@ -1492,16 +1473,6 @@ "type": "Amount" } ], - [ - "MaxSlotPrice", - { - "nth": 14, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], [ "MinimumOffer", { @@ -1543,7 +1514,7 @@ } ], [ - "Asset1In", + "LPTokenOut", { "nth": 20, "isVLEncoded": false, @@ -1553,7 +1524,7 @@ } ], [ - "Asset2In", + "LPTokenIn", { "nth": 21, "isVLEncoded": false, @@ -1563,7 +1534,7 @@ } ], [ - "Asset1Out", + "EPrice", { "nth": 22, "isVLEncoded": false, @@ -1573,7 +1544,7 @@ } ], [ - "Asset2Out", + "Price", { "nth": 23, "isVLEncoded": false, @@ -1582,40 +1553,10 @@ "type": "Amount" } ], - [ - "LPToken", - { - "nth": 24, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "EPrice", - { - "nth": 25, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], - [ - "Price", - { - "nth": 26, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Amount" - } - ], [ "LPTokenBalance", { - "nth": 27, + "nth": 24, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -2022,6 +1963,26 @@ "type": "PathSet" } ], + [ + "Asset", + { + "nth": 1, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Issue" + } + ], + [ + "Asset2", + { + "nth": 2, + "isVLEncoded": false, + "isSerialized": true, + "isSigningField": true, + "type": "Issue" + } + ], [ "TransactionMetaData", { @@ -2152,16 +2113,6 @@ "type": "STObject" } ], - [ - "AMM", - { - "nth": 15, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], [ "Signer", { @@ -2272,36 +2223,6 @@ "type": "STObject" } ], - [ - "AMMToken", - { - "nth": 29, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "Token1", - { - "nth": 30, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], - [ - "Token2", - { - "nth": 31, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "STObject" - } - ], [ "Signers", { @@ -2553,6 +2474,7 @@ "terNO_RIPPLE": -90, "terQUEUED": -89, "terPRE_TICKET": -88, + "terNO_AMM": -87, "tesSUCCESS": 0, @@ -2609,8 +2531,7 @@ "tecAMM_INVALID_TOKENS": 166, "tecAMM_EXISTS": 167, "tecAMM_FAILED_BID": 168, - "tecAMM_DIRECT_PAYMENT": 169, - "tecAMM_FAILED_VOTE": 170 + "tecAMM_FAILED_VOTE": 169 }, "TRANSACTION_TYPES": { "Invalid": -1, @@ -2642,7 +2563,7 @@ "NFTokenCreateOffer": 27, "NFTokenCancelOffer": 28, "NFTokenAcceptOffer": 29, - "AMMInstanceCreate": 35, + "AMMCreate": 35, "AMMDeposit": 36, "AMMWithdraw": 37, "AMMVote": 38, diff --git a/packages/xrpl/src/models/transactions/AMMBid.ts b/packages/xrpl/src/models/transactions/AMMBid.ts index e02c3cc2..cc74a2f2 100644 --- a/packages/xrpl/src/models/transactions/AMMBid.ts +++ b/packages/xrpl/src/models/transactions/AMMBid.ts @@ -27,17 +27,17 @@ export interface AMMBid extends BaseTransaction { /** * This field represents the minimum price that the bidder wants to pay for the slot. - * It is specified in units of LPToken. If specified let MinSlotPrice be X and let + * It is specified in units of LPToken. If specified let MinBidPrice be X and let * the slot-price computed by price scheduling algorithm be Y, then bidder always pays * the max(X, Y). */ - MinSlotPrice?: Amount + MinBidPrice?: Amount /** * This field represents the maximum price that the bidder wants to pay for the slot. * It is specified in units of LPToken. */ - MaxSlotPrice?: Amount + MaxBidPrice?: Amount /** * This field represents an array of XRPL account IDs that are authorized to trade @@ -64,12 +64,12 @@ export function validateAMMBid(tx: Record): void { throw new ValidationError('AMMBid: AMMID must be a string') } - if (tx.MinSlotPrice != null && !isAmount(tx.MinSlotPrice)) { - throw new ValidationError('AMMBid: MinSlotPrice must be an Amount') + if (tx.MinBidPrice != null && !isAmount(tx.MinBidPrice)) { + throw new ValidationError('AMMBid: MinBidPrice must be an Amount') } - if (tx.MaxSlotPrice != null && !isAmount(tx.MaxSlotPrice)) { - throw new ValidationError('AMMBid: MaxSlotPrice must be an Amount') + if (tx.MaxBidPrice != null && !isAmount(tx.MaxBidPrice)) { + throw new ValidationError('AMMBid: MaxBidPrice must be an Amount') } if (tx.AuthAccounts != null) { diff --git a/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts b/packages/xrpl/src/models/transactions/AMMCreate.ts similarity index 50% rename from packages/xrpl/src/models/transactions/AMMInstanceCreate.ts rename to packages/xrpl/src/models/transactions/AMMCreate.ts index 23faa330..fbeda32d 100644 --- a/packages/xrpl/src/models/transactions/AMMInstanceCreate.ts +++ b/packages/xrpl/src/models/transactions/AMMCreate.ts @@ -6,23 +6,23 @@ import { BaseTransaction, isAmount, validateBaseTransaction } from './common' export const AMM_MAX_TRADING_FEE = 65000 /** - * AMMInstanceCreate is used to create AccountRoot and the corresponding + * AMMCreate is used to create AccountRoot and the corresponding * AMM ledger entries. * * This allows for the creation of only one AMM instance per unique asset pair. */ -export interface AMMInstanceCreate extends BaseTransaction { - TransactionType: 'AMMInstanceCreate' +export interface AMMCreate extends BaseTransaction { + TransactionType: 'AMMCreate' /** * Specifies one of the pool assets (XRP or token) of the AMM instance. */ - Asset1: Amount + Amount: Amount /** * Specifies the other pool asset of the AMM instance. */ - Asset2: Amount + Amount2: Amount /** * Specifies the fee, in basis point, to be charged @@ -36,41 +36,41 @@ export interface AMMInstanceCreate extends BaseTransaction { } /** - * Verify the form and type of an AMMInstanceCreate at runtime. + * Verify the form and type of an AMMCreate at runtime. * - * @param tx - An AMMInstanceCreate Transaction. - * @throws When the AMMInstanceCreate is Malformed. + * @param tx - An AMMCreate Transaction. + * @throws When the AMMCreate is Malformed. */ -export function validateAMMInstanceCreate(tx: Record): void { +export function validateAMMCreate(tx: Record): void { validateBaseTransaction(tx) - if (tx.Asset1 == null) { - throw new ValidationError('AMMInstanceCreate: missing field Asset1') + if (tx.Amount == null) { + throw new ValidationError('AMMCreate: missing field Amount') } - if (!isAmount(tx.Asset1)) { - throw new ValidationError('AMMInstanceCreate: Asset1 must be an Amount') + if (!isAmount(tx.Amount)) { + throw new ValidationError('AMMCreate: Amount must be an Amount') } - if (tx.Asset2 == null) { - throw new ValidationError('AMMInstanceCreate: missing field Asset2') + if (tx.Amount2 == null) { + throw new ValidationError('AMMCreate: missing field Amount2') } - if (!isAmount(tx.Asset2)) { - throw new ValidationError('AMMInstanceCreate: Asset2 must be an Amount') + if (!isAmount(tx.Amount2)) { + throw new ValidationError('AMMCreate: Amount2 must be an Amount') } if (tx.TradingFee == null) { - throw new ValidationError('AMMInstanceCreate: missing field TradingFee') + throw new ValidationError('AMMCreate: missing field TradingFee') } if (typeof tx.TradingFee !== 'number') { - throw new ValidationError('AMMInstanceCreate: TradingFee must be a number') + throw new ValidationError('AMMCreate: TradingFee must be a number') } if (tx.TradingFee < 0 || tx.TradingFee > AMM_MAX_TRADING_FEE) { throw new ValidationError( - `AMMInstanceCreate: TradingFee must be between 0 and ${AMM_MAX_TRADING_FEE}`, + `AMMCreate: TradingFee must be between 0 and ${AMM_MAX_TRADING_FEE}`, ) } } diff --git a/packages/xrpl/src/models/transactions/AMMDeposit.ts b/packages/xrpl/src/models/transactions/AMMDeposit.ts index 66616d08..6132464d 100644 --- a/packages/xrpl/src/models/transactions/AMMDeposit.ts +++ b/packages/xrpl/src/models/transactions/AMMDeposit.ts @@ -11,14 +11,14 @@ import { /** * AMMDeposit is the deposit transaction used to add liquidity to the AMM instance pool, - * thus obtaining some share of the instance's pools in the form of LPToken. + * thus obtaining some share of the instance's pools in the form of LPTokenOut. * * The following are the recommended valid combinations: - * - LPToken - * - Asset1In - * - Asset1In and Asset2In - * - Asset1In and LPToken - * - Asset1In and EPrice + * - LPTokenOut + * - Amount + * - Amount and Amount2 + * - Amount and LPTokenOut + * - Amount and EPrice */ export interface AMMDeposit extends BaseTransaction { TransactionType: 'AMMDeposit' @@ -32,22 +32,22 @@ export interface AMMDeposit extends BaseTransaction { * Specifies the amount of shares of the AMM instance pools that the trader * wants to redeem or trade in. */ - LPToken?: IssuedCurrencyAmount + LPTokenOut?: IssuedCurrencyAmount /** * Specifies one of the pool assets (XRP or token) of the AMM instance to * deposit more of its value. */ - Asset1In?: Amount + Amount?: Amount /** * Specifies the other pool asset of the AMM instance to deposit more of * its value. */ - Asset2In?: Amount + Amount2?: Amount /** - * Specifies the maximum effective-price that LPToken can be traded out. + * Specifies the maximum effective-price that LPTokenOut can be traded out. */ EPrice?: Amount } @@ -69,28 +69,28 @@ export function validateAMMDeposit(tx: Record): void { throw new ValidationError('AMMDeposit: AMMID must be a string') } - if (tx.Asset2In != null && tx.Asset1In == null) { - throw new ValidationError('AMMDeposit: must set Asset1In with Asset2In') - } else if (tx.EPrice != null && tx.Asset1In == null) { - throw new ValidationError('AMMDeposit: must set Asset1In with EPrice') - } else if (tx.LPToken == null && tx.Asset1In == null) { + if (tx.Amount2 != null && tx.Amount == null) { + throw new ValidationError('AMMDeposit: must set Amount with Amount2') + } else if (tx.EPrice != null && tx.Amount == null) { + throw new ValidationError('AMMDeposit: must set Amount with EPrice') + } else if (tx.LPTokenOut == null && tx.Amount == null) { throw new ValidationError( - 'AMMDeposit: must set at least LPToken or Asset1In', + 'AMMDeposit: must set at least LPTokenOut or Amount', ) } - if (tx.LPToken != null && !isIssuedCurrency(tx.LPToken)) { + if (tx.LPTokenOut != null && !isIssuedCurrency(tx.LPTokenOut)) { throw new ValidationError( - 'AMMDeposit: LPToken must be an IssuedCurrencyAmount', + 'AMMDeposit: LPTokenOut must be an IssuedCurrencyAmount', ) } - if (tx.Asset1In != null && !isAmount(tx.Asset1In)) { - throw new ValidationError('AMMDeposit: Asset1In must be an Amount') + if (tx.Amount != null && !isAmount(tx.Amount)) { + throw new ValidationError('AMMDeposit: Amount must be an Amount') } - if (tx.Asset2In != null && !isAmount(tx.Asset2In)) { - throw new ValidationError('AMMDeposit: Asset2In must be an Amount') + if (tx.Amount2 != null && !isAmount(tx.Amount2)) { + throw new ValidationError('AMMDeposit: Amount2 must be an Amount') } if (tx.EPrice != null && !isAmount(tx.EPrice)) { diff --git a/packages/xrpl/src/models/transactions/AMMVote.ts b/packages/xrpl/src/models/transactions/AMMVote.ts index 270a4141..bc69f9d4 100644 --- a/packages/xrpl/src/models/transactions/AMMVote.ts +++ b/packages/xrpl/src/models/transactions/AMMVote.ts @@ -1,6 +1,6 @@ import { ValidationError } from '../../errors' -import { AMM_MAX_TRADING_FEE } from './AMMInstanceCreate' +import { AMM_MAX_TRADING_FEE } from './AMMCreate' import { BaseTransaction, validateBaseTransaction } from './common' /** @@ -23,7 +23,7 @@ export interface AMMVote extends BaseTransaction { * 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 + TradingFee: number } /** @@ -43,17 +43,17 @@ export function validateAMMVote(tx: Record): void { throw new ValidationError('AMMVote: AMMID must be a string') } - if (tx.FeeVal == null) { - throw new ValidationError('AMMVote: missing field FeeVal') + if (tx.TradingFee == null) { + throw new ValidationError('AMMVote: missing field TradingFee') } - if (typeof tx.FeeVal !== 'number') { - throw new ValidationError('AMMVote: FeeVal must be a number') + if (typeof tx.TradingFee !== 'number') { + throw new ValidationError('AMMVote: TradingFee must be a number') } - if (tx.FeeVal < 0 || tx.FeeVal > AMM_MAX_TRADING_FEE) { + if (tx.TradingFee < 0 || tx.TradingFee > AMM_MAX_TRADING_FEE) { throw new ValidationError( - `AMMVote: FeeVal must be between 0 and ${AMM_MAX_TRADING_FEE}`, + `AMMVote: TradingFee must be between 0 and ${AMM_MAX_TRADING_FEE}`, ) } } diff --git a/packages/xrpl/src/models/transactions/AMMWithdraw.ts b/packages/xrpl/src/models/transactions/AMMWithdraw.ts index ae997466..04a6cb8b 100644 --- a/packages/xrpl/src/models/transactions/AMMWithdraw.ts +++ b/packages/xrpl/src/models/transactions/AMMWithdraw.ts @@ -12,14 +12,14 @@ import { /** * AMMWithdraw is the withdraw transaction used to remove liquidity from the AMM * instance pool, thus redeeming some share of the pools that one owns in the form - * of LPToken. + * of LPTokenIn. * * The following are the recommended valid combinations: - * - LPToken - * - Asset1Out - * - Asset1Out and Asset2Out - * - Asset1Out and LPToken - * - Asset1Out and EPrice + * - LPTokenIn + * - Amount + * - Amount and Amount2 + * - Amount and LPTokenIn + * - Amount and EPrice */ export interface AMMWithdraw extends BaseTransaction { TransactionType: 'AMMWithdraw' @@ -33,19 +33,19 @@ export interface AMMWithdraw extends BaseTransaction { * Specifies the amount of shares of the AMM instance pools that the trader * wants to redeem or trade in. */ - LPToken?: IssuedCurrencyAmount + LPTokenIn?: IssuedCurrencyAmount /** * Specifies one of the pools assets that the trader wants to remove. - * If the asset is XRP, then the Asset1Out is a string specifying the number of drops. + * If the asset is XRP, then the Amount is a string specifying the number of drops. * Otherwise it is an IssuedCurrencyAmount object. */ - Asset1Out?: Amount + Amount?: Amount /** * Specifies the other pool asset that the trader wants to remove. */ - Asset2Out?: Amount + Amount2?: Amount /** * Specifies the effective-price of the token out after successful execution of @@ -71,28 +71,28 @@ export function validateAMMWithdraw(tx: Record): void { throw new ValidationError('AMMWithdraw: AMMID must be a string') } - if (tx.Asset2Out != null && tx.Asset1Out == null) { - throw new ValidationError('AMMWithdraw: must set Asset1Out with Asset2Out') - } else if (tx.EPrice != null && tx.Asset1Out == null) { - throw new ValidationError('AMMWithdraw: must set Asset1Out with EPrice') - } else if (tx.LPToken == null && tx.Asset1Out == null) { + if (tx.Amount2 != null && tx.Amount == null) { + throw new ValidationError('AMMWithdraw: must set Amount with Amount2') + } else if (tx.EPrice != null && tx.Amount == null) { + throw new ValidationError('AMMWithdraw: must set Amount with EPrice') + } else if (tx.LPTokenIn == null && tx.Amount == null) { throw new ValidationError( - 'AMMWithdraw: must set at least LPToken or Asset1Out', + 'AMMWithdraw: must set at least LPTokenIn or Amount', ) } - if (tx.LPToken != null && !isIssuedCurrency(tx.LPToken)) { + if (tx.LPTokenIn != null && !isIssuedCurrency(tx.LPTokenIn)) { throw new ValidationError( - 'AMMWithdraw: LPToken must be an IssuedCurrencyAmount', + 'AMMWithdraw: LPTokenIn must be an IssuedCurrencyAmount', ) } - if (tx.Asset1Out != null && !isAmount(tx.Asset1Out)) { - throw new ValidationError('AMMWithdraw: Asset1Out must be an Amount') + if (tx.Amount != null && !isAmount(tx.Amount)) { + throw new ValidationError('AMMWithdraw: Amount must be an Amount') } - if (tx.Asset2Out != null && !isAmount(tx.Asset2Out)) { - throw new ValidationError('AMMWithdraw: Asset2Out must be an Amount') + if (tx.Amount2 != null && !isAmount(tx.Amount2)) { + throw new ValidationError('AMMWithdraw: Amount2 must be an Amount') } if (tx.EPrice != null && !isAmount(tx.EPrice)) { diff --git a/packages/xrpl/src/models/transactions/index.ts b/packages/xrpl/src/models/transactions/index.ts index 187b308e..a9b5c26c 100644 --- a/packages/xrpl/src/models/transactions/index.ts +++ b/packages/xrpl/src/models/transactions/index.ts @@ -9,7 +9,7 @@ export { export { AccountDelete } from './accountDelete' export { AMMBid } from './AMMBid' export { AMMDeposit } from './AMMDeposit' -export { AMMInstanceCreate } from './AMMInstanceCreate' +export { AMMCreate } from './AMMCreate' export { AMMVote } from './AMMVote' export { AMMWithdraw } from './AMMWithdraw' export { CheckCancel } from './checkCancel' diff --git a/packages/xrpl/src/models/transactions/transaction.ts b/packages/xrpl/src/models/transactions/transaction.ts index 1b5c6624..e6ad2fc5 100644 --- a/packages/xrpl/src/models/transactions/transaction.ts +++ b/packages/xrpl/src/models/transactions/transaction.ts @@ -11,10 +11,7 @@ import { AccountDelete, validateAccountDelete } from './accountDelete' import { AccountSet, validateAccountSet } from './accountSet' import { AMMBid, validateAMMBid } from './AMMBid' import { AMMDeposit, validateAMMDeposit } from './AMMDeposit' -import { - AMMInstanceCreate, - validateAMMInstanceCreate, -} from './AMMInstanceCreate' +import { AMMCreate, validateAMMCreate } from './AMMCreate' import { AMMVote, validateAMMVote } from './AMMVote' import { AMMWithdraw, validateAMMWithdraw } from './AMMWithdraw' import { CheckCancel, validateCheckCancel } from './checkCancel' @@ -67,7 +64,7 @@ export type Transaction = | AccountSet | AMMBid | AMMDeposit - | AMMInstanceCreate + | AMMCreate | AMMVote | AMMWithdraw | CheckCancel @@ -136,8 +133,8 @@ export function validate(transaction: Record): void { validateAMMDeposit(tx) break - case 'AMMInstanceCreate': - validateAMMInstanceCreate(tx) + case 'AMMCreate': + validateAMMCreate(tx) break case 'AMMVote': diff --git a/packages/xrpl/test/models/AMMBid.ts b/packages/xrpl/test/models/AMMBid.ts index ece8b692..08e07a8c 100644 --- a/packages/xrpl/test/models/AMMBid.ts +++ b/packages/xrpl/test/models/AMMBid.ts @@ -14,8 +14,8 @@ describe('AMMBid', function () { TransactionType: 'AMMBid', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - MinSlotPrice: '5', - MaxSlotPrice: '10', + MinBidPrice: '5', + MaxBidPrice: '10', AuthAccounts: [ { AuthAccount: { @@ -64,21 +64,21 @@ describe('AMMBid', function () { ) }) - it(`throws w/ MinSlotPrice must be an Amount`, function () { - bid.MinSlotPrice = 5 + it(`throws w/ MinBidPrice must be an Amount`, function () { + bid.MinBidPrice = 5 assert.throws( () => validate(bid), ValidationError, - 'AMMBid: MinSlotPrice must be an Amount', + 'AMMBid: MinBidPrice must be an Amount', ) }) - it(`throws w/ MaxSlotPrice must be an Amount`, function () { - bid.MaxSlotPrice = 10 + it(`throws w/ MaxBidPrice must be an Amount`, function () { + bid.MaxBidPrice = 10 assert.throws( () => validate(bid), ValidationError, - 'AMMBid: MaxSlotPrice must be an Amount', + 'AMMBid: MaxBidPrice must be an Amount', ) }) diff --git a/packages/xrpl/test/models/AMMCreate.ts b/packages/xrpl/test/models/AMMCreate.ts new file mode 100644 index 00000000..ce18ef9e --- /dev/null +++ b/packages/xrpl/test/models/AMMCreate.ts @@ -0,0 +1,102 @@ +import { assert } from 'chai' +import { validate, ValidationError } from 'xrpl-local' + +/** + * AMMCreate Transaction Verification Testing. + * + * Providing runtime verification testing for each specific transaction type. + */ +describe('AMMCreate', function () { + let ammCreate + + beforeEach(function () { + ammCreate = { + TransactionType: 'AMMCreate', + Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Amount: '1000', + Amount2: { + currency: 'USD', + issuer: 'rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9', + value: '1000', + }, + TradingFee: 12, + Sequence: 1337, + } as any + }) + + it(`verifies valid AMMCreate`, function () { + assert.doesNotThrow(() => validate(ammCreate)) + }) + + it(`throws w/ missing Amount`, function () { + delete ammCreate.Amount + assert.throws( + () => validate(ammCreate), + ValidationError, + 'AMMCreate: missing field Amount', + ) + }) + + it(`throws w/ Amount must be an Amount`, function () { + ammCreate.Amount = 1000 + assert.throws( + () => validate(ammCreate), + ValidationError, + 'AMMCreate: Amount must be an Amount', + ) + }) + + it(`throws w/ missing Amount2`, function () { + delete ammCreate.Amount2 + assert.throws( + () => validate(ammCreate), + ValidationError, + 'AMMCreate: missing field Amount2', + ) + }) + + it(`throws w/ Amount2 must be an Amount`, function () { + ammCreate.Amount2 = 1000 + assert.throws( + () => validate(ammCreate), + ValidationError, + 'AMMCreate: Amount2 must be an Amount', + ) + }) + + it(`throws w/ missing TradingFee`, function () { + delete ammCreate.TradingFee + assert.throws( + () => validate(ammCreate), + ValidationError, + 'AMMCreate: missing field TradingFee', + ) + }) + + it(`throws w/ TradingFee must be a number`, function () { + ammCreate.TradingFee = '12' + assert.throws( + () => validate(ammCreate), + ValidationError, + 'AMMCreate: TradingFee must be a number', + ) + }) + + it(`throws when TradingFee is greater than 65000`, function () { + ammCreate.TradingFee = 65001 + assert.throws( + () => validate(ammCreate), + ValidationError, + `AMMCreate: TradingFee must be between 0 and 65000`, + ) + }) + + it(`throws when TradingFee is a negative number`, function () { + ammCreate.TradingFee = -1 + assert.throws( + () => validate(ammCreate), + ValidationError, + `AMMCreate: TradingFee must be between 0 and 65000`, + ) + }) +}) diff --git a/packages/xrpl/test/models/AMMDeposit.ts b/packages/xrpl/test/models/AMMDeposit.ts index 1d54ba25..00a37440 100644 --- a/packages/xrpl/test/models/AMMDeposit.ts +++ b/packages/xrpl/test/models/AMMDeposit.ts @@ -7,7 +7,7 @@ import { validate, ValidationError } from 'xrpl-local' * Providing runtime verification testing for each specific transaction type. */ describe('AMMDeposit', function () { - const LPToken = { + const LPTokenOut = { currency: 'B3813FCAB4EE68B3D0D735D6849465A9113EE048', issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', value: '1000', @@ -23,30 +23,30 @@ describe('AMMDeposit', function () { } as any }) - it(`verifies valid AMMDeposit with LPToken`, function () { - deposit.LPToken = LPToken + it(`verifies valid AMMDeposit with LPTokenOut`, function () { + deposit.LPTokenOut = LPTokenOut assert.doesNotThrow(() => validate(deposit)) }) - it(`verifies valid AMMDeposit with Asset1In`, function () { - deposit.Asset1In = '1000' + it(`verifies valid AMMDeposit with Amount`, function () { + deposit.Amount = '1000' assert.doesNotThrow(() => validate(deposit)) }) - it(`verifies valid AMMDeposit with Asset1In and Asset2In`, function () { - deposit.Asset1In = '1000' - deposit.Asset2In = '1000' + it(`verifies valid AMMDeposit with Amount and Amount2`, function () { + deposit.Amount = '1000' + deposit.Amount2 = '1000' assert.doesNotThrow(() => validate(deposit)) }) - it(`verifies valid AMMDeposit with Asset1In and LPToken`, function () { - deposit.Asset1In = '1000' - deposit.LPToken = LPToken + it(`verifies valid AMMDeposit with Amount and LPTokenOut`, function () { + deposit.Amount = '1000' + deposit.LPTokenOut = LPTokenOut assert.doesNotThrow(() => validate(deposit)) }) - it(`verifies valid AMMDeposit with Asset1In and EPrice`, function () { - deposit.Asset1In = '1000' + it(`verifies valid AMMDeposit with Amount and EPrice`, function () { + deposit.Amount = '1000' deposit.EPrice = '25' assert.doesNotThrow(() => validate(deposit)) }) @@ -69,62 +69,62 @@ describe('AMMDeposit', function () { ) }) - it(`throws w/ must set at least LPToken or Asset1In`, function () { + it(`throws w/ must set at least LPTokenOut or Amount`, function () { assert.throws( () => validate(deposit), ValidationError, - 'AMMDeposit: must set at least LPToken or Asset1In', + 'AMMDeposit: must set at least LPTokenOut or Amount', ) }) - it(`throws w/ must set Asset1In with Asset2In`, function () { - deposit.Asset2In = '500' + it(`throws w/ must set Amount with Amount2`, function () { + deposit.Amount2 = '500' assert.throws( () => validate(deposit), ValidationError, - 'AMMDeposit: must set Asset1In with Asset2In', + 'AMMDeposit: must set Amount with Amount2', ) }) - it(`throws w/ must set Asset1In with EPrice`, function () { + it(`throws w/ must set Amount with EPrice`, function () { deposit.EPrice = '25' assert.throws( () => validate(deposit), ValidationError, - 'AMMDeposit: must set Asset1In with EPrice', + 'AMMDeposit: must set Amount with EPrice', ) }) - it(`throws w/ LPToken must be an IssuedCurrencyAmount`, function () { - deposit.LPToken = 1234 + it(`throws w/ LPTokenOut must be an IssuedCurrencyAmount`, function () { + deposit.LPTokenOut = 1234 assert.throws( () => validate(deposit), ValidationError, - 'AMMDeposit: LPToken must be an IssuedCurrencyAmount', + 'AMMDeposit: LPTokenOut must be an IssuedCurrencyAmount', ) }) - it(`throws w/ Asset1In must be an Amount`, function () { - deposit.Asset1In = 1234 + it(`throws w/ Amount must be an Amount`, function () { + deposit.Amount = 1234 assert.throws( () => validate(deposit), ValidationError, - 'AMMDeposit: Asset1In must be an Amount', + 'AMMDeposit: Amount must be an Amount', ) }) - it(`throws w/ Asset2In must be an Amount`, function () { - deposit.Asset1In = '1000' - deposit.Asset2In = 1234 + it(`throws w/ Amount2 must be an Amount`, function () { + deposit.Amount = '1000' + deposit.Amount2 = 1234 assert.throws( () => validate(deposit), ValidationError, - 'AMMDeposit: Asset2In must be an Amount', + 'AMMDeposit: Amount2 must be an Amount', ) }) it(`throws w/ EPrice must be an Amount`, function () { - deposit.Asset1In = '1000' + deposit.Amount = '1000' deposit.EPrice = 1234 assert.throws( () => validate(deposit), diff --git a/packages/xrpl/test/models/AMMInstanceCreate.ts b/packages/xrpl/test/models/AMMInstanceCreate.ts deleted file mode 100644 index 8e4f1597..00000000 --- a/packages/xrpl/test/models/AMMInstanceCreate.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { assert } from 'chai' -import { validate, ValidationError } from 'xrpl-local' - -/** - * AMMInstanceCreate Transaction Verification Testing. - * - * Providing runtime verification testing for each specific transaction type. - */ -describe('AMMInstanceCreate', function () { - let instanceCreate - - beforeEach(function () { - instanceCreate = { - TransactionType: 'AMMInstanceCreate', - Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - Asset1: '1000', - Asset2: { - currency: 'USD', - issuer: 'rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9', - value: '1000', - }, - TradingFee: 12, - Sequence: 1337, - } as any - }) - - it(`verifies valid AMMInstanceCreate`, function () { - assert.doesNotThrow(() => validate(instanceCreate)) - }) - - it(`throws w/ missing Asset1`, function () { - delete instanceCreate.Asset1 - assert.throws( - () => validate(instanceCreate), - ValidationError, - 'AMMInstanceCreate: missing field Asset1', - ) - }) - - it(`throws w/ Asset1 must be an Amount`, function () { - instanceCreate.Asset1 = 1000 - assert.throws( - () => validate(instanceCreate), - ValidationError, - 'AMMInstanceCreate: Asset1 must be an Amount', - ) - }) - - it(`throws w/ missing Asset2`, function () { - delete instanceCreate.Asset2 - assert.throws( - () => validate(instanceCreate), - ValidationError, - 'AMMInstanceCreate: missing field Asset2', - ) - }) - - it(`throws w/ Asset2 must be an Amount`, function () { - instanceCreate.Asset2 = 1000 - assert.throws( - () => validate(instanceCreate), - ValidationError, - 'AMMInstanceCreate: Asset2 must be an Amount', - ) - }) - - it(`throws w/ missing TradingFee`, function () { - delete instanceCreate.TradingFee - assert.throws( - () => validate(instanceCreate), - ValidationError, - 'AMMInstanceCreate: missing field TradingFee', - ) - }) - - it(`throws w/ TradingFee must be a number`, function () { - instanceCreate.TradingFee = '12' - assert.throws( - () => validate(instanceCreate), - ValidationError, - 'AMMInstanceCreate: TradingFee must be a number', - ) - }) - - it(`throws when TradingFee is greater than 65000`, function () { - instanceCreate.TradingFee = 65001 - assert.throws( - () => validate(instanceCreate), - ValidationError, - `AMMInstanceCreate: TradingFee must be between 0 and 65000`, - ) - }) - - it(`throws when TradingFee is a negative number`, function () { - instanceCreate.TradingFee = -1 - assert.throws( - () => validate(instanceCreate), - ValidationError, - `AMMInstanceCreate: TradingFee must be between 0 and 65000`, - ) - }) -}) diff --git a/packages/xrpl/test/models/AMMVote.ts b/packages/xrpl/test/models/AMMVote.ts index b7ae2852..b813d7b5 100644 --- a/packages/xrpl/test/models/AMMVote.ts +++ b/packages/xrpl/test/models/AMMVote.ts @@ -14,7 +14,7 @@ describe('AMMVote', function () { TransactionType: 'AMMVote', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', - FeeVal: 25, + TradingFee: 25, Sequence: 1337, } as any }) @@ -41,39 +41,39 @@ describe('AMMVote', function () { ) }) - it(`throws w/ missing field FeeVal`, function () { - delete vote.FeeVal + it(`throws w/ missing field TradingFee`, function () { + delete vote.TradingFee assert.throws( () => validate(vote), ValidationError, - 'AMMVote: missing field FeeVal', + 'AMMVote: missing field TradingFee', ) }) - it(`throws w/ FeeVal must be a number`, function () { - vote.FeeVal = '25' + it(`throws w/ TradingFee must be a number`, function () { + vote.TradingFee = '25' assert.throws( () => validate(vote), ValidationError, - 'AMMVote: FeeVal must be a number', + 'AMMVote: TradingFee must be a number', ) }) - it(`throws when FeeVal is greater than AMM_MAX_TRADING_FEE`, function () { - vote.FeeVal = 65001 + it(`throws when TradingFee is greater than AMM_MAX_TRADING_FEE`, function () { + vote.TradingFee = 65001 assert.throws( () => validate(vote), ValidationError, - 'AMMVote: FeeVal must be between 0 and 65000', + 'AMMVote: TradingFee must be between 0 and 65000', ) }) - it(`throws when FeeVal is a negative number`, function () { - vote.FeeVal = -1 + it(`throws when TradingFee is a negative number`, function () { + vote.TradingFee = -1 assert.throws( () => validate(vote), ValidationError, - 'AMMVote: FeeVal must be between 0 and 65000', + 'AMMVote: TradingFee must be between 0 and 65000', ) }) }) diff --git a/packages/xrpl/test/models/AMMWithdraw.ts b/packages/xrpl/test/models/AMMWithdraw.ts index 68fdd314..f8c51894 100644 --- a/packages/xrpl/test/models/AMMWithdraw.ts +++ b/packages/xrpl/test/models/AMMWithdraw.ts @@ -7,7 +7,7 @@ import { validate, ValidationError } from 'xrpl-local' * Providing runtime verification testing for each specific transaction type. */ describe('AMMWithdraw', function () { - const LPToken = { + const LPTokenIn = { currency: 'B3813FCAB4EE68B3D0D735D6849465A9113EE048', issuer: 'rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg', value: '1000', @@ -23,30 +23,30 @@ describe('AMMWithdraw', function () { } as any }) - it(`verifies valid AMMWithdraw with LPToken`, function () { - withdraw.LPToken = LPToken + it(`verifies valid AMMWithdraw with LPTokenIn`, function () { + withdraw.LPTokenIn = LPTokenIn assert.doesNotThrow(() => validate(withdraw)) }) - it(`verifies valid AMMWithdraw with Asset1Out`, function () { - withdraw.Asset1Out = '1000' + it(`verifies valid AMMWithdraw with Amount`, function () { + withdraw.Amount = '1000' assert.doesNotThrow(() => validate(withdraw)) }) - it(`verifies valid AMMWithdraw with Asset1Out and Asset2Out`, function () { - withdraw.Asset1Out = '1000' - withdraw.Asset2Out = '1000' + it(`verifies valid AMMWithdraw with Amount and Amount2`, function () { + withdraw.Amount = '1000' + withdraw.Amount2 = '1000' assert.doesNotThrow(() => validate(withdraw)) }) - it(`verifies valid AMMWithdraw with Asset1Out and LPToken`, function () { - withdraw.Asset1Out = '1000' - withdraw.LPToken = LPToken + it(`verifies valid AMMWithdraw with Amount and LPTokenIn`, function () { + withdraw.Amount = '1000' + withdraw.LPTokenIn = LPTokenIn assert.doesNotThrow(() => validate(withdraw)) }) - it(`verifies valid AMMWithdraw with Asset1Out and EPrice`, function () { - withdraw.Asset1Out = '1000' + it(`verifies valid AMMWithdraw with Amount and EPrice`, function () { + withdraw.Amount = '1000' withdraw.EPrice = '25' assert.doesNotThrow(() => validate(withdraw)) }) @@ -69,62 +69,62 @@ describe('AMMWithdraw', function () { ) }) - it(`throws w/ must set at least LPToken or Asset1Out`, function () { + it(`throws w/ must set at least LPTokenIn or Amount`, function () { assert.throws( () => validate(withdraw), ValidationError, - 'AMMWithdraw: must set at least LPToken or Asset1Out', + 'AMMWithdraw: must set at least LPTokenIn or Amount', ) }) - it(`throws w/ must set Asset1Out with Asset2Out`, function () { - withdraw.Asset2Out = '500' + it(`throws w/ must set Amount with Amount2`, function () { + withdraw.Amount2 = '500' assert.throws( () => validate(withdraw), ValidationError, - 'AMMWithdraw: must set Asset1Out with Asset2Out', + 'AMMWithdraw: must set Amount with Amount2', ) }) - it(`throws w/ must set Asset1Out with EPrice`, function () { + it(`throws w/ must set Amount with EPrice`, function () { withdraw.EPrice = '25' assert.throws( () => validate(withdraw), ValidationError, - 'AMMWithdraw: must set Asset1Out with EPrice', + 'AMMWithdraw: must set Amount with EPrice', ) }) - it(`throws w/ LPToken must be an IssuedCurrencyAmount`, function () { - withdraw.LPToken = 1234 + it(`throws w/ LPTokenIn must be an IssuedCurrencyAmount`, function () { + withdraw.LPTokenIn = 1234 assert.throws( () => validate(withdraw), ValidationError, - 'AMMWithdraw: LPToken must be an IssuedCurrencyAmount', + 'AMMWithdraw: LPTokenIn must be an IssuedCurrencyAmount', ) }) - it(`throws w/ Asset1Out must be an Amount`, function () { - withdraw.Asset1Out = 1234 + it(`throws w/ Amount must be an Amount`, function () { + withdraw.Amount = 1234 assert.throws( () => validate(withdraw), ValidationError, - 'AMMWithdraw: Asset1Out must be an Amount', + 'AMMWithdraw: Amount must be an Amount', ) }) - it(`throws w/ Asset2Out must be an Amount`, function () { - withdraw.Asset1Out = '1000' - withdraw.Asset2Out = 1234 + it(`throws w/ Amount2 must be an Amount`, function () { + withdraw.Amount = '1000' + withdraw.Amount2 = 1234 assert.throws( () => validate(withdraw), ValidationError, - 'AMMWithdraw: Asset2Out must be an Amount', + 'AMMWithdraw: Amount2 must be an Amount', ) }) it(`throws w/ EPrice must be an Amount`, function () { - withdraw.Asset1Out = '1000' + withdraw.Amount = '1000' withdraw.EPrice = 1234 assert.throws( () => validate(withdraw), From 54b86bc1d795c5b20fc3a8ad53dda72b6acd7c82 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 10:14:02 -0500 Subject: [PATCH 37/61] rename amm_info param asset1 -> asset --- packages/xrpl/src/models/methods/ammInfo.ts | 8 ++++---- packages/xrpl/src/models/transactions/transaction.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 4d51ccdd..6f3a663c 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -18,13 +18,13 @@ export interface AMMInfoRequest extends BaseRequest { /** * Specifies one of the pool assets (XRP or token) of the AMM instance. - * Both asset1 and asset2 must be defined to specify an AMM instance. + * Both asset and asset2 must be defined to specify an AMM instance. */ - asset1?: Currency + asset?: Currency /** * Specifies the other pool asset of the AMM instance. - * Both asset1 and asset2 must be defined to specify an AMM instance. + * Both asset and asset2 must be defined to specify an AMM instance. */ asset2?: Currency } @@ -49,7 +49,7 @@ export interface AMMInfoResponse extends BaseResponse { /** * Specifies one of the pool assets (XRP or token) of the AMM instance. */ - Asset1: Amount + asset: Amount /** * Specifies the other pool asset of the AMM instance. diff --git a/packages/xrpl/src/models/transactions/transaction.ts b/packages/xrpl/src/models/transactions/transaction.ts index e6ad2fc5..cfa8994a 100644 --- a/packages/xrpl/src/models/transactions/transaction.ts +++ b/packages/xrpl/src/models/transactions/transaction.ts @@ -10,8 +10,8 @@ import { setTransactionFlagsToNumber } from '../utils/flags' import { AccountDelete, validateAccountDelete } from './accountDelete' import { AccountSet, validateAccountSet } from './accountSet' import { AMMBid, validateAMMBid } from './AMMBid' -import { AMMDeposit, validateAMMDeposit } from './AMMDeposit' import { AMMCreate, validateAMMCreate } from './AMMCreate' +import { AMMDeposit, validateAMMDeposit } from './AMMDeposit' import { AMMVote, validateAMMVote } from './AMMVote' import { AMMWithdraw, validateAMMWithdraw } from './AMMWithdraw' import { CheckCancel, validateCheckCancel } from './checkCancel' From c99aa048dae5e3af2deadfe60a886ba5abbf8a2d Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 10:21:14 -0500 Subject: [PATCH 38/61] fix typo --- packages/xrpl/src/models/methods/ammInfo.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 6f3a663c..136c64a5 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -49,7 +49,7 @@ export interface AMMInfoResponse extends BaseResponse { /** * Specifies one of the pool assets (XRP or token) of the AMM instance. */ - asset: Amount + Asset: Amount /** * Specifies the other pool asset of the AMM instance. From 3120abc627826cca5cbd772e47c91a1d108fad78 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 10:27:57 -0500 Subject: [PATCH 39/61] change AMM_MAX_TRADING_FEE to 1% --- packages/xrpl/src/models/methods/ammInfo.ts | 4 ++-- packages/xrpl/src/models/transactions/AMMCreate.ts | 6 +++--- packages/xrpl/src/models/transactions/AMMVote.ts | 4 ++-- packages/xrpl/test/models/AMMCreate.ts | 8 ++++---- packages/xrpl/test/models/AMMVote.ts | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 136c64a5..7a966122 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -67,9 +67,9 @@ export interface AMMInfoResponse extends BaseResponse { /** * Specifies the fee, in basis point, to be charged to the traders for the trades * executed against the AMM instance. Trading fee is a percentage of the trading volume. - * Valid values for this field are between 0 and 65000 inclusive. + * Valid values for this field are between 0 and 1000 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. + * between 0% and 1%. This field is required. */ TradingFee: number diff --git a/packages/xrpl/src/models/transactions/AMMCreate.ts b/packages/xrpl/src/models/transactions/AMMCreate.ts index fbeda32d..9ce8b68d 100644 --- a/packages/xrpl/src/models/transactions/AMMCreate.ts +++ b/packages/xrpl/src/models/transactions/AMMCreate.ts @@ -3,7 +3,7 @@ import { Amount } from '../common' import { BaseTransaction, isAmount, validateBaseTransaction } from './common' -export const AMM_MAX_TRADING_FEE = 65000 +export const AMM_MAX_TRADING_FEE = 1000 /** * AMMCreate is used to create AccountRoot and the corresponding @@ -28,9 +28,9 @@ export interface AMMCreate extends BaseTransaction { * Specifies the fee, in basis point, to be charged * to the traders for the trades executed against the AMM instance. * Trading fee is a percentage of the trading volume. - * Valid values for this field are between 0 and 65000 inclusive. + * Valid values for this field are between 0 and 1000 inclusive. * A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee - * between 0% and 65%. + * between 0% and 1%. */ TradingFee: number } diff --git a/packages/xrpl/src/models/transactions/AMMVote.ts b/packages/xrpl/src/models/transactions/AMMVote.ts index bc69f9d4..b53ccd19 100644 --- a/packages/xrpl/src/models/transactions/AMMVote.ts +++ b/packages/xrpl/src/models/transactions/AMMVote.ts @@ -19,9 +19,9 @@ export interface AMMVote extends BaseTransaction { /** * Specifies the fee, in basis point. - * Valid values for this field are between 0 and 65000 inclusive. + * Valid values for this field are between 0 and 1000 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. + * between 0% and 1%. This field is required. */ TradingFee: number } diff --git a/packages/xrpl/test/models/AMMCreate.ts b/packages/xrpl/test/models/AMMCreate.ts index ce18ef9e..d75a1f17 100644 --- a/packages/xrpl/test/models/AMMCreate.ts +++ b/packages/xrpl/test/models/AMMCreate.ts @@ -82,12 +82,12 @@ describe('AMMCreate', function () { ) }) - it(`throws when TradingFee is greater than 65000`, function () { - ammCreate.TradingFee = 65001 + it(`throws when TradingFee is greater than 1000`, function () { + ammCreate.TradingFee = 1001 assert.throws( () => validate(ammCreate), ValidationError, - `AMMCreate: TradingFee must be between 0 and 65000`, + `AMMCreate: TradingFee must be between 0 and 1000`, ) }) @@ -96,7 +96,7 @@ describe('AMMCreate', function () { assert.throws( () => validate(ammCreate), ValidationError, - `AMMCreate: TradingFee must be between 0 and 65000`, + `AMMCreate: TradingFee must be between 0 and 1000`, ) }) }) diff --git a/packages/xrpl/test/models/AMMVote.ts b/packages/xrpl/test/models/AMMVote.ts index b813d7b5..96268052 100644 --- a/packages/xrpl/test/models/AMMVote.ts +++ b/packages/xrpl/test/models/AMMVote.ts @@ -60,11 +60,11 @@ describe('AMMVote', function () { }) it(`throws when TradingFee is greater than AMM_MAX_TRADING_FEE`, function () { - vote.TradingFee = 65001 + vote.TradingFee = 1001 assert.throws( () => validate(vote), ValidationError, - 'AMMVote: TradingFee must be between 0 and 65000', + 'AMMVote: TradingFee must be between 0 and 1000', ) }) @@ -73,7 +73,7 @@ describe('AMMVote', function () { assert.throws( () => validate(vote), ValidationError, - 'AMMVote: TradingFee must be between 0 and 65000', + 'AMMVote: TradingFee must be between 0 and 1000', ) }) }) From 25752d77a4701b844e85a73fd9fea8d5a965954a Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 11:51:08 -0500 Subject: [PATCH 40/61] Use Asset/Asset2 instead of AMMID for Deposit/Withdraw/Bid/Vote --- packages/xrpl/src/models/common/index.ts | 2 ++ .../xrpl/src/models/transactions/AMMBid.ts | 19 ++++++++----------- .../src/models/transactions/AMMDeposit.ts | 19 ++++++++----------- .../xrpl/src/models/transactions/AMMVote.ts | 18 ++++++++---------- .../src/models/transactions/AMMWithdraw.ts | 19 ++++++++----------- packages/xrpl/test/models/AMMBid.ts | 19 ------------------- packages/xrpl/test/models/AMMDeposit.ts | 19 ------------------- packages/xrpl/test/models/AMMVote.ts | 19 ------------------- packages/xrpl/test/models/AMMWithdraw.ts | 19 ------------------- 9 files changed, 34 insertions(+), 119 deletions(-) diff --git a/packages/xrpl/src/models/common/index.ts b/packages/xrpl/src/models/common/index.ts index 26625c74..c6cea185 100644 --- a/packages/xrpl/src/models/common/index.ts +++ b/packages/xrpl/src/models/common/index.ts @@ -22,6 +22,8 @@ interface IssuedCurrency { export type Currency = IssuedCurrency | XRP +export type Issue = Currency + export interface IssuedCurrencyAmount extends IssuedCurrency { value: string } diff --git a/packages/xrpl/src/models/transactions/AMMBid.ts b/packages/xrpl/src/models/transactions/AMMBid.ts index cc74a2f2..7cdd09cc 100644 --- a/packages/xrpl/src/models/transactions/AMMBid.ts +++ b/packages/xrpl/src/models/transactions/AMMBid.ts @@ -1,5 +1,5 @@ import { ValidationError } from '../../errors' -import { Amount } from '../common' +import { Amount, Issue } from '../common' import { BaseTransaction, isAmount, validateBaseTransaction } from './common' @@ -21,9 +21,14 @@ export interface AMMBid extends BaseTransaction { TransactionType: 'AMMBid' /** - * A hash that uniquely identifies the AMM instance. This field is required. + * Specifies one of the pool assets (XRP or token) of the AMM instance. */ - AMMID: string + Asset: Issue + + /** + * Specifies the other pool asset of the AMM instance. + */ + Asset2: Issue /** * This field represents the minimum price that the bidder wants to pay for the slot. @@ -56,14 +61,6 @@ export interface AMMBid extends BaseTransaction { export function validateAMMBid(tx: Record): void { validateBaseTransaction(tx) - if (tx.AMMID == null) { - throw new ValidationError('AMMBid: missing field AMMID') - } - - if (typeof tx.AMMID !== 'string') { - throw new ValidationError('AMMBid: AMMID must be a string') - } - if (tx.MinBidPrice != null && !isAmount(tx.MinBidPrice)) { throw new ValidationError('AMMBid: MinBidPrice must be an Amount') } diff --git a/packages/xrpl/src/models/transactions/AMMDeposit.ts b/packages/xrpl/src/models/transactions/AMMDeposit.ts index 6132464d..98008e43 100644 --- a/packages/xrpl/src/models/transactions/AMMDeposit.ts +++ b/packages/xrpl/src/models/transactions/AMMDeposit.ts @@ -1,6 +1,6 @@ /* eslint-disable complexity -- required for validateAMMDeposit */ import { ValidationError } from '../../errors' -import { Amount, IssuedCurrencyAmount } from '../common' +import { Amount, Issue, IssuedCurrencyAmount } from '../common' import { BaseTransaction, @@ -24,9 +24,14 @@ export interface AMMDeposit extends BaseTransaction { TransactionType: 'AMMDeposit' /** - * A hash that uniquely identifies the AMM instance. This field is required. + * Specifies one of the pool assets (XRP or token) of the AMM instance. */ - AMMID: string + Asset: Issue + + /** + * Specifies the other pool asset of the AMM instance. + */ + Asset2: Issue /** * Specifies the amount of shares of the AMM instance pools that the trader @@ -61,14 +66,6 @@ export interface AMMDeposit extends BaseTransaction { export function validateAMMDeposit(tx: Record): void { validateBaseTransaction(tx) - if (tx.AMMID == null) { - throw new ValidationError('AMMDeposit: missing field AMMID') - } - - if (typeof tx.AMMID !== 'string') { - throw new ValidationError('AMMDeposit: AMMID must be a string') - } - if (tx.Amount2 != null && tx.Amount == null) { throw new ValidationError('AMMDeposit: must set Amount with Amount2') } else if (tx.EPrice != null && tx.Amount == null) { diff --git a/packages/xrpl/src/models/transactions/AMMVote.ts b/packages/xrpl/src/models/transactions/AMMVote.ts index b53ccd19..38324ec6 100644 --- a/packages/xrpl/src/models/transactions/AMMVote.ts +++ b/packages/xrpl/src/models/transactions/AMMVote.ts @@ -1,4 +1,5 @@ import { ValidationError } from '../../errors' +import { Issue } from '../common' import { AMM_MAX_TRADING_FEE } from './AMMCreate' import { BaseTransaction, validateBaseTransaction } from './common' @@ -13,9 +14,14 @@ export interface AMMVote extends BaseTransaction { TransactionType: 'AMMVote' /** - * A hash that uniquely identifies the AMM instance. This field is required. + * Specifies one of the pool assets (XRP or token) of the AMM instance. */ - AMMID: string + Asset: Issue + + /** + * Specifies the other pool asset of the AMM instance. + */ + Asset2: Issue /** * Specifies the fee, in basis point. @@ -35,14 +41,6 @@ export interface AMMVote extends BaseTransaction { 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.TradingFee == null) { throw new ValidationError('AMMVote: missing field TradingFee') } diff --git a/packages/xrpl/src/models/transactions/AMMWithdraw.ts b/packages/xrpl/src/models/transactions/AMMWithdraw.ts index 04a6cb8b..41ac9dc1 100644 --- a/packages/xrpl/src/models/transactions/AMMWithdraw.ts +++ b/packages/xrpl/src/models/transactions/AMMWithdraw.ts @@ -1,6 +1,6 @@ /* eslint-disable complexity -- required for validateAMMWithdraw */ import { ValidationError } from '../../errors' -import { Amount, IssuedCurrencyAmount } from '../common' +import { Amount, Issue, IssuedCurrencyAmount } from '../common' import { BaseTransaction, @@ -25,9 +25,14 @@ export interface AMMWithdraw extends BaseTransaction { TransactionType: 'AMMWithdraw' /** - * A hash that uniquely identifies the AMM instance. This field is required. + * Specifies one of the pool assets (XRP or token) of the AMM instance. */ - AMMID: string + Asset: Issue + + /** + * Specifies the other pool asset of the AMM instance. + */ + Asset2: Issue /** * Specifies the amount of shares of the AMM instance pools that the trader @@ -63,14 +68,6 @@ export interface AMMWithdraw extends BaseTransaction { export function validateAMMWithdraw(tx: Record): void { validateBaseTransaction(tx) - if (tx.AMMID == null) { - throw new ValidationError('AMMWithdraw: missing field AMMID') - } - - if (typeof tx.AMMID !== 'string') { - throw new ValidationError('AMMWithdraw: AMMID must be a string') - } - if (tx.Amount2 != null && tx.Amount == null) { throw new ValidationError('AMMWithdraw: must set Amount with Amount2') } else if (tx.EPrice != null && tx.Amount == null) { diff --git a/packages/xrpl/test/models/AMMBid.ts b/packages/xrpl/test/models/AMMBid.ts index 08e07a8c..121a698f 100644 --- a/packages/xrpl/test/models/AMMBid.ts +++ b/packages/xrpl/test/models/AMMBid.ts @@ -13,7 +13,6 @@ describe('AMMBid', function () { bid = { TransactionType: 'AMMBid', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', MinBidPrice: '5', MaxBidPrice: '10', AuthAccounts: [ @@ -46,24 +45,6 @@ describe('AMMBid', function () { assert.doesNotThrow(() => validate(bid)) }) - it(`throws w/ missing field AMMID`, function () { - delete bid.AMMID - assert.throws( - () => validate(bid), - ValidationError, - 'AMMBid: missing field AMMID', - ) - }) - - it(`throws w/ AMMID must be a string`, function () { - bid.AMMID = 1234 - assert.throws( - () => validate(bid), - ValidationError, - 'AMMBid: AMMID must be a string', - ) - }) - it(`throws w/ MinBidPrice must be an Amount`, function () { bid.MinBidPrice = 5 assert.throws( diff --git a/packages/xrpl/test/models/AMMDeposit.ts b/packages/xrpl/test/models/AMMDeposit.ts index 00a37440..853c2266 100644 --- a/packages/xrpl/test/models/AMMDeposit.ts +++ b/packages/xrpl/test/models/AMMDeposit.ts @@ -18,7 +18,6 @@ describe('AMMDeposit', function () { deposit = { TransactionType: 'AMMDeposit', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', Sequence: 1337, } as any }) @@ -51,24 +50,6 @@ describe('AMMDeposit', function () { assert.doesNotThrow(() => validate(deposit)) }) - it(`throws w/ missing AMMID`, function () { - delete deposit.AMMID - assert.throws( - () => validate(deposit), - ValidationError, - 'AMMDeposit: missing field AMMID', - ) - }) - - it(`throws w/ AMMID must be a string`, function () { - deposit.AMMID = 1234 - assert.throws( - () => validate(deposit), - ValidationError, - 'AMMDeposit: AMMID must be a string', - ) - }) - it(`throws w/ must set at least LPTokenOut or Amount`, function () { assert.throws( () => validate(deposit), diff --git a/packages/xrpl/test/models/AMMVote.ts b/packages/xrpl/test/models/AMMVote.ts index 96268052..ae625841 100644 --- a/packages/xrpl/test/models/AMMVote.ts +++ b/packages/xrpl/test/models/AMMVote.ts @@ -13,7 +13,6 @@ describe('AMMVote', function () { vote = { TransactionType: 'AMMVote', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', TradingFee: 25, Sequence: 1337, } as any @@ -23,24 +22,6 @@ describe('AMMVote', function () { assert.doesNotThrow(() => validate(vote)) }) - it(`throws w/ missing field AMMID`, function () { - delete vote.AMMID - assert.throws( - () => validate(vote), - ValidationError, - 'AMMVote: missing field AMMID', - ) - }) - - it(`throws w/ AMMID must be a string`, function () { - vote.AMMID = 1234 - assert.throws( - () => validate(vote), - ValidationError, - 'AMMVote: AMMID must be a string', - ) - }) - it(`throws w/ missing field TradingFee`, function () { delete vote.TradingFee assert.throws( diff --git a/packages/xrpl/test/models/AMMWithdraw.ts b/packages/xrpl/test/models/AMMWithdraw.ts index f8c51894..32315125 100644 --- a/packages/xrpl/test/models/AMMWithdraw.ts +++ b/packages/xrpl/test/models/AMMWithdraw.ts @@ -18,7 +18,6 @@ describe('AMMWithdraw', function () { withdraw = { TransactionType: 'AMMWithdraw', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - AMMID: '24BA86F99302CF124AB27311C831F5BFAA72C4625DDA65B7EDF346A60CC19883', Sequence: 1337, } as any }) @@ -51,24 +50,6 @@ describe('AMMWithdraw', function () { assert.doesNotThrow(() => validate(withdraw)) }) - it(`throws w/ missing AMMID`, function () { - delete withdraw.AMMID - assert.throws( - () => validate(withdraw), - ValidationError, - 'AMMWithdraw: missing field AMMID', - ) - }) - - it(`throws w/ AMMID must be a string`, function () { - withdraw.AMMID = 1234 - assert.throws( - () => validate(withdraw), - ValidationError, - 'AMMWithdraw: AMMID must be a string', - ) - }) - it(`throws w/ must set at least LPTokenIn or Amount`, function () { assert.throws( () => validate(withdraw), From 64d8a904f08b3463bddea8c9c64971398d257431 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 13:37:20 -0500 Subject: [PATCH 41/61] add Deposit/Withdraw flags --- .../src/models/transactions/AMMDeposit.ts | 22 ++++++++++++++++ .../src/models/transactions/AMMWithdraw.ts | 26 +++++++++++++++++++ .../xrpl/src/models/transactions/index.ts | 12 +++++++-- packages/xrpl/src/models/utils/flags.ts | 26 +++++++++++++++++++ packages/xrpl/test/models/AMMDeposit.ts | 9 ++++++- packages/xrpl/test/models/AMMWithdraw.ts | 5 +++- 6 files changed, 96 insertions(+), 4 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMDeposit.ts b/packages/xrpl/src/models/transactions/AMMDeposit.ts index 98008e43..b321d5e1 100644 --- a/packages/xrpl/src/models/transactions/AMMDeposit.ts +++ b/packages/xrpl/src/models/transactions/AMMDeposit.ts @@ -4,11 +4,33 @@ import { Amount, Issue, IssuedCurrencyAmount } from '../common' import { BaseTransaction, + GlobalFlags, isAmount, isIssuedCurrency, validateBaseTransaction, } from './common' +/** + * Enum representing values for AMMDeposit Transaction Flags. + * + * @category Transaction Flags + */ +export enum AMMDepositFlags { + tfLPToken = 0x00010000, + tfSingleAsset = 0x00080000, + tfTwoAsset = 0x00100000, + tfOneAssetLPToken = 0x00200000, + tfLimitLPToken = 0x00400000, +} + +export interface AMMDepositFlagsInterface extends GlobalFlags { + tfLPToken?: boolean + tfSingleAsset?: boolean + tfTwoAsset?: boolean + tfOneAssetLPToken?: boolean + tfLimitLPToken?: boolean +} + /** * AMMDeposit is the deposit transaction used to add liquidity to the AMM instance pool, * thus obtaining some share of the instance's pools in the form of LPTokenOut. diff --git a/packages/xrpl/src/models/transactions/AMMWithdraw.ts b/packages/xrpl/src/models/transactions/AMMWithdraw.ts index 41ac9dc1..d7ecefd5 100644 --- a/packages/xrpl/src/models/transactions/AMMWithdraw.ts +++ b/packages/xrpl/src/models/transactions/AMMWithdraw.ts @@ -4,11 +4,37 @@ import { Amount, Issue, IssuedCurrencyAmount } from '../common' import { BaseTransaction, + GlobalFlags, isAmount, isIssuedCurrency, validateBaseTransaction, } from './common' +/** + * Enum representing values for AMMWithdrawFlags Transaction Flags. + * + * @category Transaction Flags + */ +export enum AMMWithdrawFlags { + tfLPToken = 0x00010000, + tfWithdrawAll = 0x00020000, + tfOneAssetWithdrawAll = 0x00040000, + tfSingleAsset = 0x00080000, + tfTwoAsset = 0x00100000, + tfOneAssetLPToken = 0x00200000, + tfLimitLPToken = 0x00400000, +} + +export interface AMMWithdrawFlagsInterface extends GlobalFlags { + tfLPToken?: boolean + tfWithdrawAll?: boolean + tfOneAssetWithdrawAll?: boolean + tfSingleAsset?: boolean + tfTwoAsset?: boolean + tfOneAssetLPToken?: boolean + tfLimitLPToken?: boolean +} + /** * AMMWithdraw is the withdraw transaction used to remove liquidity from the AMM * instance pool, thus redeeming some share of the pools that one owns in the form diff --git a/packages/xrpl/src/models/transactions/index.ts b/packages/xrpl/src/models/transactions/index.ts index a9b5c26c..354b50ad 100644 --- a/packages/xrpl/src/models/transactions/index.ts +++ b/packages/xrpl/src/models/transactions/index.ts @@ -8,10 +8,18 @@ export { } from './accountSet' export { AccountDelete } from './accountDelete' export { AMMBid } from './AMMBid' -export { AMMDeposit } from './AMMDeposit' +export { + AMMDepositFlags, + AMMDepositFlagsInterface, + AMMDeposit, +} from './AMMDeposit' export { AMMCreate } from './AMMCreate' export { AMMVote } from './AMMVote' -export { AMMWithdraw } from './AMMWithdraw' +export { + AMMWithdrawFlags, + AMMWithdrawFlagsInterface, + AMMWithdraw, +} from './AMMWithdraw' export { CheckCancel } from './checkCancel' export { CheckCash } from './checkCash' export { CheckCreate } from './checkCreate' diff --git a/packages/xrpl/src/models/utils/flags.ts b/packages/xrpl/src/models/utils/flags.ts index f185c99b..a4108130 100644 --- a/packages/xrpl/src/models/utils/flags.ts +++ b/packages/xrpl/src/models/utils/flags.ts @@ -10,6 +10,14 @@ import { AccountSetFlagsInterface, AccountSetTfFlags, } from '../transactions/accountSet' +import { + AMMDepositFlags, + AMMDepositFlagsInterface, +} from '../transactions/AMMDeposit' +import { + AMMWithdrawFlags, + AMMWithdrawFlagsInterface, +} from '../transactions/AMMWithdraw' import { GlobalFlags } from '../transactions/common' import { OfferCreateFlagsInterface, @@ -63,6 +71,12 @@ export function setTransactionFlagsToNumber(tx: Transaction): void { case 'AccountSet': tx.Flags = convertAccountSetFlagsToNumber(tx.Flags) return + case 'AMMDeposit': + tx.Flags = convertAMMDepositFlagsToNumber(tx.Flags) + return + case 'AMMWithdraw': + tx.Flags = convertAMMWithdrawFlagsToNumber(tx.Flags) + return case 'OfferCreate': tx.Flags = convertOfferCreateFlagsToNumber(tx.Flags) return @@ -86,6 +100,18 @@ function convertAccountSetFlagsToNumber( return reduceFlags(flags, AccountSetTfFlags) } +function convertAMMDepositFlagsToNumber( + flags: AMMDepositFlagsInterface, +): number { + return reduceFlags(flags, AMMDepositFlags) +} + +function convertAMMWithdrawFlagsToNumber( + flags: AMMWithdrawFlagsInterface, +): number { + return reduceFlags(flags, AMMWithdrawFlags) +} + function convertOfferCreateFlagsToNumber( flags: OfferCreateFlagsInterface, ): number { diff --git a/packages/xrpl/test/models/AMMDeposit.ts b/packages/xrpl/test/models/AMMDeposit.ts index 853c2266..4fef86bc 100644 --- a/packages/xrpl/test/models/AMMDeposit.ts +++ b/packages/xrpl/test/models/AMMDeposit.ts @@ -1,5 +1,6 @@ +/* eslint-disable no-bitwise -- bitwise necessary for enabling flags */ import { assert } from 'chai' -import { validate, ValidationError } from 'xrpl-local' +import { AMMDepositFlags, validate, ValidationError } from 'xrpl-local' /** * AMMDeposit Transaction Verification Testing. @@ -19,34 +20,40 @@ describe('AMMDeposit', function () { TransactionType: 'AMMDeposit', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', Sequence: 1337, + Flags: 0, } as any }) it(`verifies valid AMMDeposit with LPTokenOut`, function () { deposit.LPTokenOut = LPTokenOut + deposit.Flags |= AMMDepositFlags.tfLPToken assert.doesNotThrow(() => validate(deposit)) }) it(`verifies valid AMMDeposit with Amount`, function () { deposit.Amount = '1000' + deposit.Flags |= AMMDepositFlags.tfSingleAsset assert.doesNotThrow(() => validate(deposit)) }) it(`verifies valid AMMDeposit with Amount and Amount2`, function () { deposit.Amount = '1000' deposit.Amount2 = '1000' + deposit.Flags |= AMMDepositFlags.tfTwoAsset assert.doesNotThrow(() => validate(deposit)) }) it(`verifies valid AMMDeposit with Amount and LPTokenOut`, function () { deposit.Amount = '1000' deposit.LPTokenOut = LPTokenOut + deposit.Flags |= AMMDepositFlags.tfOneAssetLPToken assert.doesNotThrow(() => validate(deposit)) }) it(`verifies valid AMMDeposit with Amount and EPrice`, function () { deposit.Amount = '1000' deposit.EPrice = '25' + deposit.Flags |= AMMDepositFlags.tfLimitLPToken assert.doesNotThrow(() => validate(deposit)) }) diff --git a/packages/xrpl/test/models/AMMWithdraw.ts b/packages/xrpl/test/models/AMMWithdraw.ts index 32315125..ae7a984d 100644 --- a/packages/xrpl/test/models/AMMWithdraw.ts +++ b/packages/xrpl/test/models/AMMWithdraw.ts @@ -1,5 +1,6 @@ +/* eslint-disable no-bitwise -- bitwise necessary for enabling flags */ import { assert } from 'chai' -import { validate, ValidationError } from 'xrpl-local' +import { AMMWithdrawFlags, validate, ValidationError } from 'xrpl-local' /** * AMMWithdraw Transaction Verification Testing. @@ -19,6 +20,7 @@ describe('AMMWithdraw', function () { TransactionType: 'AMMWithdraw', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', Sequence: 1337, + Flags: 0, } as any }) @@ -29,6 +31,7 @@ describe('AMMWithdraw', function () { it(`verifies valid AMMWithdraw with Amount`, function () { withdraw.Amount = '1000' + withdraw.Flags |= AMMWithdrawFlags.tfSingleAsset assert.doesNotThrow(() => validate(withdraw)) }) From bcdd8fe2cf8810f350dd84829875b715a1b2147f Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 14:59:12 -0500 Subject: [PATCH 42/61] rename FeeVal -> TradingFee in VoteEntry --- packages/xrpl/src/models/methods/ammInfo.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 7a966122..0448148c 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -30,7 +30,7 @@ export interface AMMInfoRequest extends BaseRequest { } interface VoteEntry { - FeeVal: number + TradingFee: number VoteWeight: number } From eba8bd2ec1d9ecc4647ba5bc10db74900ba2ba55 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 15:09:33 -0500 Subject: [PATCH 43/61] rename MinBidPrice -> BidMin and MaxBidPrice -> BidMax --- .../src/enums/definitions.json | 4 ++-- packages/xrpl/src/models/transactions/AMMBid.ts | 14 +++++++------- packages/xrpl/test/models/AMMBid.ts | 16 ++++++++-------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/ripple-binary-codec/src/enums/definitions.json b/packages/ripple-binary-codec/src/enums/definitions.json index 55bbac88..b9aa434c 100644 --- a/packages/ripple-binary-codec/src/enums/definitions.json +++ b/packages/ripple-binary-codec/src/enums/definitions.json @@ -1454,7 +1454,7 @@ } ], [ - "MinBidPrice", + "BidMin", { "nth": 12, "isVLEncoded": false, @@ -1464,7 +1464,7 @@ } ], [ - "MaxBidPrice", + "BidMax", { "nth": 13, "isVLEncoded": false, diff --git a/packages/xrpl/src/models/transactions/AMMBid.ts b/packages/xrpl/src/models/transactions/AMMBid.ts index 7cdd09cc..4e6469b1 100644 --- a/packages/xrpl/src/models/transactions/AMMBid.ts +++ b/packages/xrpl/src/models/transactions/AMMBid.ts @@ -32,17 +32,17 @@ export interface AMMBid extends BaseTransaction { /** * This field represents the minimum price that the bidder wants to pay for the slot. - * It is specified in units of LPToken. If specified let MinBidPrice be X and let + * It is specified in units of LPToken. If specified let BidMin be X and let * the slot-price computed by price scheduling algorithm be Y, then bidder always pays * the max(X, Y). */ - MinBidPrice?: Amount + BidMin?: Amount /** * This field represents the maximum price that the bidder wants to pay for the slot. * It is specified in units of LPToken. */ - MaxBidPrice?: Amount + BidMax?: Amount /** * This field represents an array of XRPL account IDs that are authorized to trade @@ -61,12 +61,12 @@ export interface AMMBid extends BaseTransaction { export function validateAMMBid(tx: Record): void { validateBaseTransaction(tx) - if (tx.MinBidPrice != null && !isAmount(tx.MinBidPrice)) { - throw new ValidationError('AMMBid: MinBidPrice must be an Amount') + if (tx.BidMin != null && !isAmount(tx.BidMin)) { + throw new ValidationError('AMMBid: BidMin must be an Amount') } - if (tx.MaxBidPrice != null && !isAmount(tx.MaxBidPrice)) { - throw new ValidationError('AMMBid: MaxBidPrice must be an Amount') + if (tx.BidMax != null && !isAmount(tx.BidMax)) { + throw new ValidationError('AMMBid: BidMax must be an Amount') } if (tx.AuthAccounts != null) { diff --git a/packages/xrpl/test/models/AMMBid.ts b/packages/xrpl/test/models/AMMBid.ts index 121a698f..d4154547 100644 --- a/packages/xrpl/test/models/AMMBid.ts +++ b/packages/xrpl/test/models/AMMBid.ts @@ -13,8 +13,8 @@ describe('AMMBid', function () { bid = { TransactionType: 'AMMBid', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', - MinBidPrice: '5', - MaxBidPrice: '10', + BidMin: '5', + BidMax: '10', AuthAccounts: [ { AuthAccount: { @@ -45,21 +45,21 @@ describe('AMMBid', function () { assert.doesNotThrow(() => validate(bid)) }) - it(`throws w/ MinBidPrice must be an Amount`, function () { - bid.MinBidPrice = 5 + it(`throws w/ BidMin must be an Amount`, function () { + bid.BidMin = 5 assert.throws( () => validate(bid), ValidationError, - 'AMMBid: MinBidPrice must be an Amount', + 'AMMBid: BidMin must be an Amount', ) }) - it(`throws w/ MaxBidPrice must be an Amount`, function () { - bid.MaxBidPrice = 10 + it(`throws w/ BidMax must be an Amount`, function () { + bid.BidMax = 10 assert.throws( () => validate(bid), ValidationError, - 'AMMBid: MaxBidPrice must be an Amount', + 'AMMBid: BidMax must be an Amount', ) }) From 1c26e8b6d53ae76b72b2bf8951a6b3030ca423b4 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 9 Nov 2022 15:20:37 -0500 Subject: [PATCH 44/61] update definitions to change Asset & Asset2 nth values to 3 & 4 --- packages/ripple-binary-codec/src/enums/definitions.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ripple-binary-codec/src/enums/definitions.json b/packages/ripple-binary-codec/src/enums/definitions.json index b9aa434c..c9d2c494 100644 --- a/packages/ripple-binary-codec/src/enums/definitions.json +++ b/packages/ripple-binary-codec/src/enums/definitions.json @@ -1966,7 +1966,7 @@ [ "Asset", { - "nth": 1, + "nth": 3, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, @@ -1976,7 +1976,7 @@ [ "Asset2", { - "nth": 2, + "nth": 4, "isVLEncoded": false, "isSerialized": true, "isSigningField": true, From 40388cc1e58bcb9042417147a98dd2105dddedd2 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 16 Nov 2022 14:02:24 -0500 Subject: [PATCH 45/61] update definitions --- .../src/enums/definitions.json | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/packages/ripple-binary-codec/src/enums/definitions.json b/packages/ripple-binary-codec/src/enums/definitions.json index c9d2c494..ab3bc26f 100644 --- a/packages/ripple-binary-codec/src/enums/definitions.json +++ b/packages/ripple-binary-codec/src/enums/definitions.json @@ -1013,26 +1013,6 @@ "type": "Hash160" } ], - [ - "TokenCurrency", - { - "nth": 5, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash160" - } - ], - [ - "TokenIssuer", - { - "nth": 6, - "isVLEncoded": false, - "isSerialized": true, - "isSigningField": true, - "type": "Hash160" - } - ], [ "LedgerHash", { From 0574fabf47ea71f797e530bb059e0f4051f414fb Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 16 Nov 2022 20:58:57 -0500 Subject: [PATCH 46/61] add Issue type and tests for Asset/Asset2 --- .../ripple-binary-codec/src/types/index.ts | 2 + .../ripple-binary-codec/src/types/issue.ts | 96 +++++++++++++++++++ .../xrpl/src/models/transactions/AMMBid.ts | 23 ++++- .../src/models/transactions/AMMDeposit.ts | 17 ++++ .../xrpl/src/models/transactions/AMMVote.ts | 18 +++- .../src/models/transactions/AMMWithdraw.ts | 17 ++++ .../xrpl/src/models/transactions/common.ts | 21 +++- packages/xrpl/test/models/AMMBid.ts | 43 +++++++++ packages/xrpl/test/models/AMMDeposit.ts | 55 ++++++++++- packages/xrpl/test/models/AMMVote.ts | 43 +++++++++ packages/xrpl/test/models/AMMWithdraw.ts | 55 ++++++++++- 11 files changed, 383 insertions(+), 7 deletions(-) create mode 100644 packages/ripple-binary-codec/src/types/issue.ts diff --git a/packages/ripple-binary-codec/src/types/index.ts b/packages/ripple-binary-codec/src/types/index.ts index 5efa199a..aa0c280e 100644 --- a/packages/ripple-binary-codec/src/types/index.ts +++ b/packages/ripple-binary-codec/src/types/index.ts @@ -11,6 +11,7 @@ import { Currency } from './currency' import { Hash128 } from './hash-128' import { Hash160 } from './hash-160' import { Hash256 } from './hash-256' +import { Issue } from './issue' import { PathSet } from './path-set' import { STArray } from './st-array' import { STObject } from './st-object' @@ -28,6 +29,7 @@ const coreTypes = { Hash128, Hash160, Hash256, + Issue, PathSet, STArray, STObject, diff --git a/packages/ripple-binary-codec/src/types/issue.ts b/packages/ripple-binary-codec/src/types/issue.ts new file mode 100644 index 00000000..29bd160b --- /dev/null +++ b/packages/ripple-binary-codec/src/types/issue.ts @@ -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(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 } diff --git a/packages/xrpl/src/models/transactions/AMMBid.ts b/packages/xrpl/src/models/transactions/AMMBid.ts index 4e6469b1..70ef4222 100644 --- a/packages/xrpl/src/models/transactions/AMMBid.ts +++ b/packages/xrpl/src/models/transactions/AMMBid.ts @@ -1,7 +1,12 @@ import { ValidationError } from '../../errors' import { Amount, Issue } from '../common' -import { BaseTransaction, isAmount, validateBaseTransaction } from './common' +import { + BaseTransaction, + isAmount, + isIssue, + validateBaseTransaction, +} from './common' const MAX_AUTH_ACCOUNTS = 4 @@ -61,6 +66,22 @@ export interface AMMBid extends BaseTransaction { export function validateAMMBid(tx: Record): void { 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)) { throw new ValidationError('AMMBid: BidMin must be an Amount') } diff --git a/packages/xrpl/src/models/transactions/AMMDeposit.ts b/packages/xrpl/src/models/transactions/AMMDeposit.ts index b321d5e1..0770d338 100644 --- a/packages/xrpl/src/models/transactions/AMMDeposit.ts +++ b/packages/xrpl/src/models/transactions/AMMDeposit.ts @@ -6,6 +6,7 @@ import { BaseTransaction, GlobalFlags, isAmount, + isIssue, isIssuedCurrency, validateBaseTransaction, } from './common' @@ -88,6 +89,22 @@ export interface AMMDeposit extends BaseTransaction { export function validateAMMDeposit(tx: Record): void { 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) { throw new ValidationError('AMMDeposit: must set Amount with Amount2') } else if (tx.EPrice != null && tx.Amount == null) { diff --git a/packages/xrpl/src/models/transactions/AMMVote.ts b/packages/xrpl/src/models/transactions/AMMVote.ts index 38324ec6..ce33acfe 100644 --- a/packages/xrpl/src/models/transactions/AMMVote.ts +++ b/packages/xrpl/src/models/transactions/AMMVote.ts @@ -2,7 +2,7 @@ import { ValidationError } from '../../errors' import { Issue } from '../common' 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. @@ -41,6 +41,22 @@ export interface AMMVote extends BaseTransaction { export function validateAMMVote(tx: Record): void { 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) { throw new ValidationError('AMMVote: missing field TradingFee') } diff --git a/packages/xrpl/src/models/transactions/AMMWithdraw.ts b/packages/xrpl/src/models/transactions/AMMWithdraw.ts index d7ecefd5..eac8d218 100644 --- a/packages/xrpl/src/models/transactions/AMMWithdraw.ts +++ b/packages/xrpl/src/models/transactions/AMMWithdraw.ts @@ -6,6 +6,7 @@ import { BaseTransaction, GlobalFlags, isAmount, + isIssue, isIssuedCurrency, validateBaseTransaction, } from './common' @@ -94,6 +95,22 @@ export interface AMMWithdraw extends BaseTransaction { export function validateAMMWithdraw(tx: Record): void { 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) { throw new ValidationError('AMMWithdraw: must set Amount with Amount2') } else if (tx.EPrice != null && tx.Amount == null) { diff --git a/packages/xrpl/src/models/transactions/common.ts b/packages/xrpl/src/models/transactions/common.ts index 498a2d74..bd330b7b 100644 --- a/packages/xrpl/src/models/transactions/common.ts +++ b/packages/xrpl/src/models/transactions/common.ts @@ -4,7 +4,7 @@ import { TRANSACTION_TYPES } from 'ripple-binary-codec' import { ValidationError } from '../../errors' -import { Amount, IssuedCurrencyAmount, Memo, Signer } from '../common' +import { Amount, Issue, IssuedCurrencyAmount, Memo, Signer } from '../common' import { onlyHasFields } from '../utils' const MEMO_SIZE = 3 @@ -84,6 +84,25 @@ export function isAmount(amount: unknown): amount is 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 export interface GlobalFlags {} diff --git a/packages/xrpl/test/models/AMMBid.ts b/packages/xrpl/test/models/AMMBid.ts index d4154547..834bf34d 100644 --- a/packages/xrpl/test/models/AMMBid.ts +++ b/packages/xrpl/test/models/AMMBid.ts @@ -13,6 +13,13 @@ describe('AMMBid', function () { bid = { TransactionType: 'AMMBid', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset: { + currency: 'XRP', + }, + Asset2: { + currency: 'ETH', + issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd', + }, BidMin: '5', BidMax: '10', AuthAccounts: [ @@ -45,6 +52,42 @@ describe('AMMBid', function () { 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 () { bid.BidMin = 5 assert.throws( diff --git a/packages/xrpl/test/models/AMMDeposit.ts b/packages/xrpl/test/models/AMMDeposit.ts index 4fef86bc..f7b65fd3 100644 --- a/packages/xrpl/test/models/AMMDeposit.ts +++ b/packages/xrpl/test/models/AMMDeposit.ts @@ -19,6 +19,13 @@ describe('AMMDeposit', function () { deposit = { TransactionType: 'AMMDeposit', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset: { + currency: 'XRP', + }, + Asset2: { + currency: 'ETH', + issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd', + }, Sequence: 1337, Flags: 0, } as any @@ -38,7 +45,11 @@ describe('AMMDeposit', function () { it(`verifies valid AMMDeposit with Amount and Amount2`, function () { deposit.Amount = '1000' - deposit.Amount2 = '1000' + deposit.Amount2 = { + currency: 'ETH', + issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd', + value: '2.5', + } deposit.Flags |= AMMDepositFlags.tfTwoAsset assert.doesNotThrow(() => validate(deposit)) }) @@ -57,6 +68,42 @@ describe('AMMDeposit', function () { 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 () { assert.throws( () => validate(deposit), @@ -66,7 +113,11 @@ describe('AMMDeposit', function () { }) it(`throws w/ must set Amount with Amount2`, function () { - deposit.Amount2 = '500' + deposit.Amount2 = { + currency: 'ETH', + issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd', + value: '2.5', + } assert.throws( () => validate(deposit), ValidationError, diff --git a/packages/xrpl/test/models/AMMVote.ts b/packages/xrpl/test/models/AMMVote.ts index ae625841..f00350b4 100644 --- a/packages/xrpl/test/models/AMMVote.ts +++ b/packages/xrpl/test/models/AMMVote.ts @@ -13,6 +13,13 @@ describe('AMMVote', function () { vote = { TransactionType: 'AMMVote', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset: { + currency: 'XRP', + }, + Asset2: { + currency: 'ETH', + issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd', + }, TradingFee: 25, Sequence: 1337, } as any @@ -22,6 +29,42 @@ describe('AMMVote', function () { 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 () { delete vote.TradingFee assert.throws( diff --git a/packages/xrpl/test/models/AMMWithdraw.ts b/packages/xrpl/test/models/AMMWithdraw.ts index ae7a984d..d14b1aac 100644 --- a/packages/xrpl/test/models/AMMWithdraw.ts +++ b/packages/xrpl/test/models/AMMWithdraw.ts @@ -19,6 +19,13 @@ describe('AMMWithdraw', function () { withdraw = { TransactionType: 'AMMWithdraw', Account: 'rWYkbWkCeg8dP6rXALnjgZSjjLyih5NXm', + Asset: { + currency: 'XRP', + }, + Asset2: { + currency: 'ETH', + issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd', + }, Sequence: 1337, Flags: 0, } as any @@ -37,7 +44,11 @@ describe('AMMWithdraw', function () { it(`verifies valid AMMWithdraw with Amount and Amount2`, function () { withdraw.Amount = '1000' - withdraw.Amount2 = '1000' + withdraw.Amount2 = { + currency: 'ETH', + issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd', + value: '2.5', + } assert.doesNotThrow(() => validate(withdraw)) }) @@ -53,6 +64,42 @@ describe('AMMWithdraw', function () { 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 () { assert.throws( () => validate(withdraw), @@ -62,7 +109,11 @@ describe('AMMWithdraw', function () { }) it(`throws w/ must set Amount with Amount2`, function () { - withdraw.Amount2 = '500' + withdraw.Amount2 = { + currency: 'ETH', + issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd', + value: '2.5', + } assert.throws( () => validate(withdraw), ValidationError, From 64e4242085a9d49f6f6a31381bb4e7d438ba589c Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 16 Nov 2022 21:03:08 -0500 Subject: [PATCH 47/61] remove AMMID from amm_info and use Issue type --- packages/xrpl/src/models/methods/ammInfo.ts | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 0448148c..5f014ad4 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -1,4 +1,4 @@ -import { Amount, Currency, IssuedCurrencyAmount } from '../common' +import { Issue, IssuedCurrencyAmount } from '../common' import { BaseRequest, BaseResponse } from './baseMethod' @@ -11,22 +11,17 @@ import { BaseRequest, BaseResponse } from './baseMethod' export interface AMMInfoRequest extends BaseRequest { command: 'amm_info' - /** - * A hash that uniquely identifies the AMM instance. - */ - amm_id?: string - /** * Specifies one of the pool assets (XRP or token) of the AMM instance. * Both asset and asset2 must be defined to specify an AMM instance. */ - asset?: Currency + asset?: Issue /** * Specifies the other pool asset of the AMM instance. * Both asset and asset2 must be defined to specify an AMM instance. */ - asset2?: Currency + asset2?: Issue } interface VoteEntry { @@ -49,12 +44,12 @@ export interface AMMInfoResponse extends BaseResponse { /** * Specifies one of the pool assets (XRP or token) of the AMM instance. */ - Asset: Amount + Asset: Issue /** * Specifies the other pool asset of the AMM instance. */ - Asset2: Amount + Asset2: Issue /** * Represents the liquidity providers' shares of the AMM instance's pools. @@ -73,11 +68,6 @@ export interface AMMInfoResponse extends BaseResponse { */ TradingFee: number - /** - * A hash that uniquely identifies the AMM instance. - */ - AMMID?: string - /** * Keeps a track of up to eight active votes for the instance. */ From e32db9dd39d5b4b3c1593024ad81474b38eb3c16 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 16 Nov 2022 21:21:21 -0500 Subject: [PATCH 48/61] update amm_info fields --- packages/xrpl/src/models/methods/ammInfo.ts | 55 ++++++++++++++++++--- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 5f014ad4..2ba30ebc 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -1,4 +1,4 @@ -import { Issue, IssuedCurrencyAmount } from '../common' +import { Amount, Issue, IssuedCurrencyAmount } from '../common' import { BaseRequest, BaseResponse } from './baseMethod' @@ -24,9 +24,18 @@ export interface AMMInfoRequest extends BaseRequest { asset2?: Issue } +interface AuthAccount { + AuthAccount: { + Account: string + } +} + interface VoteEntry { - TradingFee: number - VoteWeight: number + VoteEntry: { + Account: string + TradingFee: number + VoteWeight: number + } } /** @@ -52,12 +61,42 @@ export interface AMMInfoResponse extends BaseResponse { Asset2: Issue /** - * Represents the liquidity providers' shares of the AMM instance's pools. - * LPTokens are tokens on XRPL. Each LPToken represents a proportional share of each pool of the AMM instance. - * The AMM instance account issues the LPTokens to LPs upon liquidity provision. - * LPTokens are balanced in the LPs trustline upon liquidity removal. + * Details of the current owner of the auction slot. */ - LPToken: IssuedCurrencyAmount + AuctionSlot?: { + /** + * The current owner of this auction slot. + */ + Account: string + + /** + * A list of at most 4 additional accounts that are authorized to trade at the discounted fee for this AMM instance. + */ + AuthAccounts: AuthAccount[] + + /** + * The trading fee to be charged to the auction owner, in the same format as TradingFee. + * By default this is 0, meaning that the auction owner can trade at no fee instead of the standard fee for this AMM. + */ + DiscountedFee: number + + /** + * The time when this slot expires, in seconds since the Ripple Epoch. + */ + Expiration: string + + /** + * The amount the auction owner paid to win this slot, in LPTokens. + */ + Price: Amount + } + + /** + * The total outstanding balance of liquidity provider tokens from this AMM instance. + * The holders of these tokens can vote on the AMM's trading fee in proportion to their holdings, + * or redeem the tokens for a share of the AMM's assets which grows with the trading fees collected. + */ + LPTokenBalance: IssuedCurrencyAmount /** * Specifies the fee, in basis point, to be charged to the traders for the trades From ff65441d3317ea9f88131335f4969ed5f9f0fd63 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 16 Nov 2022 21:24:40 -0500 Subject: [PATCH 49/61] fix lint errors --- packages/xrpl/src/models/methods/ammInfo.ts | 2 +- packages/xrpl/src/models/transactions/AMMBid.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 2ba30ebc..68eeb7a0 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -92,7 +92,7 @@ export interface AMMInfoResponse extends BaseResponse { } /** - * The total outstanding balance of liquidity provider tokens from this AMM instance. + * The total outstanding balance of liquidity provider tokens from this AMM instance. * The holders of these tokens can vote on the AMM's trading fee in proportion to their holdings, * or redeem the tokens for a share of the AMM's assets which grows with the trading fees collected. */ diff --git a/packages/xrpl/src/models/transactions/AMMBid.ts b/packages/xrpl/src/models/transactions/AMMBid.ts index 70ef4222..1a6ec810 100644 --- a/packages/xrpl/src/models/transactions/AMMBid.ts +++ b/packages/xrpl/src/models/transactions/AMMBid.ts @@ -1,3 +1,4 @@ +/* eslint-disable complexity -- required for validateAMMBid */ import { ValidationError } from '../../errors' import { Amount, Issue } from '../common' From 434ad71672bc5ea76bfa764204b43f7503d7d490 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 17 Nov 2022 09:34:40 -0500 Subject: [PATCH 50/61] update unit tests --- packages/xrpl/test/models/AMMWithdraw.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/xrpl/test/models/AMMWithdraw.ts b/packages/xrpl/test/models/AMMWithdraw.ts index d14b1aac..153766f8 100644 --- a/packages/xrpl/test/models/AMMWithdraw.ts +++ b/packages/xrpl/test/models/AMMWithdraw.ts @@ -33,6 +33,7 @@ describe('AMMWithdraw', function () { it(`verifies valid AMMWithdraw with LPTokenIn`, function () { withdraw.LPTokenIn = LPTokenIn + withdraw.Flags |= AMMWithdrawFlags.tfLPToken assert.doesNotThrow(() => validate(withdraw)) }) @@ -49,18 +50,21 @@ describe('AMMWithdraw', function () { issuer: 'rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd', value: '2.5', } + withdraw.Flags |= AMMWithdrawFlags.tfTwoAsset assert.doesNotThrow(() => validate(withdraw)) }) it(`verifies valid AMMWithdraw with Amount and LPTokenIn`, function () { withdraw.Amount = '1000' withdraw.LPTokenIn = LPTokenIn + withdraw.Flags |= AMMWithdrawFlags.tfOneAssetLPToken assert.doesNotThrow(() => validate(withdraw)) }) it(`verifies valid AMMWithdraw with Amount and EPrice`, function () { withdraw.Amount = '1000' withdraw.EPrice = '25' + withdraw.Flags |= AMMWithdrawFlags.tfLimitLPToken assert.doesNotThrow(() => validate(withdraw)) }) From 09707537901eb29a2460fb2a993b5c06ecda0418 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 17 Nov 2022 13:14:25 -0500 Subject: [PATCH 51/61] add AMM codec-fixtures --- .../test/fixtures/codec-fixtures.json | 209 +++++++++++++++++- 1 file changed, 208 insertions(+), 1 deletion(-) diff --git a/packages/ripple-binary-codec/test/fixtures/codec-fixtures.json b/packages/ripple-binary-codec/test/fixtures/codec-fixtures.json index 15aa20f1..5758dbf5 100644 --- a/packages/ripple-binary-codec/test/fixtures/codec-fixtures.json +++ b/packages/ripple-binary-codec/test/fixtures/codec-fixtures.json @@ -4448,6 +4448,213 @@ "Flags": 0, "Sequence": 62 } + }, + { + "binary": "12002315000A220000000024000000026140000000000027106840000000000000016BD5838D7EA4C680000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440913E39EC2BA0E5BC4C5DF1222B1AE9E76758F2B8FFEF1F056076147BB0ADC8117CD0296360DA08B3D48BE9EFC8693C03A253E0D9F166C19CA8D936F9E61A1100811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMCreate", + "TxnSignature": "913E39EC2BA0E5BC4C5DF1222B1AE9E76758F2B8FFEF1F056076147BB0ADC8117CD0296360DA08B3D48BE9EFC8693C03A253E0D9F166C19CA8D936F9E61A1100", + "Amount": "10000", + "Amount2": { + "currency": "ETH", + "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", + "value": "10000" + }, + "TradingFee": 10, + "Fee": "1", + "Flags": 0, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0" + } + }, + { + "binary": "120024220001000024000000026840000000000000016014D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D074409EEE8CF88C668B955E7EEAB1B4A1B059EDF4F51B7F1546810F87E3E48B09237F015C651E37FB40A979E00EA21361D4E18D7A33DB7DD23070CEEAB2648AB3BB0D811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMDeposit", + "TxnSignature": "9EEE8CF88C668B955E7EEAB1B4A1B059EDF4F51B7F1546810F87E3E48B09237F015C651E37FB40A979E00EA21361D4E18D7A33DB7DD23070CEEAB2648AB3BB0D", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "LPTokenOut": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"}, + "Fee": "1", + "Flags": 65536, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0" + } + }, + { + "binary": "120024220008000024000000026140000000000003E86840000000000000017321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440BD18A6E2B10B451F61CFADC32B59A0243702DC5DAAE556D51CB9C79981D40C78101FFA9DE6163CFBDF6E7578DF02F2AE3B8A5AB60697E0746D65064D91E8F90A811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMDeposit", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "Fee": "1", + "Flags": 524288, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "BD18A6E2B10B451F61CFADC32B59A0243702DC5DAAE556D51CB9C79981D40C78101FFA9DE6163CFBDF6E7578DF02F2AE3B8A5AB60697E0746D65064D91E8F90A" + } + }, + { + "binary": "120024220010000024000000026140000000000003E86840000000000000016BD511C37937E080000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440E0B1AE32A0F731BF0CEF0D019295BD7F35B22F11A5962F65FA99EE4D38993B14B53DB11C15E36D756E282812E9015D38A6F225940A157693F43F9B795C59950F811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMDeposit", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "Amount2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", "value": "500"}, + "Fee": "1", + "Flags": 1048576, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "E0B1AE32A0F731BF0CEF0D019295BD7F35B22F11A5962F65FA99EE4D38993B14B53DB11C15E36D756E282812E9015D38A6F225940A157693F43F9B795C59950F" + } + }, + { + "binary": "120024220020000024000000026140000000000003E86840000000000000016014D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440452BC59F9EE12C224EC983EFDF580F20C4A50E897105FD1FB13520D9753CFB02BD210599181574DF6AD0DB6A42C1EA48D9E48FC3D11B9008E4C76FBB163D5B00811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMDeposit", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "LPTokenOut": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"}, + "Fee": "1", + "Flags": 2097152, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "452BC59F9EE12C224EC983EFDF580F20C4A50E897105FD1FB13520D9753CFB02BD210599181574DF6AD0DB6A42C1EA48D9E48FC3D11B9008E4C76FBB163D5B00" + } + }, + { + "binary": "120024220040000024000000026140000000000003E8684000000000000001601640000000000000197321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440DD6685DC586FAA6AD2D50D785900122EB147D4AC09A55D7080267A9B38180F87CEC44B823359FC3F0AC0104D47B53FFC6B80415664C3C4582672420A0100F70C811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMDeposit", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "EPrice": "25", + "Fee": "1", + "Flags": 4194304, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "DD6685DC586FAA6AD2D50D785900122EB147D4AC09A55D7080267A9B38180F87CEC44B823359FC3F0AC0104D47B53FFC6B80415664C3C4582672420A0100F70C" + } + }, + { + "binary": "120025220001000024000000026840000000000000016015D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0744066944797E9F03808C9A00AAEFF786AD74FEB2E64B51A9601E89ABA820AAA15927C2E961A9CCA22C4B0D2A2B55E342BD6E297BD765B6F4D3FDCA578A3416BB505811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMWithdraw", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "LPTokenIn": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"}, + "Fee": "1", + "Flags": 65536, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "66944797E9F03808C9A00AAEFF786AD74FEB2E64B51A9601E89ABA820AAA15927C2E961A9CCA22C4B0D2A2B55E342BD6E297BD765B6F4D3FDCA578A3416BB505" + } + }, + { + "binary": "120025220008000024000000026140000000000003E86840000000000000017321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440E30397CE7E99B13D35FFB5C66725B17F4F103675E10293C7B1D63C1BE3FA81B884BD3FBD31B52F6B811F99C5FBB5102D170EC379C268DF80DABF04E7F2DD4F0C811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMWithdraw", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "Fee": "1", + "Flags": 524288, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "E30397CE7E99B13D35FFB5C66725B17F4F103675E10293C7B1D63C1BE3FA81B884BD3FBD31B52F6B811F99C5FBB5102D170EC379C268DF80DABF04E7F2DD4F0C" + } + }, + { + "binary": "120025220010000024000000026140000000000003E86840000000000000016BD511C37937E080000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D07440C0818312B269A4EF16C1C7EBBB74EFD1852A288BB214A714B8BE3B5F4B2F9CFDFF4F66C931B8434244A8016035B9EC9493B7CF5E0ACF4570A88DF808D79E4300811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMWithdraw", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "Amount2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", "value": "500"}, + "Fee": "1", + "Flags": 1048576, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "C0818312B269A4EF16C1C7EBBB74EFD1852A288BB214A714B8BE3B5F4B2F9CFDFF4F66C931B8434244A8016035B9EC9493B7CF5E0ACF4570A88DF808D79E4300" + } + }, + { + "binary": "120025220020000024000000026140000000000003E86840000000000000016015D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0744073552B3DC7AE99DDF4E4FF0D60E6D0BE4688E3474D363603FA25DA6AD8BBA8F0E4E3EA82ADB2B57F5B9A6C379969E00095546DDA0E74FF3D0F0689351C2F8C06811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMWithdraw", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "LPTokenIn": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"}, + "Fee": "1", + "Flags": 2097152, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "73552B3DC7AE99DDF4E4FF0D60E6D0BE4688E3474D363603FA25DA6AD8BBA8F0E4E3EA82ADB2B57F5B9A6C379969E00095546DDA0E74FF3D0F0689351C2F8C06" + } + }, + { + "binary": "120025220040000024000000026140000000000003E8684000000000000001601640000000000000197321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0744023BAFE5BFE58E7BF0B02B5875983D007C10796C8E62A190BF688EBE5D8A104DAD2DE7EDE995FE2E494883FD8140F38E22E3376A2F49C50EFCAA00C7499A4690E811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMWithdraw", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "Amount": "1000", + "EPrice": "25", + "Fee": "1", + "Flags": 4194304, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "23BAFE5BFE58E7BF0B02B5875983D007C10796C8E62A190BF688EBE5D8A104DAD2DE7EDE995FE2E494883FD8140F38E22E3376A2F49C50EFCAA00C7499A4690E" + } + }, + { + "binary": "120027220000000024000000026840000000000000016CD4C8E1BC9BF04000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0486DD4CC6F3B40B6C000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D074406B2A1548E6DC14681356C27CCBE7072CAB2AD8C72D0D7A045916FB0E0DBE6BF71A429CC519E9200172829D3EEF79100899D3A8710C1C3C1A2B664FD64086AD0A811462D4D845D20B4F09CFEA8BB4C01063D99FC9673EF01AE01C81149A91957F8F16BC57F3F200CD8C98375BF1791586E1F10318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMBid", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "AuthAccounts": [{"AuthAccount": {"Account": "rEaHTti4HZsMBpxTAF4ncWxkcdqDh1h6P7"}}], + "BidMax": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "35"}, + "BidMin": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "25"}, + "Fee": "1", + "Flags": 0, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "6B2A1548E6DC14681356C27CCBE7072CAB2AD8C72D0D7A045916FB0E0DBE6BF71A429CC519E9200172829D3EEF79100899D3A8710C1C3C1A2B664FD64086AD0A" + } + }, + { + "binary": "1200261500EA220000000024000000026840000000000000017321ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0744072767CF9A0F5E9C9DA6BBB6E84905B0ECDF122D3E2D730843EFD377521E8E73664AD809D0A54E8C75CD1735ACB64E310BB49FDED10913FA150B8C006D4ACEC00811462D4D845D20B4F09CFEA8BB4C01063D99FC9673E0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C", + "json": { + "Account": "rwr2UWxNwoBdysPSiDDraTQjAQKZEeZAcV", + "TransactionType": "AMMVote", + "Asset": {"currency": "XRP"}, + "Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"}, + "TradingFee": 234, + "Fee": "1", + "Flags": 0, + "Sequence": 2, + "SigningPubKey": "ED8A00C1D29E762266576408B08D583B987673550655F930635678B436D5CDF7D0", + "TxnSignature": "72767CF9A0F5E9C9DA6BBB6E84905B0ECDF122D3E2D730843EFD377521E8E73664AD809D0A54E8C75CD1735ACB64E310BB49FDED10913FA150B8C006D4ACEC00" + } }], "ledgerData": [{ "binary": "01E91435016340767BF1C4A3EACEB081770D8ADE216C85445DD6FB002C6B5A2930F2DECE006DA18150CB18F6DD33F6F0990754C962A7CCE62F332FF9C13939B03B864117F0BDA86B6E9B4F873B5C3E520634D343EF5D9D9A4246643D64DAD278BA95DC0EAC6EB5350CF970D521276CDE21276CE60A00", @@ -4463,4 +4670,4 @@ "transaction_hash": "DD33F6F0990754C962A7CCE62F332FF9C13939B03B864117F0BDA86B6E9B4F87" } }] -} \ No newline at end of file +} From feafc0c91b332ed37f10dbd853d2c07125d921f1 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 17 Nov 2022 13:37:45 -0500 Subject: [PATCH 52/61] update Issue type --- packages/ripple-binary-codec/src/types/issue.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ripple-binary-codec/src/types/issue.ts b/packages/ripple-binary-codec/src/types/issue.ts index 29bd160b..3c3925b9 100644 --- a/packages/ripple-binary-codec/src/types/issue.ts +++ b/packages/ripple-binary-codec/src/types/issue.ts @@ -41,7 +41,7 @@ class Issue extends SerializedType { * representing an integer amount * @returns An Amount object */ - static from(value: T): Issue { + static from(value: T): Issue { if (value instanceof Issue) { return value } From 98f8223b23def3229a42e56d39db42d8a65f506b Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 17 Nov 2022 14:20:57 -0500 Subject: [PATCH 53/61] add one asset and withdraw all tests --- .../src/models/transactions/AMMWithdraw.ts | 4 ---- packages/xrpl/test/models/AMMWithdraw.ts | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/xrpl/src/models/transactions/AMMWithdraw.ts b/packages/xrpl/src/models/transactions/AMMWithdraw.ts index eac8d218..1d8a9aa9 100644 --- a/packages/xrpl/src/models/transactions/AMMWithdraw.ts +++ b/packages/xrpl/src/models/transactions/AMMWithdraw.ts @@ -115,10 +115,6 @@ export function validateAMMWithdraw(tx: Record): void { throw new ValidationError('AMMWithdraw: must set Amount with Amount2') } else if (tx.EPrice != null && tx.Amount == null) { throw new ValidationError('AMMWithdraw: must set Amount with EPrice') - } else if (tx.LPTokenIn == null && tx.Amount == null) { - throw new ValidationError( - 'AMMWithdraw: must set at least LPTokenIn or Amount', - ) } if (tx.LPTokenIn != null && !isIssuedCurrency(tx.LPTokenIn)) { diff --git a/packages/xrpl/test/models/AMMWithdraw.ts b/packages/xrpl/test/models/AMMWithdraw.ts index 153766f8..c5ac476a 100644 --- a/packages/xrpl/test/models/AMMWithdraw.ts +++ b/packages/xrpl/test/models/AMMWithdraw.ts @@ -68,6 +68,17 @@ describe('AMMWithdraw', function () { assert.doesNotThrow(() => validate(withdraw)) }) + it(`verifies valid AMMWithdraw one asset withdraw all`, function () { + withdraw.Amount = '1000' + withdraw.Flags |= AMMWithdrawFlags.tfOneAssetWithdrawAll + assert.doesNotThrow(() => validate(withdraw)) + }) + + it(`verifies valid AMMWithdraw withdraw all`, function () { + withdraw.Flags |= AMMWithdrawFlags.tfWithdrawAll + assert.doesNotThrow(() => validate(withdraw)) + }) + it(`throws w/ missing field Asset`, function () { delete withdraw.Asset assert.throws( @@ -104,14 +115,6 @@ describe('AMMWithdraw', function () { ) }) - it(`throws w/ must set at least LPTokenIn or Amount`, function () { - assert.throws( - () => validate(withdraw), - ValidationError, - 'AMMWithdraw: must set at least LPTokenIn or Amount', - ) - }) - it(`throws w/ must set Amount with Amount2`, function () { withdraw.Amount2 = { currency: 'ETH', From ec1d8b67a50de5639914ddca5a931708d3f6482a Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Thu, 15 Dec 2022 13:06:39 -0500 Subject: [PATCH 54/61] refactor amm_info response fields to match AMMDevnet --- packages/xrpl/src/models/methods/ammInfo.ts | 133 ++++++++++---------- 1 file changed, 70 insertions(+), 63 deletions(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 68eeb7a0..e179a3df 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -45,83 +45,90 @@ interface VoteEntry { */ export interface AMMInfoResponse extends BaseResponse { result: { - /** - * The account that tracks the balance of LPTokens between the AMM instance via Trustline. - */ - AMMAccount: string - - /** - * Specifies one of the pool assets (XRP or token) of the AMM instance. - */ - Asset: Issue - - /** - * Specifies the other pool asset of the AMM instance. - */ - Asset2: Issue - - /** - * Details of the current owner of the auction slot. - */ - AuctionSlot?: { + amm: { /** - * The current owner of this auction slot. + * The account that tracks the balance of LPTokens between the AMM instance via Trustline. */ - Account: string + AMMAccount: string /** - * A list of at most 4 additional accounts that are authorized to trade at the discounted fee for this AMM instance. + * The AMM identifier that uniquely identifies an AMM instance. */ - AuthAccounts: AuthAccount[] + AMMID: string /** - * The trading fee to be charged to the auction owner, in the same format as TradingFee. - * By default this is 0, meaning that the auction owner can trade at no fee instead of the standard fee for this AMM. + * One of the pool assets (XRP or token) of the AMM instance. */ - DiscountedFee: number + Amount: Amount /** - * The time when this slot expires, in seconds since the Ripple Epoch. + * The other pool asset of the AMM instance. */ - Expiration: string + Amount2: Amount /** - * The amount the auction owner paid to win this slot, in LPTokens. + * Details of the current owner of the auction slot. */ - Price: Amount + AuctionSlot?: { + /** + * The current owner of this auction slot. + */ + Account: string + + /** + * A list of at most 4 additional accounts that are authorized to trade at the discounted fee for this AMM instance. + */ + AuthAccounts: AuthAccount[] + + /** + * The trading fee to be charged to the auction owner, in the same format as TradingFee. + * By default this is 0, meaning that the auction owner can trade at no fee instead of the standard fee for this AMM. + */ + DiscountedFee: number + + /** + * The time when this slot expires, in seconds since the Ripple Epoch. + */ + Expiration: string + + /** + * The amount the auction owner paid to win this slot, in LPTokens. + */ + Price: Amount + } + + /** + * The total outstanding balance of liquidity provider tokens from this AMM instance. + * The holders of these tokens can vote on the AMM's trading fee in proportion to their holdings, + * or redeem the tokens for a share of the AMM's assets which grows with the trading fees collected. + */ + LPToken: IssuedCurrencyAmount + + /** + * Specifies the fee, in basis point, to be charged to the traders for the trades + * executed against the AMM instance. Trading fee is a percentage of the trading volume. + * Valid values for this field are between 0 and 1000 inclusive. + * A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee + * between 0% and 1%. This field is required. + */ + TradingFee: number + + /** + * Keeps a track of up to eight active votes for the instance. + */ + VoteSlots?: VoteEntry[] + + /** + * The ledger index of the current in-progress ledger, which was used when + * retrieving this information. + */ + ledger_current_index?: number + + /** + * True if this data is from a validated ledger version; if omitted or set + * to false, this data is not final. + */ + validated?: boolean } - - /** - * The total outstanding balance of liquidity provider tokens from this AMM instance. - * The holders of these tokens can vote on the AMM's trading fee in proportion to their holdings, - * or redeem the tokens for a share of the AMM's assets which grows with the trading fees collected. - */ - LPTokenBalance: IssuedCurrencyAmount - - /** - * Specifies the fee, in basis point, to be charged to the traders for the trades - * executed against the AMM instance. Trading fee is a percentage of the trading volume. - * Valid values for this field are between 0 and 1000 inclusive. - * A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee - * between 0% and 1%. This field is required. - */ - TradingFee: number - - /** - * Keeps a track of up to eight active votes for the instance. - */ - VoteSlots?: VoteEntry[] - - /** - * The ledger index of the current in-progress ledger, which was used when - * retrieving this information. - */ - ledger_current_index?: number - - /** - * True if this data is from a validated ledger version; if omitted or set - * to false, this data is not final. - */ - validated?: boolean } } From 218ca005e1aa62e44715ef9fe31364d52056d7c0 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 9 Jan 2023 17:30:05 -0500 Subject: [PATCH 55/61] update definitions.json with refactored error codes --- .../ripple-binary-codec/src/enums/definitions.json | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/ripple-binary-codec/src/enums/definitions.json b/packages/ripple-binary-codec/src/enums/definitions.json index ab3bc26f..e5ecefb4 100644 --- a/packages/ripple-binary-codec/src/enums/definitions.json +++ b/packages/ripple-binary-codec/src/enums/definitions.json @@ -2417,8 +2417,7 @@ "temUNKNOWN": -264, "temSEQ_AND_TICKET": -263, "temBAD_NFTOKEN_TRANSFER_FEE": -262, - "temBAD_AMM_OPTIONS": -261, - "temBAD_AMM_TOKENS": -260, + "temAMM_BAD_TOKENS": -261, "tefFAILURE": -199, "tefALREADY": -198, @@ -2504,14 +2503,13 @@ "tecINSUFFICIENT_FUNDS": 159, "tecOBJECT_NOT_FOUND": 160, "tecINSUFFICIENT_PAYMENT": 161, - "tecUNFUNDED_AMM": 162, + "tecAMM_UNFUNDED": 162, "tecAMM_BALANCE": 163, "tecAMM_FAILED_DEPOSIT": 164, "tecAMM_FAILED_WITHDRAW": 165, "tecAMM_INVALID_TOKENS": 166, - "tecAMM_EXISTS": 167, - "tecAMM_FAILED_BID": 168, - "tecAMM_FAILED_VOTE": 169 + "tecAMM_FAILED_BID": 167, + "tecAMM_FAILED_VOTE": 168 }, "TRANSACTION_TYPES": { "Invalid": -1, From e634db3dd2004b83edeb9884cb5c91dc91b329af Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 9 Jan 2023 17:43:48 -0500 Subject: [PATCH 56/61] update ammInfo.ts response model --- packages/xrpl/src/models/methods/ammInfo.ts | 67 +++++++++++++-------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index e179a3df..4a63df93 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -25,17 +25,13 @@ export interface AMMInfoRequest extends BaseRequest { } interface AuthAccount { - AuthAccount: { - Account: string - } + account: string } interface VoteEntry { - VoteEntry: { - Account: string - TradingFee: number - VoteWeight: number - } + account: string + trading_fee: number + vote_weight: number } /** @@ -49,52 +45,54 @@ export interface AMMInfoResponse extends BaseResponse { /** * The account that tracks the balance of LPTokens between the AMM instance via Trustline. */ - AMMAccount: string - - /** - * The AMM identifier that uniquely identifies an AMM instance. - */ - AMMID: string + amm_account: string /** * One of the pool assets (XRP or token) of the AMM instance. */ - Amount: Amount + amount: Amount /** * The other pool asset of the AMM instance. */ - Amount2: Amount + amount2: Amount + + /** + * Flag indicating whether asset2 is frozen. + */ + asset2_frozen: boolean /** * Details of the current owner of the auction slot. */ - AuctionSlot?: { + auction_slot?: { /** * The current owner of this auction slot. */ - Account: string + account: string /** * A list of at most 4 additional accounts that are authorized to trade at the discounted fee for this AMM instance. */ - AuthAccounts: AuthAccount[] + auth_accounts: AuthAccount[] /** * The trading fee to be charged to the auction owner, in the same format as TradingFee. * By default this is 0, meaning that the auction owner can trade at no fee instead of the standard fee for this AMM. */ - DiscountedFee: number + discounted_fee: number /** * The time when this slot expires, in seconds since the Ripple Epoch. */ - Expiration: string + expiration: string /** * The amount the auction owner paid to win this slot, in LPTokens. */ - Price: Amount + price: Amount + + time_interval: number } /** @@ -102,7 +100,7 @@ export interface AMMInfoResponse extends BaseResponse { * The holders of these tokens can vote on the AMM's trading fee in proportion to their holdings, * or redeem the tokens for a share of the AMM's assets which grows with the trading fees collected. */ - LPToken: IssuedCurrencyAmount + lp_token: IssuedCurrencyAmount /** * Specifies the fee, in basis point, to be charged to the traders for the trades @@ -111,12 +109,12 @@ export interface AMMInfoResponse extends BaseResponse { * A value of 1 is equivalent to 1/10 bps or 0.001%, allowing trading fee * between 0% and 1%. This field is required. */ - TradingFee: number + trading_fee: number /** * Keeps a track of up to eight active votes for the instance. */ - VoteSlots?: VoteEntry[] + vote_slots?: VoteEntry[] /** * The ledger index of the current in-progress ledger, which was used when @@ -130,5 +128,24 @@ export interface AMMInfoResponse extends BaseResponse { */ validated?: boolean } + + /** + * The identifying hash of the ledger that was used to generate this + * response. + */ + ledger_hash?: string + + /** + * The ledger index of the ledger version that was used to generate this + * response. + */ + ledger_index?: number + + /** + * If included and set to true, the information in this response comes from + * a validated ledger version. Otherwise, the information is subject to + * change. + */ + validated?: boolean } } From f3d6bd4be4634bb87b29cf92eb3fb520da64851b Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 9 Jan 2023 17:51:33 -0500 Subject: [PATCH 57/61] remove invalid fields from ammInfo.ts response model --- packages/xrpl/src/models/methods/ammInfo.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 4a63df93..eaf6fd9f 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -115,18 +115,6 @@ export interface AMMInfoResponse extends BaseResponse { * Keeps a track of up to eight active votes for the instance. */ vote_slots?: VoteEntry[] - - /** - * The ledger index of the current in-progress ledger, which was used when - * retrieving this information. - */ - ledger_current_index?: number - - /** - * True if this data is from a validated ledger version; if omitted or set - * to false, this data is not final. - */ - validated?: boolean } /** From 8cdeb2ba99ce3682b3b00ab38111fbf65e7bcffe Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Mon, 9 Jan 2023 18:13:18 -0500 Subject: [PATCH 58/61] update time_interval description --- packages/xrpl/src/models/methods/ammInfo.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index eaf6fd9f..20585708 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -92,6 +92,9 @@ export interface AMMInfoResponse extends BaseResponse { */ price: Amount + /** + * Total slot time of 24-hours is divided into 20 equal time intervals. + */ time_interval: number } From 287dc1acf8f0d0e56287f6de602ab09648f9637d Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 15 Feb 2023 18:18:07 -0500 Subject: [PATCH 59/61] rename test model names and fix lint errors --- packages/xrpl/test/models/{AMMBid.ts => AMMBid.test.ts} | 3 ++- packages/xrpl/test/models/{AMMCreate.ts => AMMCreate.test.ts} | 3 ++- .../xrpl/test/models/{AMMDeposit.ts => AMMDeposit.test.ts} | 3 ++- packages/xrpl/test/models/{AMMVote.ts => AMMVote.test.ts} | 3 ++- .../xrpl/test/models/{AMMWithdraw.ts => AMMWithdraw.test.ts} | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) rename packages/xrpl/test/models/{AMMBid.ts => AMMBid.test.ts} (97%) rename packages/xrpl/test/models/{AMMCreate.ts => AMMCreate.test.ts} (97%) rename packages/xrpl/test/models/{AMMDeposit.ts => AMMDeposit.test.ts} (98%) rename packages/xrpl/test/models/{AMMVote.ts => AMMVote.test.ts} (97%) rename packages/xrpl/test/models/{AMMWithdraw.ts => AMMWithdraw.test.ts} (98%) diff --git a/packages/xrpl/test/models/AMMBid.ts b/packages/xrpl/test/models/AMMBid.test.ts similarity index 97% rename from packages/xrpl/test/models/AMMBid.ts rename to packages/xrpl/test/models/AMMBid.test.ts index 834bf34d..0ef28dce 100644 --- a/packages/xrpl/test/models/AMMBid.ts +++ b/packages/xrpl/test/models/AMMBid.test.ts @@ -1,5 +1,6 @@ import { assert } from 'chai' -import { validate, ValidationError } from 'xrpl-local' + +import { validate, ValidationError } from '../../src' /** * AMMBid Transaction Verification Testing. diff --git a/packages/xrpl/test/models/AMMCreate.ts b/packages/xrpl/test/models/AMMCreate.test.ts similarity index 97% rename from packages/xrpl/test/models/AMMCreate.ts rename to packages/xrpl/test/models/AMMCreate.test.ts index d75a1f17..03b5028b 100644 --- a/packages/xrpl/test/models/AMMCreate.ts +++ b/packages/xrpl/test/models/AMMCreate.test.ts @@ -1,5 +1,6 @@ import { assert } from 'chai' -import { validate, ValidationError } from 'xrpl-local' + +import { validate, ValidationError } from '../../src' /** * AMMCreate Transaction Verification Testing. diff --git a/packages/xrpl/test/models/AMMDeposit.ts b/packages/xrpl/test/models/AMMDeposit.test.ts similarity index 98% rename from packages/xrpl/test/models/AMMDeposit.ts rename to packages/xrpl/test/models/AMMDeposit.test.ts index f7b65fd3..9eeb6ec3 100644 --- a/packages/xrpl/test/models/AMMDeposit.ts +++ b/packages/xrpl/test/models/AMMDeposit.test.ts @@ -1,6 +1,7 @@ /* eslint-disable no-bitwise -- bitwise necessary for enabling flags */ import { assert } from 'chai' -import { AMMDepositFlags, validate, ValidationError } from 'xrpl-local' + +import { AMMDepositFlags, validate, ValidationError } from '../../src' /** * AMMDeposit Transaction Verification Testing. diff --git a/packages/xrpl/test/models/AMMVote.ts b/packages/xrpl/test/models/AMMVote.test.ts similarity index 97% rename from packages/xrpl/test/models/AMMVote.ts rename to packages/xrpl/test/models/AMMVote.test.ts index f00350b4..765690cc 100644 --- a/packages/xrpl/test/models/AMMVote.ts +++ b/packages/xrpl/test/models/AMMVote.test.ts @@ -1,5 +1,6 @@ import { assert } from 'chai' -import { validate, ValidationError } from 'xrpl-local' + +import { validate, ValidationError } from '../../src' /** * AMMVote Transaction Verification Testing. diff --git a/packages/xrpl/test/models/AMMWithdraw.ts b/packages/xrpl/test/models/AMMWithdraw.test.ts similarity index 98% rename from packages/xrpl/test/models/AMMWithdraw.ts rename to packages/xrpl/test/models/AMMWithdraw.test.ts index c5ac476a..27a5c5c0 100644 --- a/packages/xrpl/test/models/AMMWithdraw.ts +++ b/packages/xrpl/test/models/AMMWithdraw.test.ts @@ -1,6 +1,7 @@ /* eslint-disable no-bitwise -- bitwise necessary for enabling flags */ import { assert } from 'chai' -import { AMMWithdrawFlags, validate, ValidationError } from 'xrpl-local' + +import { AMMWithdrawFlags, validate, ValidationError } from '../../src' /** * AMMWithdraw Transaction Verification Testing. From 7e8427785cdececec9c83d61c7c01f02baeb433b Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 15 Feb 2023 18:21:30 -0500 Subject: [PATCH 60/61] add Owner Reserve Fee for AMMCreate transaction --- packages/xrpl/src/sugar/autofill.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/xrpl/src/sugar/autofill.ts b/packages/xrpl/src/sugar/autofill.ts index 05d50a96..cdcc97b0 100644 --- a/packages/xrpl/src/sugar/autofill.ts +++ b/packages/xrpl/src/sugar/autofill.ts @@ -140,7 +140,7 @@ async function setNextValidSequenceNumber( tx.Sequence = data.result.account_data.Sequence } -async function fetchAccountDeleteFee(client: Client): Promise { +async function fetchOwnerReserveFee(client: Client): Promise { const response = await client.request({ command: 'server_state' }) const fee = response.result.state.validated_ledger?.reserve_inc @@ -172,9 +172,11 @@ async function calculateFeePerTransactionType( baseFee = product.dp(0, BigNumber.ROUND_CEIL) } - // AccountDelete Transaction - if (tx.TransactionType === 'AccountDelete') { - baseFee = await fetchAccountDeleteFee(client) + if ( + tx.TransactionType === 'AccountDelete' || + tx.TransactionType === 'AMMCreate' + ) { + baseFee = await fetchOwnerReserveFee(client) } /* From d2f7fe622bfbdb9e9c89f7c6b4a2347301b5be72 Mon Sep 17 00:00:00 2001 From: Omar Khan Date: Wed, 15 Feb 2023 18:45:07 -0500 Subject: [PATCH 61/61] add missing asset_frozen field --- packages/xrpl/src/models/methods/ammInfo.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/xrpl/src/models/methods/ammInfo.ts b/packages/xrpl/src/models/methods/ammInfo.ts index 20585708..6ad5135f 100644 --- a/packages/xrpl/src/models/methods/ammInfo.ts +++ b/packages/xrpl/src/models/methods/ammInfo.ts @@ -58,7 +58,12 @@ export interface AMMInfoResponse extends BaseResponse { amount2: Amount /** - * Flag indicating whether asset2 is frozen. + * (Omitted for XRP) If true, the amount currency is currently frozen for asset. + */ + asset_frozen: boolean + + /** + * (Omitted for XRP) If true, the amount currency is currently frozen for asset2. */ asset2_frozen: boolean