mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-13 09:05:49 +00:00
Compare commits
4 Commits
@transia/x
...
@transia/x
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6c11d1df8 | ||
|
|
526d1e7686 | ||
|
|
3c668f41b8 | ||
|
|
aeb29a20a1 |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@transia/xrpl",
|
"name": "@transia/xrpl",
|
||||||
"version": "2.7.3-alpha.20",
|
"version": "2.7.3-alpha.22",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"description": "A TypeScript/JavaScript API for interacting with the XRP Ledger in Node.js and the browser",
|
"description": "A TypeScript/JavaScript API for interacting with the XRP Ledger in Node.js and the browser",
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@@ -2,16 +2,15 @@ import {
|
|||||||
xAddressToClassicAddress,
|
xAddressToClassicAddress,
|
||||||
isValidXAddress,
|
isValidXAddress,
|
||||||
} from '@transia/ripple-address-codec'
|
} from '@transia/ripple-address-codec'
|
||||||
import BigNumber from 'bignumber.js'
|
import { encode } from '@transia/ripple-binary-codec'
|
||||||
|
|
||||||
import type { Client } from '..'
|
import type { Client } from '..'
|
||||||
import { ValidationError, XrplError } from '../errors'
|
import { ValidationError, XrplError } from '../errors'
|
||||||
import { AccountInfoRequest, AccountObjectsRequest } from '../models/methods'
|
import { AccountInfoRequest, AccountObjectsRequest } from '../models/methods'
|
||||||
import { Transaction } from '../models/transactions'
|
import { Transaction } from '../models/transactions'
|
||||||
import { setTransactionFlagsToNumber } from '../models/utils/flags'
|
import { setTransactionFlagsToNumber } from '../models/utils/flags'
|
||||||
import { xrpToDrops } from '../utils'
|
|
||||||
|
|
||||||
import { getFeeXrp } from './getFeeXrp'
|
import { getFeeEstimateXrp } from './getFeeXrp'
|
||||||
|
|
||||||
// Expire unconfirmed transactions after 20 ledger versions, approximately 1 minute, by default
|
// Expire unconfirmed transactions after 20 ledger versions, approximately 1 minute, by default
|
||||||
const LEDGER_OFFSET = 20
|
const LEDGER_OFFSET = 20
|
||||||
@@ -50,17 +49,18 @@ async function autofill<T extends Transaction>(
|
|||||||
if (tx.Sequence == null) {
|
if (tx.Sequence == null) {
|
||||||
promises.push(setNextValidSequenceNumber(this, tx))
|
promises.push(setNextValidSequenceNumber(this, tx))
|
||||||
}
|
}
|
||||||
if (tx.Fee == null) {
|
|
||||||
promises.push(calculateFeePerTransactionType(this, tx, signersCount))
|
|
||||||
}
|
|
||||||
if (tx.LastLedgerSequence == null) {
|
if (tx.LastLedgerSequence == null) {
|
||||||
promises.push(setLatestValidatedLedgerSequence(this, tx))
|
promises.push(setLatestValidatedLedgerSequence(this, tx))
|
||||||
}
|
}
|
||||||
if (tx.TransactionType === 'AccountDelete') {
|
if (tx.TransactionType === 'AccountDelete') {
|
||||||
promises.push(checkAccountDeleteBlockers(this, tx))
|
promises.push(checkAccountDeleteBlockers(this, tx))
|
||||||
}
|
}
|
||||||
|
await Promise.all(promises).then(() => tx)
|
||||||
|
|
||||||
return Promise.all(promises).then(() => tx)
|
if (tx.Fee == null) {
|
||||||
|
await calculateFeePerTransactionType(this, tx, signersCount)
|
||||||
|
}
|
||||||
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
function setValidAddresses(tx: Transaction): void {
|
function setValidAddresses(tx: Transaction): void {
|
||||||
@@ -146,64 +146,17 @@ async function setNextValidSequenceNumber(
|
|||||||
tx.Sequence = data.result.account_data.Sequence
|
tx.Sequence = data.result.account_data.Sequence
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchAccountDeleteFee(client: Client): Promise<BigNumber> {
|
|
||||||
const response = await client.request({ command: 'server_state' })
|
|
||||||
const fee = response.result.state.validated_ledger?.reserve_inc
|
|
||||||
|
|
||||||
if (fee == null) {
|
|
||||||
return Promise.reject(new Error('Could not fetch Owner Reserve.'))
|
|
||||||
}
|
|
||||||
|
|
||||||
return new BigNumber(fee)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function calculateFeePerTransactionType(
|
async function calculateFeePerTransactionType(
|
||||||
client: Client,
|
client: Client,
|
||||||
tx: Transaction,
|
tx: Transaction,
|
||||||
signersCount = 0,
|
signersCount = 0,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// netFee is usually 0.00001 XRP (10 drops)
|
const copyTx = { ...tx }
|
||||||
const netFeeXRP = await getFeeXrp(client)
|
copyTx.SigningPubKey = ``
|
||||||
const netFeeDrops = xrpToDrops(netFeeXRP)
|
copyTx.Fee = `0`
|
||||||
let baseFee = new BigNumber(netFeeDrops)
|
const tx_blob = encode(copyTx)
|
||||||
|
// eslint-disable-next-line require-atomic-updates, no-param-reassign -- ignore
|
||||||
// EscrowFinish Transaction with Fulfillment
|
tx.Fee = await getFeeEstimateXrp(client, tx_blob, signersCount)
|
||||||
if (tx.TransactionType === 'EscrowFinish' && tx.Fulfillment != null) {
|
|
||||||
const fulfillmentBytesSize: number = Math.ceil(tx.Fulfillment.length / 2)
|
|
||||||
// 10 drops × (33 + (Fulfillment size in bytes / 16))
|
|
||||||
const product = new BigNumber(
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-magic-numbers -- expected use of magic numbers
|
|
||||||
scaleValue(netFeeDrops, 33 + fulfillmentBytesSize / 16),
|
|
||||||
)
|
|
||||||
baseFee = product.dp(0, BigNumber.ROUND_CEIL)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AccountDelete Transaction
|
|
||||||
if (tx.TransactionType === 'AccountDelete') {
|
|
||||||
baseFee = await fetchAccountDeleteFee(client)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Multi-signed Transaction
|
|
||||||
* 10 drops × (1 + Number of Signatures Provided)
|
|
||||||
*/
|
|
||||||
if (signersCount > 0) {
|
|
||||||
baseFee = BigNumber.sum(baseFee, scaleValue(netFeeDrops, 1 + signersCount))
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxFeeDrops = xrpToDrops(client.maxFeeXRP)
|
|
||||||
const totalFee =
|
|
||||||
tx.TransactionType === 'AccountDelete'
|
|
||||||
? baseFee
|
|
||||||
: BigNumber.min(baseFee, maxFeeDrops)
|
|
||||||
|
|
||||||
// Round up baseFee and return it as a string
|
|
||||||
// eslint-disable-next-line no-param-reassign, @typescript-eslint/no-magic-numbers -- param reassign is safe, base 10 magic num
|
|
||||||
tx.Fee = totalFee.dp(0, BigNumber.ROUND_CEIL).toString(10)
|
|
||||||
}
|
|
||||||
|
|
||||||
function scaleValue(value, multiplier): string {
|
|
||||||
return new BigNumber(value).times(multiplier).toString()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setLatestValidatedLedgerSequence(
|
async function setLatestValidatedLedgerSequence(
|
||||||
|
|||||||
@@ -50,15 +50,20 @@ export async function getFeeXrp(
|
|||||||
*
|
*
|
||||||
* @param client - The Client used to connect to the ledger.
|
* @param client - The Client used to connect to the ledger.
|
||||||
* @param txBlob - The encoded transaction to estimate the fee for.
|
* @param txBlob - The encoded transaction to estimate the fee for.
|
||||||
|
* @param signersCount - The number of multisigners.
|
||||||
* @returns The transaction fee.
|
* @returns The transaction fee.
|
||||||
*/
|
*/
|
||||||
export async function getFeeEstimateXrp(
|
export async function getFeeEstimateXrp(
|
||||||
client: Client,
|
client: Client,
|
||||||
txBlob: string,
|
txBlob: string,
|
||||||
|
signersCount = 0,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const response = await client.request({
|
const response = await client.request({
|
||||||
command: 'fee',
|
command: 'fee',
|
||||||
tx_blob: txBlob,
|
tx_blob: txBlob,
|
||||||
})
|
})
|
||||||
return response.result.drops.open_ledger_fee
|
const openLedgerFee = response.result.drops.open_ledger_fee
|
||||||
|
const baseFee = new BigNumber(response.result.drops.base_fee)
|
||||||
|
const totalFee = BigNumber.sum(openLedgerFee, Number(baseFee) * signersCount)
|
||||||
|
return new BigNumber(totalFee.toFixed(NUM_DECIMAL_PLACES)).toString(BASE_10)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user