From 78b1c2076b3f7fee697e6673ebe48508ce920dd7 Mon Sep 17 00:00:00 2001 From: Mayukha Vadari Date: Mon, 6 Jan 2025 17:02:16 -0500 Subject: [PATCH] add sugar method --- packages/xrpl/src/client/index.ts | 68 +++++++++++++++++++- packages/xrpl/src/models/methods/index.ts | 2 + packages/xrpl/src/models/methods/simulate.ts | 28 ++++---- packages/xrpl/src/sugar/submit.ts | 5 +- 4 files changed, 83 insertions(+), 20 deletions(-) diff --git a/packages/xrpl/src/client/index.ts b/packages/xrpl/src/client/index.ts index 722b169f2a..4272773812 100644 --- a/packages/xrpl/src/client/index.ts +++ b/packages/xrpl/src/client/index.ts @@ -40,6 +40,8 @@ import type { MarkerRequest, MarkerResponse, SubmitResponse, + SimulateResponse, + SimulateRequest, } from '../models/methods' import type { BookOffer, BookOfferCurrency } from '../models/methods/bookOffers' import type { @@ -74,7 +76,7 @@ import { separateBuySellOrders, sortAndLimitOffers, } from '../sugar/getOrderbook' -import { dropsToXrp, hashes, isValidClassicAddress } from '../utils' +import { decode, dropsToXrp, hashes, isValidClassicAddress } from '../utils' import { Wallet } from '../Wallet' import { type FaucetRequestBody, @@ -764,6 +766,70 @@ class Client extends EventEmitter { return submitRequest(this, signedTx, opts?.failHard) } + /** + * Simulates an unsigned transaction. + * Steps performed on a transaction: + * 1. Autofill. + * 2. Sign & Encode. + * 3. Submit. + * + * @category Core + * + * @param transaction - A transaction to autofill, sign & encode, and submit. + * @param opts - (Optional) Options used to sign and submit a transaction. + * @param opts.binary - If true, return the metadata in a binary encoding. + * + * @returns A promise that contains SimulateResponse. + * @throws RippledError if the simulate request fails. + */ + public async simulate( + transaction: SubmittableTransaction | string, + opts?: { + // If true, return the binary-encoded representation of the results. + binary?: boolean + }, + ): Promise { + // verify that the transaction isn't signed + const decodedTx = + typeof transaction === 'string' + ? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- needed for typing + (decode(transaction) as unknown as SubmittableTransaction) + : transaction + if (typeof decodedTx === 'string') { + throw new ValidationError( + 'Provided transaction is not a valid transaction.', + ) + } + if (decodedTx.TxnSignature !== '' && decodedTx.TxnSignature != null) { + throw new ValidationError('Transaction must not be signed.') + } + if ( + decodedTx.Signers?.some( + (signer) => + signer.Signer.TxnSignature !== '' && + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- needed for JS + signer.Signer.TxnSignature != null, + ) + ) { + throw new ValidationError('Transaction must not be signed.') + } + + setValidAddresses(decodedTx) + setTransactionFlagsToNumber(decodedTx) + + if (decodedTx.NetworkID == null) { + decodedTx.NetworkID = txNeedsNetworkID(this) ? this.networkID : undefined + } + + // send request + const binary = opts?.binary ?? false + const request: SimulateRequest = + typeof transaction === 'string' + ? { command: 'simulate', tx_blob: transaction, binary } + : { command: 'simulate', tx_json: transaction, binary } + return this.request(request) + } + /** * Asynchronously submits a transaction and verifies that it has been included in a * validated ledger (or has errored/will not be included for some reason). diff --git a/packages/xrpl/src/models/methods/index.ts b/packages/xrpl/src/models/methods/index.ts index f1df73050b..e055658a8b 100644 --- a/packages/xrpl/src/models/methods/index.ts +++ b/packages/xrpl/src/models/methods/index.ts @@ -211,6 +211,7 @@ type Request = | LedgerDataRequest | LedgerEntryRequest // transaction methods + | SimulateRequest | SubmitRequest | SubmitMultisignedRequest | TransactionEntryRequest @@ -269,6 +270,7 @@ type Response = | LedgerDataResponse | LedgerEntryResponse // transaction methods + | SimulateResponse | SubmitResponse | SubmitMultisignedVersionResponseMap | TransactionEntryResponse diff --git a/packages/xrpl/src/models/methods/simulate.ts b/packages/xrpl/src/models/methods/simulate.ts index 49d65a93a2..1acf8ff4af 100644 --- a/packages/xrpl/src/models/methods/simulate.ts +++ b/packages/xrpl/src/models/methods/simulate.ts @@ -12,13 +12,8 @@ import { BaseRequest, BaseResponse } from './baseMethod' * * @category Requests */ -export type SimulateRequest = SimulateBinaryRequest | SimulateJsonRequest - -export type SimulateBinaryRequest = BaseRequest & { - command: 'simulate' - - binary: true -} & ( +export type SimulateRequest = SimulateRequestBase & + ( | { tx_blob: string } @@ -27,18 +22,19 @@ export type SimulateBinaryRequest = BaseRequest & { } ) -export type SimulateJsonRequest = BaseRequest & { +export interface SimulateRequestBase extends BaseRequest { command: 'simulate' + binary?: boolean +} + +export type SimulateBinaryRequest = SimulateRequest & { + binary: true +} + +export type SimulateJsonRequest = SimulateRequest & { binary?: false -} & ( - | { - tx_blob: string - } - | { - tx_json: Transaction - } - ) +} export type SimulateResponse = SimulateBinaryResponse | SimulateJsonResponse diff --git a/packages/xrpl/src/sugar/submit.ts b/packages/xrpl/src/sugar/submit.ts index 423a863cf8..b14f68d945 100644 --- a/packages/xrpl/src/sugar/submit.ts +++ b/packages/xrpl/src/sugar/submit.ts @@ -1,5 +1,3 @@ -import { decode, encode } from 'ripple-binary-codec' - import type { Client, SubmitRequest, @@ -12,6 +10,7 @@ import { ValidationError, XrplError } from '../errors' import { Signer } from '../models/common' import { TxResponse } from '../models/methods' import { BaseTransaction } from '../models/transactions/common' +import { decode, encode } from '../utils' /** Approximate time for a ledger to close, in milliseconds */ const LEDGER_CLOSE_TIME = 1000 @@ -52,7 +51,7 @@ export async function submitRequest( failHard = false, ): Promise { if (!isSigned(signedTransaction)) { - throw new ValidationError('Transaction must be signed') + throw new ValidationError('Transaction must be signed.') } const signedTxEncoded =