mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-14 01:25:48 +00:00
Compare commits
17 Commits
@transia/x
...
@transia/r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
036312d361 | ||
|
|
3467680506 | ||
|
|
f209126364 | ||
|
|
33a8b3679a | ||
|
|
572aaa7a40 | ||
|
|
b6c11d1df8 | ||
|
|
526d1e7686 | ||
|
|
3c668f41b8 | ||
|
|
aeb29a20a1 | ||
|
|
8c814482e5 | ||
|
|
5b57ea8b77 | ||
|
|
7663e6049f | ||
|
|
420d6b2c35 | ||
|
|
02c41d2eb1 | ||
|
|
3f1a54f018 | ||
|
|
ac865e472e | ||
|
|
60c97901d2 |
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -29,7 +29,7 @@
|
|||||||
"enable": true
|
"enable": true
|
||||||
},
|
},
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll.eslint": true
|
"source.fixAll.eslint": "explicit"
|
||||||
},
|
},
|
||||||
"files.insertFinalNewline": true,
|
"files.insertFinalNewline": true,
|
||||||
"files.trimFinalNewlines": true,
|
"files.trimFinalNewlines": true,
|
||||||
|
|||||||
@@ -32,19 +32,19 @@ All of which works in Node.js (tested for v14+) & web browsers (tested for Chrom
|
|||||||
In an existing project (with package.json), install xrpl.js with:
|
In an existing project (with package.json), install xrpl.js with:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ npm install --save xrpl
|
$ npm install --save @transia/xrpl
|
||||||
```
|
```
|
||||||
|
|
||||||
Or with `yarn`:
|
Or with `yarn`:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ yarn add xrpl
|
$ yarn add @transia/xrpl
|
||||||
```
|
```
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const xrpl = require("xrpl");
|
const xrpl = require("@transia/xrpl");
|
||||||
async function main() {
|
async function main() {
|
||||||
const client = new xrpl.Client("wss://s.altnet.rippletest.net:51233");
|
const client = new xrpl.Client("wss://s.altnet.rippletest.net:51233");
|
||||||
await client.connect();
|
await client.connect();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@transia/ripple-binary-codec",
|
"name": "@transia/ripple-binary-codec",
|
||||||
"version": "1.4.6-alpha.4",
|
"version": "1.4.6-alpha.8",
|
||||||
"description": "XRP Ledger binary codec",
|
"description": "XRP Ledger binary codec",
|
||||||
"files": [
|
"files": [
|
||||||
"dist/*",
|
"dist/*",
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
"LedgerHashes": 104,
|
"LedgerHashes": 104,
|
||||||
"Amendments": 102,
|
"Amendments": 102,
|
||||||
"FeeSettings": 115,
|
"FeeSettings": 115,
|
||||||
"ImportVlseq": 73,
|
"ImportVLSequence": 73,
|
||||||
"Escrow": 117,
|
"Escrow": 117,
|
||||||
"PayChannel": 120,
|
"PayChannel": 120,
|
||||||
"Check": 67,
|
"Check": 67,
|
||||||
@@ -2521,11 +2521,11 @@
|
|||||||
"temBAD_PATH": -291,
|
"temBAD_PATH": -291,
|
||||||
"temBAD_PATH_LOOP": -290,
|
"temBAD_PATH_LOOP": -290,
|
||||||
"temBAD_REGKEY": -289,
|
"temBAD_REGKEY": -289,
|
||||||
"temBAD_SEND_XRP_LIMIT": -288,
|
"temBAD_SEND_NATIVE_LIMIT": -288,
|
||||||
"temBAD_SEND_XRP_MAX": -287,
|
"temBAD_SEND_NATIVE_MAX": -287,
|
||||||
"temBAD_SEND_XRP_NO_DIRECT": -286,
|
"temBAD_SEND_NATIVE_NO_DIRECT": -286,
|
||||||
"temBAD_SEND_XRP_PARTIAL": -285,
|
"temBAD_SEND_NATIVE_PARTIAL": -285,
|
||||||
"temBAD_SEND_XRP_PATHS": -284,
|
"temBAD_SEND_NATIVE_PATHS": -284,
|
||||||
"temBAD_SEQUENCE": -283,
|
"temBAD_SEQUENCE": -283,
|
||||||
"temBAD_SIGNATURE": -282,
|
"temBAD_SIGNATURE": -282,
|
||||||
"temBAD_SRC_ACCOUNT": -281,
|
"temBAD_SRC_ACCOUNT": -281,
|
||||||
@@ -2557,7 +2557,6 @@
|
|||||||
"temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT": -255,
|
"temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT": -255,
|
||||||
"temXCHAIN_TOO_MANY_ATTESTATIONS": -254,
|
"temXCHAIN_TOO_MANY_ATTESTATIONS": -254,
|
||||||
"temHOOK_DATA_TOO_LARGE": -253,
|
"temHOOK_DATA_TOO_LARGE": -253,
|
||||||
"temHOOK_REJECTED": -252,
|
|
||||||
|
|
||||||
"tefFAILURE": -199,
|
"tefFAILURE": -199,
|
||||||
"tefALREADY": -198,
|
"tefALREADY": -198,
|
||||||
@@ -2582,6 +2581,7 @@
|
|||||||
"tefNFTOKEN_IS_NOT_TRANSFERABLE": -179,
|
"tefNFTOKEN_IS_NOT_TRANSFERABLE": -179,
|
||||||
"tefPAST_IMPORT_SEQ": -178,
|
"tefPAST_IMPORT_SEQ": -178,
|
||||||
"tefPAST_IMPORT_VL_SEQ": -177,
|
"tefPAST_IMPORT_VL_SEQ": -177,
|
||||||
|
"tefNONDIR_EMIT": -176,
|
||||||
|
|
||||||
"terRETRY": -99,
|
"terRETRY": -99,
|
||||||
"terFUNDS_SPENT": -98,
|
"terFUNDS_SPENT": -98,
|
||||||
@@ -2610,7 +2610,7 @@
|
|||||||
"tecINSUF_RESERVE_LINE": 122,
|
"tecINSUF_RESERVE_LINE": 122,
|
||||||
"tecINSUF_RESERVE_OFFER": 123,
|
"tecINSUF_RESERVE_OFFER": 123,
|
||||||
"tecNO_DST": 124,
|
"tecNO_DST": 124,
|
||||||
"tecNO_DST_INSUF_XRP": 125,
|
"tecNO_DST_INSUF_NATIVE": 125,
|
||||||
"tecNO_LINE_INSUF_RESERVE": 126,
|
"tecNO_LINE_INSUF_RESERVE": 126,
|
||||||
"tecNO_LINE_REDUNDANT": 127,
|
"tecNO_LINE_REDUNDANT": 127,
|
||||||
"tecPATH_DRY": 128,
|
"tecPATH_DRY": 128,
|
||||||
@@ -2672,6 +2672,7 @@
|
|||||||
"tecXCHAIN_PAYMENT_FAILED": 184,
|
"tecXCHAIN_PAYMENT_FAILED": 184,
|
||||||
"tecXCHAIN_SELF_COMMIT": 185,
|
"tecXCHAIN_SELF_COMMIT": 185,
|
||||||
"tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR": 186,
|
"tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR": 186,
|
||||||
|
"tecINSUF_RESERVE_SELLER": 187,
|
||||||
"tecLAST_POSSIBLE_ENTRY": 255
|
"tecLAST_POSSIBLE_ENTRY": 255
|
||||||
},
|
},
|
||||||
"TRANSACTION_TYPES": {
|
"TRANSACTION_TYPES": {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const STANDARD_FORMAT_HEX_REGEX = /^0{24}[\x00-\x7F]{6}0{10}$/
|
|||||||
*/
|
*/
|
||||||
function isoToBytes(iso: string): Buffer {
|
function isoToBytes(iso: string): Buffer {
|
||||||
const bytes = Buffer.alloc(20)
|
const bytes = Buffer.alloc(20)
|
||||||
if (iso !== 'XRP') {
|
if (iso !== 'XAH') {
|
||||||
const isoBytes = iso.split('').map((c) => c.charCodeAt(0))
|
const isoBytes = iso.split('').map((c) => c.charCodeAt(0))
|
||||||
bytes.set(isoBytes, 12)
|
bytes.set(isoBytes, 12)
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,7 @@ function isIsoCode(iso: string): boolean {
|
|||||||
|
|
||||||
function isoCodeFromHex(code: Buffer): string | null {
|
function isoCodeFromHex(code: Buffer): string | null {
|
||||||
const iso = code.toString()
|
const iso = code.toString()
|
||||||
if (iso === 'XRP') {
|
if (iso === 'XAH') {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
if (isIsoCode(iso)) {
|
if (isIsoCode(iso)) {
|
||||||
@@ -89,7 +89,7 @@ class Currency extends Hash160 {
|
|||||||
const hex = this.bytes.toString('hex')
|
const hex = this.bytes.toString('hex')
|
||||||
|
|
||||||
if (XRP_HEX_REGEX.test(hex)) {
|
if (XRP_HEX_REGEX.test(hex)) {
|
||||||
this._iso = 'XRP'
|
this._iso = 'XAH'
|
||||||
} else if (STANDARD_FORMAT_HEX_REGEX.test(hex)) {
|
} else if (STANDARD_FORMAT_HEX_REGEX.test(hex)) {
|
||||||
this._iso = isoCodeFromHex(this.bytes.slice(12, 15))
|
this._iso = isoCodeFromHex(this.bytes.slice(12, 15))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ function pathSetBinaryTests() {
|
|||||||
currency: 'BTC',
|
currency: 'BTC',
|
||||||
issuer: 'r3AWbdp2jQLXLywJypdoNwVSvr81xs3uhn',
|
issuer: 'r3AWbdp2jQLXLywJypdoNwVSvr81xs3uhn',
|
||||||
},
|
},
|
||||||
{ currency: 'XRP' },
|
{ currency: 'XAH' },
|
||||||
{
|
{
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B',
|
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B',
|
||||||
|
|||||||
@@ -2904,7 +2904,7 @@
|
|||||||
"type_id": 6,
|
"type_id": 6,
|
||||||
"is_native": true,
|
"is_native": true,
|
||||||
"type": "Amount",
|
"type": "Amount",
|
||||||
"error": "1000000000000 absolute XRP is bigger than max native value 100000000000.0",
|
"error": "1000000000000 absolute XAH is bigger than max native value 100000000000.0",
|
||||||
"is_negative": false
|
"is_negative": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2912,7 +2912,7 @@
|
|||||||
"type_id": 6,
|
"type_id": 6,
|
||||||
"is_native": true,
|
"is_native": true,
|
||||||
"type": "Amount",
|
"type": "Amount",
|
||||||
"error": "10000000000000000000 absolute XRP is bigger than max native value 100000000000.0",
|
"error": "10000000000000000000 absolute XAH is bigger than max native value 100000000000.0",
|
||||||
"is_negative": true
|
"is_negative": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ describe('Hash256', function () {
|
|||||||
|
|
||||||
describe('Currency', function () {
|
describe('Currency', function () {
|
||||||
test('Decoding allows dodgy XRP without throwing', function () {
|
test('Decoding allows dodgy XRP without throwing', function () {
|
||||||
const currencyCode = '0000000000000000000000005852500000000000'
|
const currencyCode = '0000000000000000000000005841480000000000'
|
||||||
expect(Currency.from(currencyCode).toJSON()).toBe(currencyCode)
|
expect(Currency.from(currencyCode).toJSON()).toBe(currencyCode)
|
||||||
})
|
})
|
||||||
test('Currency code with lowercase letters decodes to ISO code', () => {
|
test('Currency code with lowercase letters decodes to ISO code', () => {
|
||||||
@@ -113,7 +113,7 @@ describe('Currency', function () {
|
|||||||
|
|
||||||
test('can be constructed from a Buffer', function () {
|
test('can be constructed from a Buffer', function () {
|
||||||
const xrp = new Currency(Buffer.alloc(20))
|
const xrp = new Currency(Buffer.alloc(20))
|
||||||
expect(xrp.iso()).toBe('XRP')
|
expect(xrp.iso()).toBe('XAH')
|
||||||
})
|
})
|
||||||
test('Can handle non-standard currency codes', () => {
|
test('Can handle non-standard currency codes', () => {
|
||||||
const currency = '015841551A748AD2C1F76FF6ECB0CCCD00000000'
|
const currency = '015841551A748AD2C1F76FF6ECB0CCCD00000000'
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ describe('encoding and decoding tx_json', function () {
|
|||||||
Sequence: 19,
|
Sequence: 19,
|
||||||
LimitAmount: {
|
LimitAmount: {
|
||||||
value: '200',
|
value: '200',
|
||||||
currency: '0000000000000000000000005852500000000000',
|
currency: '0000000000000000000000005841480000000000',
|
||||||
issuer: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K',
|
issuer: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K',
|
||||||
},
|
},
|
||||||
Fee: '10',
|
Fee: '10',
|
||||||
|
|||||||
@@ -1698,7 +1698,7 @@ __OTHER CHANGES__
|
|||||||
parseBinary: false
|
parseBinary: false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
+ Added full currency name support, e.g. `Currency.from_json('XRP').to_human({full_name:'Ripples'})` will return `XRP - Ripples`
|
+ Added full currency name support, e.g. `Currency.from_json('XAH').to_human({full_name:'Ripples'})` will return `XAH - Ripples`
|
||||||
+ Improved interest bearing currency support, e.g. `Currency.from_human('USD - US Dollar (2.5%pa)')`
|
+ Improved interest bearing currency support, e.g. `Currency.from_human('USD - US Dollar (2.5%pa)')`
|
||||||
+ Improve test coverage
|
+ Improve test coverage
|
||||||
+ Added blob vault client. The vault client facilitates interaction with ripple's namespace and blob vault or 3rd party blob vaults using ripple's blob vault software (https://github.com/ripple/ripple-blobvault). A list of the available functions can be found at [docs/VAULTCLIENT.md](docs/VAULTCLIENT.md)
|
+ Added blob vault client. The vault client facilitates interaction with ripple's namespace and blob vault or 3rd party blob vaults using ripple's blob vault software (https://github.com/ripple/ripple-blobvault). A list of the available functions can be found at [docs/VAULTCLIENT.md](docs/VAULTCLIENT.md)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@transia/xrpl",
|
"name": "@transia/xrpl",
|
||||||
"version": "2.7.3-alpha.17",
|
"version": "2.7.3-alpha.24",
|
||||||
"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": [
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@transia/ripple-address-codec": "^4.2.8-alpha.0",
|
"@transia/ripple-address-codec": "^4.2.8-alpha.0",
|
||||||
"@transia/ripple-binary-codec": "^1.4.6-alpha.4",
|
"@transia/ripple-binary-codec": "^1.4.6-alpha.8",
|
||||||
"@transia/ripple-keypairs": "^1.1.8-alpha.0",
|
"@transia/ripple-keypairs": "^1.1.8-alpha.0",
|
||||||
"bignumber.js": "^9.0.0",
|
"bignumber.js": "^9.0.0",
|
||||||
"bip32": "^2.0.6",
|
"bip32": "^2.0.6",
|
||||||
@@ -80,5 +80,6 @@
|
|||||||
"readmeFilename": "README.md",
|
"readmeFilename": "README.md",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.13.0"
|
"node": ">=10.13.0"
|
||||||
}
|
},
|
||||||
|
"gitHead": "3b234ec8ec1c677e0f3f534fd2985c985871c87e"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ async function createTxWithPaths(): Promise<void> {
|
|||||||
source_account: wallet.classicAddress,
|
source_account: wallet.classicAddress,
|
||||||
source_currencies: [
|
source_currencies: [
|
||||||
{
|
{
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
destination_account,
|
destination_account,
|
||||||
|
|||||||
@@ -485,10 +485,10 @@ class Wallet {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
txCurrency.length === standard_currency_code_len &&
|
txCurrency.length === standard_currency_code_len &&
|
||||||
txCurrency.toUpperCase() === 'XRP'
|
txCurrency.toUpperCase() === 'XAH'
|
||||||
) {
|
) {
|
||||||
throw new XrplError(
|
throw new XrplError(
|
||||||
`Trying to sign an issued currency with a similar standard code to XRP (received '${txCurrency}'). XRP is not an issued currency.`,
|
`Trying to sign an issued currency with a similar standard code to XAH (received '${txCurrency}'). XAH is not an issued currency.`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,7 +575,7 @@ function removeTrailingZeros(tx: Transaction): void {
|
|||||||
/* eslint-disable @typescript-eslint/no-magic-numbers -- Magic numbers are from rippleds of currency code encoding */
|
/* eslint-disable @typescript-eslint/no-magic-numbers -- Magic numbers are from rippleds of currency code encoding */
|
||||||
function isoToHex(iso: string): string {
|
function isoToHex(iso: string): string {
|
||||||
const bytes = Buffer.alloc(20)
|
const bytes = Buffer.alloc(20)
|
||||||
if (iso !== 'XRP') {
|
if (iso !== 'XAH') {
|
||||||
const isoBytes = iso.split('').map((chr) => chr.charCodeAt(0))
|
const isoBytes = iso.split('').map((chr) => chr.charCodeAt(0))
|
||||||
bytes.set(isoBytes, 12)
|
bytes.set(isoBytes, 12)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export type LedgerIndex = number | ('validated' | 'closed' | 'current')
|
export type LedgerIndex = number | ('validated' | 'closed' | 'current')
|
||||||
|
|
||||||
interface XRP {
|
interface XRP {
|
||||||
currency: 'XRP'
|
currency: 'XAH'
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IssuedCurrency {
|
interface IssuedCurrency {
|
||||||
|
|||||||
@@ -14,6 +14,17 @@ export interface HookExecution {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface HookEmission {
|
||||||
|
HookEmission: {
|
||||||
|
EmitGeneration: number
|
||||||
|
EmitBurden: string
|
||||||
|
EmitParentTxnID: string
|
||||||
|
EmitNonce: string
|
||||||
|
EmitCallback: string
|
||||||
|
EmitHookHash: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface CreatedNode {
|
export interface CreatedNode {
|
||||||
CreatedNode: {
|
CreatedNode: {
|
||||||
LedgerEntryType: string
|
LedgerEntryType: string
|
||||||
@@ -75,6 +86,7 @@ export function isDeletedNode(node: Node): node is DeletedNode {
|
|||||||
|
|
||||||
export interface TransactionMetadata {
|
export interface TransactionMetadata {
|
||||||
HookExecutions?: HookExecution[]
|
HookExecutions?: HookExecution[]
|
||||||
|
HookEmissions?: HookEmission[]
|
||||||
AffectedNodes: Node[]
|
AffectedNodes: Node[]
|
||||||
DeliveredAmount?: Amount
|
DeliveredAmount?: Amount
|
||||||
// "unavailable" possible for transactions before 2014-01-20
|
// "unavailable" possible for transactions before 2014-01-20
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ async function getBalances(
|
|||||||
formatBalances(response.result.lines),
|
formatBalances(response.result.lines),
|
||||||
)
|
)
|
||||||
if (xrpBalance !== '') {
|
if (xrpBalance !== '') {
|
||||||
balances.push({ currency: 'XRP', value: xrpBalance })
|
balances.push({ currency: 'XAH', value: xrpBalance })
|
||||||
}
|
}
|
||||||
balances.push(...accountLinesBalance)
|
balances.push(...accountLinesBalance)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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.base_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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ function getXRPQuantity(
|
|||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- okay here
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- okay here
|
||||||
account: (node.FinalFields?.Account ?? node.NewFields?.Account) as string,
|
account: (node.FinalFields?.Account ?? node.NewFields?.Account) as string,
|
||||||
balance: {
|
balance: {
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
value: dropsToXrp(value).toString(),
|
value: dropsToXrp(value).toString(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
"issuer": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw"
|
"issuer": "rp8rJYTpodf8qbSCHVTNacf8nSW8mRakFw"
|
||||||
},
|
},
|
||||||
"takerGets": {
|
"takerGets": {
|
||||||
"currency": "XRP"
|
"currency": "XAH"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"value": "922.913243",
|
"value": "922.913243",
|
||||||
"currency": "XRP"
|
"currency": "XAH"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"value": "0",
|
"value": "0",
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -25,7 +25,7 @@ describe('book_offers', function () {
|
|||||||
const bookOffer: BookOffersRequest = {
|
const bookOffer: BookOffersRequest = {
|
||||||
command: 'book_offers',
|
command: 'book_offers',
|
||||||
taker_gets: {
|
taker_gets: {
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
},
|
},
|
||||||
taker_pays: {
|
taker_pays: {
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ describe('TrustSet', function () {
|
|||||||
TransactionType: 'TrustSet',
|
TransactionType: 'TrustSet',
|
||||||
Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo',
|
Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo',
|
||||||
LimitAmount: {
|
LimitAmount: {
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
issuer: 'rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX',
|
issuer: 'rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX',
|
||||||
value: '4329.23',
|
value: '4329.23',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ describe('Models Utils', function () {
|
|||||||
TransactionType: 'TrustSet',
|
TransactionType: 'TrustSet',
|
||||||
Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo',
|
Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo',
|
||||||
LimitAmount: {
|
LimitAmount: {
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
issuer: 'rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX',
|
issuer: 'rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX',
|
||||||
value: '4329.23',
|
value: '4329.23',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -15,16 +15,16 @@ import trustlineSetLimit2 from '../fixtures/utils/trustlineSetLimit2.json'
|
|||||||
import trustlineSetLimitZero from '../fixtures/utils/trustlineSetLimitZero.json'
|
import trustlineSetLimitZero from '../fixtures/utils/trustlineSetLimitZero.json'
|
||||||
|
|
||||||
describe('getBalanceChanges', function () {
|
describe('getBalanceChanges', function () {
|
||||||
it('XRP create account', function () {
|
it('XAH create account', function () {
|
||||||
const result = getBalanceChanges(paymentXrpCreateAccount.metadata)
|
const result = getBalanceChanges(paymentXrpCreateAccount.metadata)
|
||||||
const expected = [
|
const expected = [
|
||||||
{
|
{
|
||||||
account: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K',
|
account: 'rLDYrujdKUfVx28T9vRDAbyJ7G2WVXKo4K',
|
||||||
balances: [{ currency: 'XRP', value: '100' }],
|
balances: [{ currency: 'XAH', value: '100' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
account: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc',
|
account: 'rKmBGxocj9Abgy25J51Mk1iqFzW9aVF9Tc',
|
||||||
balances: [{ currency: 'XRP', value: '-100.012' }],
|
balances: [{ currency: 'XAH', value: '-100.012' }],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
assert.deepStrictEqual(result, expected)
|
assert.deepStrictEqual(result, expected)
|
||||||
@@ -43,7 +43,7 @@ describe('getBalanceChanges', function () {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: '-0.012',
|
value: '-0.012',
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -114,7 +114,7 @@ describe('getBalanceChanges', function () {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: '-0.012',
|
value: '-0.012',
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -136,7 +136,7 @@ describe('getBalanceChanges', function () {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: '-0.012',
|
value: '-0.012',
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -177,7 +177,7 @@ describe('getBalanceChanges', function () {
|
|||||||
balances: [
|
balances: [
|
||||||
{
|
{
|
||||||
value: '-0.012',
|
value: '-0.012',
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -197,7 +197,7 @@ describe('getBalanceChanges', function () {
|
|||||||
value: '10',
|
value: '10',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
value: '-0.012',
|
value: '-0.012',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -224,7 +224,7 @@ describe('getBalanceChanges', function () {
|
|||||||
balances: [
|
balances: [
|
||||||
{
|
{
|
||||||
value: '-0.012',
|
value: '-0.012',
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -239,7 +239,7 @@ describe('getBalanceChanges', function () {
|
|||||||
account: 'rsApBGKJmMfExxZBrGnzxEXyq7TMhMRg4e',
|
account: 'rsApBGKJmMfExxZBrGnzxEXyq7TMhMRg4e',
|
||||||
balances: [
|
balances: [
|
||||||
{
|
{
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
value: '-0.00001',
|
value: '-0.00001',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -286,7 +286,7 @@ describe('getBalanceChanges', function () {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: '-0.012',
|
value: '-0.012',
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -316,7 +316,7 @@ describe('getBalanceChanges', function () {
|
|||||||
value: '-100',
|
value: '-100',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
value: '-0.00001',
|
value: '-0.00001',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -347,7 +347,7 @@ describe('getBalanceChanges', function () {
|
|||||||
value: '-200',
|
value: '-200',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
value: '-0.00001',
|
value: '-0.00001',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -383,7 +383,7 @@ describe('getBalanceChanges', function () {
|
|||||||
value: '-100',
|
value: '-100',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
currency: 'XRP',
|
currency: 'XAH',
|
||||||
value: '-0.00001',
|
value: '-0.00001',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -757,13 +757,13 @@ describe('Wallet', function () {
|
|||||||
it('sign throws when a payment contains an issued currency like XRP', async function () {
|
it('sign throws when a payment contains an issued currency like XRP', async function () {
|
||||||
const payment: Payment = { ...issuedCurrencyPayment }
|
const payment: Payment = { ...issuedCurrencyPayment }
|
||||||
payment.Amount = {
|
payment.Amount = {
|
||||||
currency: 'xrp',
|
currency: 'xah',
|
||||||
issuer: 'rnURbz5HLbvqEq69b1B4TX6cUTNMmcrBqi',
|
issuer: 'rnURbz5HLbvqEq69b1B4TX6cUTNMmcrBqi',
|
||||||
value: '123.40',
|
value: '123.40',
|
||||||
}
|
}
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
wallet.sign(payment)
|
wallet.sign(payment)
|
||||||
}, /^Trying to sign an issued currency with a similar standard code to XRP \(received 'xrp'\)\. XRP is not an issued currency\./u)
|
}, /^Trying to sign an issued currency with a similar standard code to XAH \(received 'xah'\)\. XAH is not an issued currency\./u)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('sign does NOT throw when a payment contains an issued currency like xrp in hex string format', async function () {
|
it('sign does NOT throw when a payment contains an issued currency like xrp in hex string format', async function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user