mirror of
https://github.com/Xahau/xahau.js.git
synced 2026-07-30 18:40:21 +00:00
feat: extra protection for AccountDelete transactions (#1626)
* add deletion blockers check to autofill * add tests * add fail_hard: true * pass in account_objects response to error * only fail_hard for AccountDelete * reject promise instead of throwing error * fix rebase issue
This commit is contained in:
@@ -2,8 +2,12 @@ import BigNumber from 'bignumber.js'
|
||||
import { xAddressToClassicAddress, isValidXAddress } from 'ripple-address-codec'
|
||||
|
||||
import type { Client } from '..'
|
||||
import { ValidationError } from '../errors'
|
||||
import { AccountInfoRequest, LedgerRequest } from '../models/methods'
|
||||
import { ValidationError, XrplError } from '../errors'
|
||||
import {
|
||||
AccountInfoRequest,
|
||||
AccountObjectsRequest,
|
||||
LedgerRequest,
|
||||
} from '../models/methods'
|
||||
import { Transaction } from '../models/transactions'
|
||||
import setTransactionFlagsToNumber from '../models/utils/flags'
|
||||
import { xrpToDrops } from '../utils'
|
||||
@@ -46,6 +50,9 @@ async function autofill<T extends Transaction>(
|
||||
if (tx.LastLedgerSequence == null) {
|
||||
promises.push(setLatestValidatedLedgerSequence(this, tx))
|
||||
}
|
||||
if (tx.TransactionType === 'AccountDelete') {
|
||||
promises.push(checkAccountDeleteBlockers(this, tx))
|
||||
}
|
||||
|
||||
return Promise.all(promises).then(() => tx)
|
||||
}
|
||||
@@ -193,4 +200,28 @@ async function setLatestValidatedLedgerSequence(
|
||||
tx.LastLedgerSequence = ledgerSequence + LEDGER_OFFSET
|
||||
}
|
||||
|
||||
async function checkAccountDeleteBlockers(
|
||||
client: Client,
|
||||
tx: Transaction,
|
||||
): Promise<void> {
|
||||
const request: AccountObjectsRequest = {
|
||||
command: 'account_objects',
|
||||
account: tx.Account,
|
||||
ledger_index: 'validated',
|
||||
deletion_blockers_only: true,
|
||||
}
|
||||
const response = await client.request(request)
|
||||
return new Promise((resolve, reject) => {
|
||||
if (response.result.account_objects.length > 0) {
|
||||
reject(
|
||||
new XrplError(
|
||||
`Account ${tx.Account} cannot be deleted; there are Escrows, PayChannels, RippleStates, or Checks associated with the account.`,
|
||||
response.result.account_objects,
|
||||
),
|
||||
)
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
|
||||
export default autofill
|
||||
|
||||
@@ -51,6 +51,7 @@ async function submitSignedTransaction(
|
||||
const request: SubmitRequest = {
|
||||
command: 'submit',
|
||||
tx_blob: signedTxEncoded,
|
||||
fail_hard: isAccountDelete(signedTransaction),
|
||||
}
|
||||
return this.request(request)
|
||||
}
|
||||
@@ -63,4 +64,9 @@ function isSigned(transaction: Transaction | string): boolean {
|
||||
)
|
||||
}
|
||||
|
||||
function isAccountDelete(transaction: Transaction | string): boolean {
|
||||
const tx = typeof transaction === 'string' ? decode(transaction) : transaction
|
||||
return tx.TransactionType === 'AccountDelete'
|
||||
}
|
||||
|
||||
export { submitTransaction, submitSignedTransaction }
|
||||
|
||||
Reference in New Issue
Block a user