@bithomp/xrpl-api 2.7.12 → 2.7.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,8 @@
1
+ import { XrplDefinitionsBase } from "ripple-binary-codec";
1
2
  import { Connection } from "../connection";
2
3
  export interface GetFeeOptions {
3
4
  connection?: Connection;
5
+ tx?: any;
6
+ definitions?: XrplDefinitionsBase;
4
7
  }
5
8
  export declare function getFee(options?: GetFeeOptions): Promise<string | null>;
package/lib/ledger/fee.js CHANGED
@@ -25,6 +25,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.getFee = void 0;
27
27
  const bignumber_js_1 = require("bignumber.js");
28
+ const ripple_binary_codec_1 = require("ripple-binary-codec");
28
29
  const Client = __importStar(require("../client"));
29
30
  const common_1 = require("../common");
30
31
  async function getFee(options = {}) {
@@ -32,14 +33,25 @@ async function getFee(options = {}) {
32
33
  if (!connection) {
33
34
  throw new Error("There is no connection");
34
35
  }
36
+ let txBlob;
37
+ if (typeof options.tx === "string") {
38
+ txBlob = options.tx;
39
+ }
40
+ else if (typeof options.tx === "object") {
41
+ txBlob = (0, ripple_binary_codec_1.encode)(options.tx, options.definitions);
42
+ }
35
43
  const response = await connection.request({
36
44
  command: "fee",
45
+ tx_blob: txBlob,
37
46
  });
38
- const baseFee = response?.result?.drops?.base_fee;
39
- if (!baseFee) {
47
+ const openLedgerFee = response?.result?.drops?.open_ledger_fee;
48
+ if (!openLedgerFee) {
40
49
  return null;
41
50
  }
42
- const fee = new bignumber_js_1.BigNumber(baseFee).multipliedBy(Client.feeCushion).dividedBy(common_1.dropsInXRP);
51
+ const fee = new bignumber_js_1.BigNumber(openLedgerFee)
52
+ .multipliedBy(Client.feeCushion)
53
+ .dividedBy(common_1.dropsInXRP)
54
+ .decimalPlaces(6, bignumber_js_1.BigNumber.ROUND_UP);
43
55
  return fee.toString();
44
56
  }
45
57
  exports.getFee = getFee;
@@ -32,6 +32,7 @@ interface LegacyPaymentInterface {
32
32
  }
33
33
  export declare function legacyPayment(data: LegacyPaymentInterface, definitions?: XrplDefinitionsBase, validateTx?: boolean): Promise<TransactionResponse | FormattedTransaction | ErrorResponse>;
34
34
  export declare function getAccountPaymentParams(account: string, connection?: Connection): Promise<AccountPaymentParamsInterface | ErrorResponse>;
35
+ export declare function getTxSubmitParams(account: string, tx?: string | any, definitions?: XrplDefinitionsBase, connection?: Connection): Promise<AccountPaymentParamsInterface | ErrorResponse>;
35
36
  export interface SubmitOptionsInterface {
36
37
  connection?: Connection;
37
38
  definitions?: XrplDefinitionsBase;
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.submit = exports.getAccountPaymentParams = exports.legacyPayment = exports.getTransactionByCTID = exports.getTransaction = void 0;
26
+ exports.submit = exports.getTxSubmitParams = exports.getAccountPaymentParams = exports.legacyPayment = exports.getTransactionByCTID = exports.getTransaction = void 0;
27
27
  const xrpl = __importStar(require("xrpl"));
28
28
  const ripple_binary_codec_1 = require("ripple-binary-codec");
29
29
  const Client = __importStar(require("../client"));
@@ -184,18 +184,18 @@ async function legacyPayment(data, definitions, validateTx) {
184
184
  memos: data.memos,
185
185
  };
186
186
  const transaction = (0, payment_1.createPaymentTransaction)(data.sourceAddress, txPayment);
187
- const paymentParams = await getAccountPaymentParams(data.sourceAddress, connection);
188
- if ("error" in paymentParams) {
189
- return paymentParams;
187
+ const submitParams = await getTxSubmitParams(data.sourceAddress, transaction, definitions, connection);
188
+ if ("error" in submitParams) {
189
+ return submitParams;
190
190
  }
191
191
  if (data.fee) {
192
192
  transaction.Fee = (0, common_1.xrpToDrops)(data.fee);
193
193
  }
194
194
  else {
195
- transaction.Fee = paymentParams.fee;
195
+ transaction.Fee = submitParams.fee;
196
196
  }
197
- transaction.Sequence = paymentParams.sequence;
198
- transaction.LastLedgerSequence = paymentParams.lastLedgerSequence;
197
+ transaction.Sequence = submitParams.sequence;
198
+ transaction.LastLedgerSequence = submitParams.lastLedgerSequence;
199
199
  const wallet = xrpl.Wallet.fromSeed(data.secret);
200
200
  const signedTransaction = (0, wallet_1.signTransaction)(wallet, transaction, false, definitions, validateTx).tx_blob;
201
201
  return await submit(signedTransaction, { connection, definitions });
@@ -213,24 +213,34 @@ async function getAccountPaymentParams(account, connection) {
213
213
  if (fee > FEE_LIMIT) {
214
214
  fee = FEE_LIMIT;
215
215
  }
216
- resolve((0, common_1.xrpToDrops)(fee));
216
+ resolve((0, common_1.xrpToDrops)(fee.toString()));
217
217
  });
218
218
  const sequencePromise = new Promise(async (resolve, rejects) => {
219
- const accountInfo = await Client.getAccountInfo(account, { connection });
220
- if (!accountInfo) {
221
- return rejects(new Error("Account not found"));
219
+ try {
220
+ const accountData = await Client.getAccountInfoData(account, { connection });
221
+ if (!accountData) {
222
+ return rejects(new Error("Account not found"));
223
+ }
224
+ if ("error" in accountData) {
225
+ return rejects(new Error(accountData.error));
226
+ }
227
+ resolve(accountData.Sequence);
222
228
  }
223
- if ("error" in accountInfo) {
224
- return rejects(new Error(accountInfo.error));
229
+ catch (e) {
230
+ rejects(e);
225
231
  }
226
- resolve(accountInfo?.account_data?.Sequence);
227
232
  });
228
233
  const lastLedgerSequencePromise = new Promise(async (resolve) => {
229
- const ledgerIndex = await Client.getLedgerIndex();
230
- if (ledgerIndex !== undefined) {
231
- resolve(ledgerIndex + MAX_LEDGERS_AWAIT);
234
+ try {
235
+ const ledgerIndex = await Client.getLedgerIndex();
236
+ if (ledgerIndex !== undefined) {
237
+ resolve(ledgerIndex + MAX_LEDGERS_AWAIT);
238
+ }
239
+ resolve(undefined);
240
+ }
241
+ catch (e) {
242
+ resolve(undefined);
232
243
  }
233
- resolve(undefined);
234
244
  });
235
245
  const result = await Promise.all([feePromise, sequencePromise, lastLedgerSequencePromise]);
236
246
  return {
@@ -249,6 +259,72 @@ async function getAccountPaymentParams(account, connection) {
249
259
  }
250
260
  }
251
261
  exports.getAccountPaymentParams = getAccountPaymentParams;
262
+ async function getTxSubmitParams(account, tx, definitions, connection) {
263
+ try {
264
+ connection = connection || Client.findConnection("submit") || undefined;
265
+ if (!connection) {
266
+ throw new Error("There is no connection");
267
+ }
268
+ const feePromise = new Promise(async (resolve, rejects) => {
269
+ try {
270
+ if (tx && typeof tx === "object") {
271
+ tx = { ...tx, Sequence: 0, Fee: "0", SigningPubKey: "" };
272
+ }
273
+ const baseFee = await Client.getFee({ connection, tx, definitions });
274
+ let fee = parseFloat(baseFee);
275
+ if (fee > FEE_LIMIT) {
276
+ fee = FEE_LIMIT;
277
+ }
278
+ resolve((0, common_1.xrpToDrops)(fee.toString()));
279
+ }
280
+ catch (e) {
281
+ rejects(e);
282
+ }
283
+ });
284
+ const sequencePromise = new Promise(async (resolve, rejects) => {
285
+ try {
286
+ const accountData = await Client.getAccountInfoData(account, { connection });
287
+ if (!accountData) {
288
+ return rejects(new Error("Account not found"));
289
+ }
290
+ if ("error" in accountData) {
291
+ return rejects(new Error(accountData.error));
292
+ }
293
+ resolve(accountData.Sequence);
294
+ }
295
+ catch (e) {
296
+ rejects(e);
297
+ }
298
+ });
299
+ const lastLedgerSequencePromise = new Promise(async (resolve) => {
300
+ try {
301
+ const ledgerIndex = await Client.getLedgerIndex();
302
+ if (ledgerIndex !== undefined) {
303
+ resolve(ledgerIndex + MAX_LEDGERS_AWAIT);
304
+ }
305
+ resolve(undefined);
306
+ }
307
+ catch (e) {
308
+ resolve(undefined);
309
+ }
310
+ });
311
+ const result = await Promise.all([feePromise, sequencePromise, lastLedgerSequencePromise]);
312
+ return {
313
+ fee: result[0],
314
+ sequence: result[1],
315
+ lastLedgerSequence: result[2],
316
+ networkID: connection.getNetworkID(),
317
+ };
318
+ }
319
+ catch (e) {
320
+ return {
321
+ account,
322
+ status: "error",
323
+ error: e.message,
324
+ };
325
+ }
326
+ }
327
+ exports.getTxSubmitParams = getTxSubmitParams;
252
328
  async function submit(signedTransaction, options = {}) {
253
329
  const connection = options.connection || Client.findConnection("submit");
254
330
  if (!connection) {
@@ -259,11 +335,11 @@ async function submit(signedTransaction, options = {}) {
259
335
  return response;
260
336
  }
261
337
  const result = response?.result;
262
- const resultGroup = result?.engine_result.slice(0, 3);
338
+ const resultGroup = result?.engine_result?.slice(0, 3);
263
339
  if ((submitErrorsGroup.includes(resultGroup) && result?.engine_result !== "terQUEUED") || result?.kept === false) {
264
340
  return result;
265
341
  }
266
- const txHash = result.tx_json?.hash;
342
+ const txHash = result?.tx_json?.hash;
267
343
  if (!txHash) {
268
344
  return result;
269
345
  }
@@ -275,10 +351,12 @@ async function submit(signedTransaction, options = {}) {
275
351
  else {
276
352
  const ledgerIndex = await Client.getLedgerIndex();
277
353
  if (ledgerIndex !== undefined) {
278
- lastLedger = ledgerIndex + MAX_LEDGERS_AWAIT;
354
+ const ledgersToWait = MAX_LEDGERS_AWAIT * 2;
355
+ lastLedger = ledgerIndex + ledgersToWait;
279
356
  }
280
357
  }
281
- return await waitForFinalTransactionOutcome(txHash, lastLedger);
358
+ const finalResult = await waitForFinalTransactionOutcome(txHash, lastLedger);
359
+ return finalResult;
282
360
  }
283
361
  exports.submit = submit;
284
362
  async function waitForFinalTransactionOutcome(txHash, lastLedger) {
@@ -294,5 +372,13 @@ async function waitForFinalTransactionOutcome(txHash, lastLedger) {
294
372
  return waitForFinalTransactionOutcome(txHash, lastLedger);
295
373
  }
296
374
  }
375
+ if (tx && !tx.hasOwnProperty("error") && tx.validated === false) {
376
+ if (tx.hasOwnProperty("LastLedgerSequence")) {
377
+ return { ...tx, status: "timeout", error: "lastLedgerIndexReached" };
378
+ }
379
+ else {
380
+ return { ...tx, status: "timeout", error: "waitingForValidation" };
381
+ }
382
+ }
297
383
  return tx;
298
384
  }
@@ -4,6 +4,8 @@ export interface Trustline {
4
4
  currency: string;
5
5
  limit: string;
6
6
  limit_peer: string;
7
+ lock_count?: number;
8
+ locked_balance?: string;
7
9
  quality_in: number;
8
10
  quality_out: number;
9
11
  no_ripple?: boolean;
@@ -25,15 +25,22 @@ const RippleStateToTrustLine = (ledgerEntry, account) => {
25
25
  const balance = ledgerEntry.HighLimit.issuer === account && ledgerEntry.Balance.value.startsWith("-")
26
26
  ? ledgerEntry.Balance.value.slice(1)
27
27
  : ledgerEntry.Balance.value;
28
- return {
28
+ const lockedBalance = ledgerEntry.LockedBalance?.value;
29
+ let lockCount = undefined;
30
+ if (lockedBalance) {
31
+ lockCount = ledgerEntry.LockCount;
32
+ }
33
+ return (0, common_1.removeUndefined)({
29
34
  account: counterparty.issuer,
30
35
  balance,
31
36
  currency: self.currency,
32
37
  limit: self.value,
33
38
  limit_peer: counterparty.value,
39
+ lock_count: lockCount,
40
+ locked_balance: lockedBalance,
34
41
  no_ripple,
35
42
  no_ripple_peer,
36
- };
43
+ });
37
44
  };
38
45
  function accountObjectsToNFTOffers(accountObjects) {
39
46
  const nftOfferObjects = accountObjects.filter((obj) => {
@@ -1,7 +1,8 @@
1
- declare function parseBalanceChanges(metadata: any, nativeCurrency?: string): {
1
+ import { TransactionMetadata } from "xrpl";
2
+ declare function parseBalanceChanges(metadata: TransactionMetadata, nativeCurrency?: string): {
2
3
  [x: string]: any[];
3
4
  };
4
- declare function parseFinalBalances(metadata: any): {
5
+ declare function parseFinalBalances(metadata: TransactionMetadata): {
5
6
  [x: string]: any[];
6
7
  };
7
8
  export { parseBalanceChanges, parseFinalBalances };
@@ -1,7 +1,8 @@
1
- declare function parseLockedBalanceChanges(metadata: any): {
1
+ import { TransactionMetadata } from "xrpl";
2
+ declare function parseLockedBalanceChanges(metadata: TransactionMetadata): {
2
3
  [x: string]: any[];
3
4
  };
4
- declare function parseFinalLockedBalances(metadata: any): {
5
+ declare function parseFinalLockedBalances(metadata: TransactionMetadata): {
5
6
  [x: string]: any[];
6
7
  };
7
8
  export { parseLockedBalanceChanges, parseFinalLockedBalances };
@@ -30,6 +30,9 @@ function computeBalanceChange(node) {
30
30
  else if (node.previousFields.LockedBalance && node.finalFields.LockedBalance) {
31
31
  value = parseValue(node.finalFields.LockedBalance).minus(parseValue(node.previousFields.LockedBalance));
32
32
  }
33
+ else if (node.previousFields.LockedBalance) {
34
+ value = parseValue(node.previousFields.LockedBalance).negated();
35
+ }
33
36
  return value === null ? null : value.isZero() ? null : value;
34
37
  }
35
38
  function parseFinalBalance(node) {
@@ -61,11 +64,12 @@ function parseTrustlineQuantity(node, valueParser) {
61
64
  return null;
62
65
  }
63
66
  const fields = lodash_1.default.isEmpty(node.newFields) ? node.finalFields : node.newFields;
67
+ const LockedBalanceFields = lodash_1.default.isEmpty(node.newFields?.LockedBalance) ? lodash_1.default.isEmpty(node.finalFields?.LockedBalance) ? node.previousFields : node.finalFields : node.newFields;
64
68
  const result = {
65
69
  address: fields.LowLimit.issuer,
66
70
  lockedBalance: {
67
- counterparty: fields.HighLimit.issuer,
68
- currency: fields.LockedBalance.currency,
71
+ counterparty: LockedBalanceFields.LockedBalance.issuer,
72
+ currency: LockedBalanceFields.LockedBalance.currency,
69
73
  value: value.toString(),
70
74
  },
71
75
  };
@@ -134,6 +134,7 @@ function parseTransaction(tx, includeRawTransaction, nativeCurrency, definitions
134
134
  address: (0, account_1.parseAccount)(tx.Account),
135
135
  sequence: tx.Sequence,
136
136
  id: tx.hash,
137
+ ctid: tx.ctid,
137
138
  specification: (0, common_1.removeUndefined)(specification),
138
139
  outcome: outcome ? (0, common_1.removeUndefined)(outcome) : undefined,
139
140
  rawTransaction: includeRawTransaction ? JSON.stringify(tx) : undefined,
@@ -1,6 +1,7 @@
1
+ import { TransactionMetadata } from "xrpl";
1
2
  import { Amount, FormattedIssuedCurrencyAmount } from "./types/objects";
2
3
  declare function isValidSecret(secret: string): boolean;
3
4
  declare function toRippledAmount(amount: Amount | FormattedIssuedCurrencyAmount): Amount;
4
5
  declare function iso8601ToRippleTime(iso8601: string): number;
5
- declare function normalizeNodes(metadata: any): any;
6
+ declare function normalizeNodes(metadata: TransactionMetadata): any[];
6
7
  export { toRippledAmount, iso8601ToRippleTime, isValidSecret, normalizeNodes };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bithomp/xrpl-api",
3
- "version": "2.7.12",
3
+ "version": "2.7.15",
4
4
  "description": "A Bithomp JavaScript/TypeScript library for interacting with the XRP Ledger",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",