mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-12-06 17:27:59 +00:00
Compare commits
1 Commits
@transia/r
...
hooks-test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a770e93320 |
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": "explicit"
|
"source.fixAll.eslint": true
|
||||||
},
|
},
|
||||||
"files.insertFinalNewline": true,
|
"files.insertFinalNewline": true,
|
||||||
"files.trimFinalNewlines": true,
|
"files.trimFinalNewlines": true,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@transia/ripple-binary-codec",
|
"name": "@transia/ripple-binary-codec",
|
||||||
"version": "1.4.6-alpha.9",
|
"version": "1.4.6-alpha.5",
|
||||||
"description": "XRP Ledger binary codec",
|
"description": "XRP Ledger binary codec",
|
||||||
"files": [
|
"files": [
|
||||||
"dist/*",
|
"dist/*",
|
||||||
|
|||||||
@@ -141,40 +141,40 @@
|
|||||||
[
|
[
|
||||||
"LedgerEntry",
|
"LedgerEntry",
|
||||||
{
|
{
|
||||||
"nth": 257,
|
"nth": 1,
|
||||||
"isVLEncoded": false,
|
"isVLEncoded": false,
|
||||||
"isSerialized": false,
|
"isSerialized": false,
|
||||||
"isSigningField": false,
|
"isSigningField": true,
|
||||||
"type": "LedgerEntry"
|
"type": "LedgerEntry"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"Transaction",
|
"Transaction",
|
||||||
{
|
{
|
||||||
"nth": 257,
|
"nth": 1,
|
||||||
"isVLEncoded": false,
|
"isVLEncoded": false,
|
||||||
"isSerialized": false,
|
"isSerialized": false,
|
||||||
"isSigningField": false,
|
"isSigningField": true,
|
||||||
"type": "Transaction"
|
"type": "Transaction"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"Validation",
|
"Validation",
|
||||||
{
|
{
|
||||||
"nth": 257,
|
"nth": 1,
|
||||||
"isVLEncoded": false,
|
"isVLEncoded": false,
|
||||||
"isSerialized": false,
|
"isSerialized": false,
|
||||||
"isSigningField": false,
|
"isSigningField": true,
|
||||||
"type": "Validation"
|
"type": "Validation"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
"Metadata",
|
"Metadata",
|
||||||
{
|
{
|
||||||
"nth": 257,
|
"nth": 1,
|
||||||
"isVLEncoded": false,
|
"isVLEncoded": false,
|
||||||
"isSerialized": false,
|
"isSerialized": true,
|
||||||
"isSigningField": false,
|
"isSigningField": true,
|
||||||
"type": "Metadata"
|
"type": "Metadata"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -1998,16 +1998,6 @@
|
|||||||
"type": "AccountID"
|
"type": "AccountID"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
|
||||||
"Inform",
|
|
||||||
{
|
|
||||||
"nth": 99,
|
|
||||||
"isVLEncoded": true,
|
|
||||||
"isSerialized": true,
|
|
||||||
"isSigningField": true,
|
|
||||||
"type": "AccountID"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
[
|
||||||
"Indexes",
|
"Indexes",
|
||||||
{
|
{
|
||||||
@@ -2058,16 +2048,6 @@
|
|||||||
"type": "Vector256"
|
"type": "Vector256"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
|
||||||
"URITokenIDs",
|
|
||||||
{
|
|
||||||
"nth": 99,
|
|
||||||
"isVLEncoded": true,
|
|
||||||
"isSerialized": true,
|
|
||||||
"isSigningField": true,
|
|
||||||
"type": "Vector256"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
[
|
||||||
"Paths",
|
"Paths",
|
||||||
{
|
{
|
||||||
@@ -2328,26 +2308,6 @@
|
|||||||
"type": "STObject"
|
"type": "STObject"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[
|
|
||||||
"MintURIToken",
|
|
||||||
{
|
|
||||||
"nth": 92,
|
|
||||||
"isVLEncoded": false,
|
|
||||||
"isSerialized": true,
|
|
||||||
"isSigningField": true,
|
|
||||||
"type": "STObject"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"AmountEntry",
|
|
||||||
{
|
|
||||||
"nth": 91,
|
|
||||||
"isVLEncoded": false,
|
|
||||||
"isSerialized": true,
|
|
||||||
"isSigningField": true,
|
|
||||||
"type": "STObject"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
[
|
||||||
"Signers",
|
"Signers",
|
||||||
{
|
{
|
||||||
@@ -2527,16 +2487,6 @@
|
|||||||
"isSigningField": true,
|
"isSigningField": true,
|
||||||
"type": "STArray"
|
"type": "STArray"
|
||||||
}
|
}
|
||||||
],
|
|
||||||
[
|
|
||||||
"Amounts",
|
|
||||||
{
|
|
||||||
"nth": 92,
|
|
||||||
"isVLEncoded": false,
|
|
||||||
"isSerialized": true,
|
|
||||||
"isSigningField": true,
|
|
||||||
"type": "STArray"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"TRANSACTION_RESULTS": {
|
"TRANSACTION_RESULTS": {
|
||||||
@@ -2571,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_NATIVE_LIMIT": -288,
|
"temBAD_SEND_XRP_LIMIT": -288,
|
||||||
"temBAD_SEND_NATIVE_MAX": -287,
|
"temBAD_SEND_XRP_MAX": -287,
|
||||||
"temBAD_SEND_NATIVE_NO_DIRECT": -286,
|
"temBAD_SEND_XRP_NO_DIRECT": -286,
|
||||||
"temBAD_SEND_NATIVE_PARTIAL": -285,
|
"temBAD_SEND_XRP_PARTIAL": -285,
|
||||||
"temBAD_SEND_NATIVE_PATHS": -284,
|
"temBAD_SEND_XRP_PATHS": -284,
|
||||||
"temBAD_SEQUENCE": -283,
|
"temBAD_SEQUENCE": -283,
|
||||||
"temBAD_SIGNATURE": -282,
|
"temBAD_SIGNATURE": -282,
|
||||||
"temBAD_SRC_ACCOUNT": -281,
|
"temBAD_SRC_ACCOUNT": -281,
|
||||||
@@ -2607,6 +2557,7 @@
|
|||||||
"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,
|
||||||
@@ -2631,7 +2582,6 @@
|
|||||||
"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,
|
||||||
@@ -2660,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_NATIVE": 125,
|
"tecNO_DST_INSUF_XRP": 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,
|
||||||
@@ -2722,7 +2672,6 @@
|
|||||||
"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": {
|
||||||
@@ -2760,7 +2709,6 @@
|
|||||||
"URITokenBuy": 47,
|
"URITokenBuy": 47,
|
||||||
"URITokenCreateSellOffer": 48,
|
"URITokenCreateSellOffer": 48,
|
||||||
"URITokenCancelSellOffer": 49,
|
"URITokenCancelSellOffer": 49,
|
||||||
"Remit": 95,
|
|
||||||
"GenesisMint": 96,
|
"GenesisMint": 96,
|
||||||
"Import": 97,
|
"Import": 97,
|
||||||
"ClaimReward": 98,
|
"ClaimReward": 98,
|
||||||
|
|||||||
@@ -111,11 +111,6 @@ const UNLReport = {
|
|||||||
meta: require('./fixtures/unl-report-meta-binary.json'),
|
meta: require('./fixtures/unl-report-meta-binary.json'),
|
||||||
}
|
}
|
||||||
|
|
||||||
const Remit = {
|
|
||||||
tx: require('./fixtures/remit-tx.json'),
|
|
||||||
binary: require('./fixtures/remit-binary.json'),
|
|
||||||
}
|
|
||||||
|
|
||||||
function bytesListTest() {
|
function bytesListTest() {
|
||||||
const list = new BytesList()
|
const list = new BytesList()
|
||||||
.put(Buffer.from([0]))
|
.put(Buffer.from([0]))
|
||||||
@@ -296,12 +291,6 @@ function nfTokenTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function RemitTest() {
|
|
||||||
test('can serialize Remit', () => {
|
|
||||||
expect(encode(Remit.tx)).toEqual(Remit.binary)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('Binary Serialization', function () {
|
describe('Binary Serialization', function () {
|
||||||
describe('nestedObjectTests', nestedObjectTests)
|
describe('nestedObjectTests', nestedObjectTests)
|
||||||
describe('BytesList', bytesListTest)
|
describe('BytesList', bytesListTest)
|
||||||
@@ -315,5 +304,4 @@ describe('Binary Serialization', function () {
|
|||||||
describe('TicketTest', ticketTest)
|
describe('TicketTest', ticketTest)
|
||||||
describe('NFToken', nfTokenTest)
|
describe('NFToken', nfTokenTest)
|
||||||
describe('UNLReport', UNLReportTest)
|
describe('UNLReport', UNLReportTest)
|
||||||
describe('Remit', RemitTest)
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
"12005F22000000002403EDEB4A2E00000001201B03EE5D3150116F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B68400000000000000C732102F9E33F16DF9507705EC954E3F94EB5F10D1FC4A354606DBE6297DBB1096FE65474473045022100E3FAE0EDEC3D6A8FF6D81BC9CF8288A61B7EEDE8071E90FF9314CB4621058D10022043545CF631706D700CEE65A1DB83EFDD185413808292D9D90F14D87D3DC2D8CB701A04DEADBEEF81147990EC5D1D8DF69E070A968D4B186986FDF06ED0831449FF0C73CA6AF9733DA805F76CA2C37776B7C46B806314757C4A9ED08284D61F3D8807280795F858BAB61DE05C220000000150156F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B7504DEADBEEFE1F05CE05B6140000000000003E8E1E05B61D4838D7EA4C68000000000000000000000000000555344000000000006B80F0F1D98AEDA846ED981F741C398FB2C4FD1E1F100136320AED08CC1F50DD5F23A1948AF86153A3F3B7593E5EC77D65A02BB1B29E05AB6AE"
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
{
|
|
||||||
"TransactionType": "Remit",
|
|
||||||
"Account": "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
|
|
||||||
"Destination": "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
|
|
||||||
"DestinationTag": 1,
|
|
||||||
"Fee": "12",
|
|
||||||
"Flags": 0,
|
|
||||||
"LastLedgerSequence": 65953073,
|
|
||||||
"Sequence": 65923914,
|
|
||||||
"SigningPubKey": "02F9E33F16DF9507705EC954E3F94EB5F10D1FC4A354606DBE6297DBB1096FE654",
|
|
||||||
"TxnSignature": "3045022100E3FAE0EDEC3D6A8FF6D81BC9CF8288A61B7EEDE8071E90FF9314CB4621058D10022043545CF631706D700CEE65A1DB83EFDD185413808292D9D90F14D87D3DC2D8CB",
|
|
||||||
"Amounts": [
|
|
||||||
{
|
|
||||||
"AmountEntry": {
|
|
||||||
"Amount": "1000"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"AmountEntry": {
|
|
||||||
"Amount": {
|
|
||||||
"currency": "USD",
|
|
||||||
"issuer": "rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX",
|
|
||||||
"value": "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"MintURIToken": {
|
|
||||||
"URI": "DEADBEEF",
|
|
||||||
"Digest": "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
|
|
||||||
"Flags": 1
|
|
||||||
},
|
|
||||||
"URITokenIDs": [
|
|
||||||
"AED08CC1F50DD5F23A1948AF86153A3F3B7593E5EC77D65A02BB1B29E05AB6AE"
|
|
||||||
],
|
|
||||||
"InvoiceID": "6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B",
|
|
||||||
"Blob": "DEADBEEF",
|
|
||||||
"Inform": "rB5Ux4Lv2nRx6eeoAAsZmtctnBQ2LiACnk"
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@transia/xrpl",
|
"name": "@transia/xrpl",
|
||||||
"version": "2.7.3-alpha.26",
|
"version": "2.7.3-alpha.18",
|
||||||
"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.9",
|
"@transia/ripple-binary-codec": "^1.4.6-alpha.5",
|
||||||
"@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",
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ export interface IssuedCurrencyAmount extends IssuedCurrency {
|
|||||||
|
|
||||||
export type Amount = IssuedCurrencyAmount | string
|
export type Amount = IssuedCurrencyAmount | string
|
||||||
|
|
||||||
export type AmountEntry = Amount
|
|
||||||
|
|
||||||
export interface Signer {
|
export interface Signer {
|
||||||
Signer: {
|
Signer: {
|
||||||
Account: string
|
Account: string
|
||||||
@@ -207,21 +205,3 @@ export interface EmitDetails {
|
|||||||
EmitHookHash: string
|
EmitHookHash: string
|
||||||
EmitParentTxnID: string
|
EmitParentTxnID: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The object that describes the uritoken in MintURIToken.
|
|
||||||
*/
|
|
||||||
export interface MintURIToken {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
URI: string
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
Digest?: string
|
|
||||||
/**
|
|
||||||
* The flags that are set on the uritoken.
|
|
||||||
*/
|
|
||||||
Flags?: number
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
import { HookState } from '../ledger'
|
|
||||||
|
|
||||||
import { BaseRequest, BaseResponse } from './baseMethod'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `account_namespace` command retrieves the account namespace. All information retrieved is relative to a
|
|
||||||
* particular version of the ledger. Returns an {@link AccountNamespaceResponse}.
|
|
||||||
*
|
|
||||||
* @category Requests
|
|
||||||
*/
|
|
||||||
export interface AccountNamespaceRequest extends BaseRequest {
|
|
||||||
command: 'account_namespace'
|
|
||||||
/** A unique identifier for the account, most commonly the account's address. */
|
|
||||||
account: string
|
|
||||||
/** The hex namespace. */
|
|
||||||
namespace_id?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Response expected from an {@link AccountNamespaceRequest}.
|
|
||||||
*
|
|
||||||
* @category Responses
|
|
||||||
*/
|
|
||||||
export interface AccountNamespaceResponse extends BaseResponse {
|
|
||||||
result: {
|
|
||||||
/**
|
|
||||||
* The account requested.
|
|
||||||
*/
|
|
||||||
account: string
|
|
||||||
/**
|
|
||||||
* The namespace_id requested.
|
|
||||||
*/
|
|
||||||
namespace_id: string
|
|
||||||
/**
|
|
||||||
* A list of HookStates for the specified account namespace_id.
|
|
||||||
*/
|
|
||||||
namespace_entries: HookState[]
|
|
||||||
/**
|
|
||||||
* The ledger index of the current open ledger, which was used when
|
|
||||||
* retrieving this information.
|
|
||||||
*/
|
|
||||||
ledger_current_index: number
|
|
||||||
/** If true, this data comes from a validated ledger. */
|
|
||||||
validated: boolean
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,10 +8,6 @@ import {
|
|||||||
} from './accountCurrencies'
|
} from './accountCurrencies'
|
||||||
import { AccountInfoRequest, AccountInfoResponse } from './accountInfo'
|
import { AccountInfoRequest, AccountInfoResponse } from './accountInfo'
|
||||||
import { AccountLinesRequest, AccountLinesResponse } from './accountLines'
|
import { AccountLinesRequest, AccountLinesResponse } from './accountLines'
|
||||||
import {
|
|
||||||
AccountNamespaceRequest,
|
|
||||||
AccountNamespaceResponse,
|
|
||||||
} from './accountNamespace'
|
|
||||||
import { AccountNFTsRequest, AccountNFTsResponse } from './accountNFTs'
|
import { AccountNFTsRequest, AccountNFTsResponse } from './accountNFTs'
|
||||||
import { AccountObjectsRequest, AccountObjectsResponse } from './accountObjects'
|
import { AccountObjectsRequest, AccountObjectsResponse } from './accountObjects'
|
||||||
import {
|
import {
|
||||||
@@ -87,7 +83,6 @@ type Request =
|
|||||||
| AccountCurrenciesRequest
|
| AccountCurrenciesRequest
|
||||||
| AccountInfoRequest
|
| AccountInfoRequest
|
||||||
| AccountLinesRequest
|
| AccountLinesRequest
|
||||||
| AccountNamespaceRequest
|
|
||||||
| AccountNFTsRequest
|
| AccountNFTsRequest
|
||||||
| AccountObjectsRequest
|
| AccountObjectsRequest
|
||||||
| AccountOffersRequest
|
| AccountOffersRequest
|
||||||
@@ -138,7 +133,6 @@ type Response =
|
|||||||
| AccountCurrenciesResponse
|
| AccountCurrenciesResponse
|
||||||
| AccountInfoResponse
|
| AccountInfoResponse
|
||||||
| AccountLinesResponse
|
| AccountLinesResponse
|
||||||
| AccountNamespaceResponse
|
|
||||||
| AccountNFTsResponse
|
| AccountNFTsResponse
|
||||||
| AccountObjectsResponse
|
| AccountObjectsResponse
|
||||||
| AccountOffersResponse
|
| AccountOffersResponse
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export interface ServerInfoResponse extends BaseResponse {
|
|||||||
amendment_blocked?: boolean
|
amendment_blocked?: boolean
|
||||||
/** The version number of the running rippled version. */
|
/** The version number of the running rippled version. */
|
||||||
build_version: string
|
build_version: string
|
||||||
|
initial_sync_duration_us?: string
|
||||||
/**
|
/**
|
||||||
* Information on the most recently closed ledger that has not been
|
* Information on the most recently closed ledger that has not been
|
||||||
* validated by consensus. If the most recently validated ledger is
|
* validated by consensus. If the most recently validated ledger is
|
||||||
@@ -140,6 +141,7 @@ export interface ServerInfoResponse extends BaseResponse {
|
|||||||
* The network id of the server.
|
* The network id of the server.
|
||||||
*/
|
*/
|
||||||
network_id?: number
|
network_id?: number
|
||||||
|
node_size?: string
|
||||||
/**
|
/**
|
||||||
* Current multiplier to the transaction cost based on
|
* Current multiplier to the transaction cost based on
|
||||||
* load to this server.
|
* load to this server.
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export interface ServerStateResponse extends BaseResponse {
|
|||||||
state: {
|
state: {
|
||||||
amendment_blocked?: boolean
|
amendment_blocked?: boolean
|
||||||
build_version: string
|
build_version: string
|
||||||
|
initial_sync_duration_us?: string
|
||||||
complete_ledgers: string
|
complete_ledgers: string
|
||||||
closed_ledger?: {
|
closed_ledger?: {
|
||||||
age: number
|
age: number
|
||||||
@@ -51,6 +52,8 @@ export interface ServerStateResponse extends BaseResponse {
|
|||||||
load_factor_fee_queue?: number
|
load_factor_fee_queue?: number
|
||||||
load_factor_fee_reference?: number
|
load_factor_fee_reference?: number
|
||||||
load_factor_server?: number
|
load_factor_server?: number
|
||||||
|
network_id?: number
|
||||||
|
node_size?: string
|
||||||
peer_disconnects?: string
|
peer_disconnects?: string
|
||||||
peer_disconnects_resources?: string
|
peer_disconnects_resources?: string
|
||||||
peers: number
|
peers: number
|
||||||
|
|||||||
@@ -15,12 +15,7 @@ export interface EscrowCancel extends BaseTransaction {
|
|||||||
* Transaction sequence (or Ticket number) of EscrowCreate transaction that.
|
* Transaction sequence (or Ticket number) of EscrowCreate transaction that.
|
||||||
* created the escrow to cancel.
|
* created the escrow to cancel.
|
||||||
*/
|
*/
|
||||||
OfferSequence?: number
|
OfferSequence: number
|
||||||
/**
|
|
||||||
* The ID of the Escrow ledger object to cancel as a 64-character hexadecimal
|
|
||||||
* string.
|
|
||||||
*/
|
|
||||||
EscrowID?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,17 +35,11 @@ export function validateEscrowCancel(tx: Record<string, unknown>): void {
|
|||||||
throw new ValidationError('EscrowCancel: Owner must be a string')
|
throw new ValidationError('EscrowCancel: Owner must be a string')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx.OfferSequence === undefined && tx.EscrowID === undefined) {
|
if (tx.OfferSequence === undefined) {
|
||||||
throw new ValidationError(
|
throw new ValidationError('EscrowCancel: missing OfferSequence')
|
||||||
'EscrowCancel: must include OfferSequence or EscrowID',
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx.OfferSequence !== undefined && typeof tx.OfferSequence !== 'number') {
|
if (typeof tx.OfferSequence !== 'number') {
|
||||||
throw new ValidationError('EscrowCancel: invalid OfferSequence')
|
throw new ValidationError('EscrowCancel: OfferSequence must be a number')
|
||||||
}
|
|
||||||
|
|
||||||
if (tx.EscrowID !== undefined && typeof tx.EscrowID !== 'string') {
|
|
||||||
throw new ValidationError('EscrowCancel: invalid EscrowID')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,9 +44,8 @@ export {
|
|||||||
} from './paymentChannelClaim'
|
} from './paymentChannelClaim'
|
||||||
export { PaymentChannelCreate } from './paymentChannelCreate'
|
export { PaymentChannelCreate } from './paymentChannelCreate'
|
||||||
export { PaymentChannelFund } from './paymentChannelFund'
|
export { PaymentChannelFund } from './paymentChannelFund'
|
||||||
export { Remit } from './remit'
|
|
||||||
export { SetHookFlagsInterface, SetHookFlags, SetHook } from './setHook'
|
|
||||||
export { SetRegularKey } from './setRegularKey'
|
export { SetRegularKey } from './setRegularKey'
|
||||||
|
export { SetHookFlagsInterface, SetHookFlags, SetHook } from './setHook'
|
||||||
export { SignerListSet } from './signerListSet'
|
export { SignerListSet } from './signerListSet'
|
||||||
export { TicketCreate } from './ticketCreate'
|
export { TicketCreate } from './ticketCreate'
|
||||||
export { TrustSetFlagsInterface, TrustSetFlags, TrustSet } from './trustSet'
|
export { TrustSetFlagsInterface, TrustSetFlags, TrustSet } from './trustSet'
|
||||||
|
|||||||
@@ -11,16 +11,6 @@ export interface HookExecution {
|
|||||||
HookReturnCode: string
|
HookReturnCode: string
|
||||||
HookReturnString: string
|
HookReturnString: string
|
||||||
HookStateChangeCount: number
|
HookStateChangeCount: number
|
||||||
Flags: number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HookEmission {
|
|
||||||
HookEmission: {
|
|
||||||
EmittedTxnID: string
|
|
||||||
HookAccount: string
|
|
||||||
HookHash: string
|
|
||||||
EmitNonce: string
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +75,6 @@ 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
|
||||||
|
|||||||
@@ -15,12 +15,7 @@ export interface OfferCancel extends BaseTransaction {
|
|||||||
* created by that transaction. It is not considered an error if the offer.
|
* created by that transaction. It is not considered an error if the offer.
|
||||||
* specified does not exist.
|
* specified does not exist.
|
||||||
*/
|
*/
|
||||||
OfferSequence?: number
|
OfferSequence: number
|
||||||
/**
|
|
||||||
* The ID of the Escrow ledger object to cancel as a 64-character hexadecimal
|
|
||||||
* string.
|
|
||||||
*/
|
|
||||||
OfferID?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,17 +27,11 @@ export interface OfferCancel extends BaseTransaction {
|
|||||||
export function validateOfferCancel(tx: Record<string, unknown>): void {
|
export function validateOfferCancel(tx: Record<string, unknown>): void {
|
||||||
validateBaseTransaction(tx)
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
if (tx.OfferSequence === undefined && tx.OfferID === undefined) {
|
if (tx.OfferSequence === undefined) {
|
||||||
throw new ValidationError(
|
throw new ValidationError('OfferCancel: missing field OfferSequence')
|
||||||
'OfferCancel: must include OfferSequence or OfferID',
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx.OfferSequence !== undefined && typeof tx.OfferSequence !== 'number') {
|
if (typeof tx.OfferSequence !== 'number') {
|
||||||
throw new ValidationError('OfferCancel: invalid OfferSequence')
|
throw new ValidationError('OfferCancel: OfferSequence must be a number')
|
||||||
}
|
|
||||||
|
|
||||||
if (tx.OfferID !== undefined && typeof tx.OfferID !== 'string') {
|
|
||||||
throw new ValidationError('OfferCancel: invalid OfferID')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,11 +103,6 @@ export interface OfferCreate extends BaseTransaction {
|
|||||||
Expiration?: number
|
Expiration?: number
|
||||||
/** An offer to delete first, specified in the same way as OfferCancel. */
|
/** An offer to delete first, specified in the same way as OfferCancel. */
|
||||||
OfferSequence?: number
|
OfferSequence?: number
|
||||||
/**
|
|
||||||
* The ID of the Offer ledger object to cancel as a 64-character hexadecimal
|
|
||||||
* string.
|
|
||||||
*/
|
|
||||||
OfferID?: string
|
|
||||||
/** The amount and type of currency being provided by the offer creator. */
|
/** The amount and type of currency being provided by the offer creator. */
|
||||||
TakerGets: Amount
|
TakerGets: Amount
|
||||||
/** The amount and type of currency being requested by the offer creator. */
|
/** The amount and type of currency being requested by the offer creator. */
|
||||||
@@ -146,8 +141,4 @@ export function validateOfferCreate(tx: Record<string, unknown>): void {
|
|||||||
if (tx.OfferSequence !== undefined && typeof tx.OfferSequence !== 'number') {
|
if (tx.OfferSequence !== undefined && typeof tx.OfferSequence !== 'number') {
|
||||||
throw new ValidationError('OfferCreate: invalid OfferSequence')
|
throw new ValidationError('OfferCreate: invalid OfferSequence')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx.OfferID !== undefined && typeof tx.OfferID !== 'string') {
|
|
||||||
throw new ValidationError('OfferCreate: invalid OfferID')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,200 +0,0 @@
|
|||||||
import { ValidationError } from '../../errors'
|
|
||||||
import { AmountEntry, MintURIToken } from '../common'
|
|
||||||
import { isHex } from '../utils'
|
|
||||||
|
|
||||||
import { BaseTransaction, validateBaseTransaction } from './common'
|
|
||||||
|
|
||||||
const MAX_URI_LENGTH = 256
|
|
||||||
const DIGEST_LENGTH = 64
|
|
||||||
const MAX_ARRAY_LENGTH = 32
|
|
||||||
const MAX_BLOB_LENGTH = 1024
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Remit transaction represents a transfer of value from one account to
|
|
||||||
* another.
|
|
||||||
*
|
|
||||||
* @category Transaction Models
|
|
||||||
*/
|
|
||||||
export interface Remit extends BaseTransaction {
|
|
||||||
TransactionType: 'Remit'
|
|
||||||
/** The unique address of the account receiving the payment. */
|
|
||||||
Destination: string
|
|
||||||
/**
|
|
||||||
* Arbitrary tag that identifies the reason for the payment to the
|
|
||||||
* destination, or a hosted recipient to pay.
|
|
||||||
*/
|
|
||||||
DestinationTag?: number
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
Amounts?: AmountEntry[]
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
MintURIToken?: MintURIToken
|
|
||||||
/**
|
|
||||||
* Arbitrary 256-bit hash representing a specific reason or identifier for
|
|
||||||
* this payment.
|
|
||||||
*/
|
|
||||||
InvoiceID?: string
|
|
||||||
/**
|
|
||||||
* Hex value representing a VL Blob.
|
|
||||||
*/
|
|
||||||
Blob?: string
|
|
||||||
/** The unique address of the account to inform */
|
|
||||||
Inform?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify the form and type of a Remit at runtime.
|
|
||||||
*
|
|
||||||
* @param tx - A Remit Transaction.
|
|
||||||
* @throws When the Remit is malformed.
|
|
||||||
*/
|
|
||||||
// eslint-disable-next-line complexity -- ignore
|
|
||||||
export function validateRemit(tx: Record<string, unknown>): void {
|
|
||||||
validateBaseTransaction(tx)
|
|
||||||
|
|
||||||
if (tx.Amounts !== undefined) {
|
|
||||||
checkAmounts(tx)
|
|
||||||
}
|
|
||||||
if (tx.URITokenIDs !== undefined) {
|
|
||||||
checkURITokenIDs(tx)
|
|
||||||
}
|
|
||||||
if (tx.Destination === tx.Account) {
|
|
||||||
throw new ValidationError(
|
|
||||||
'Remit: Destination must not be equal to the account',
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (tx.DestinationTag != null && typeof tx.DestinationTag !== 'number') {
|
|
||||||
throw new ValidationError('Remit: DestinationTag must be a number')
|
|
||||||
}
|
|
||||||
if (tx.Inform === tx.Account || tx.inform === tx.Destination) {
|
|
||||||
throw new ValidationError(
|
|
||||||
'Remit: Inform must not be equal to the account or destination',
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tx.MintURIToken !== undefined) {
|
|
||||||
checkMintURIToken(tx)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tx.Blob !== undefined && typeof tx.Blob !== 'string') {
|
|
||||||
throw new ValidationError('Remit: Blob must be a string')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tx.Blob !== undefined && typeof tx.Blob === 'string') {
|
|
||||||
if (!isHex(tx.Blob)) {
|
|
||||||
throw new ValidationError('Remit: Blob must be a hex string')
|
|
||||||
}
|
|
||||||
if (tx.Blob.length > MAX_BLOB_LENGTH) {
|
|
||||||
throw new ValidationError('Remit: max size Blob')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkAmounts(tx: Record<string, unknown>): void {
|
|
||||||
if (!Array.isArray(tx.Amounts)) {
|
|
||||||
throw new ValidationError('Remit: Amounts must be an array')
|
|
||||||
}
|
|
||||||
if (tx.Amounts.length < 1) {
|
|
||||||
throw new ValidationError('Remit: empty field Amounts')
|
|
||||||
}
|
|
||||||
if (tx.Amounts.length > MAX_ARRAY_LENGTH) {
|
|
||||||
throw new ValidationError('Remit: max field Amounts')
|
|
||||||
}
|
|
||||||
const seen = new Set<string>()
|
|
||||||
let seenXrp = false
|
|
||||||
for (const amount of tx.Amounts) {
|
|
||||||
if (
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- ignore
|
|
||||||
amount.AmountEntry === undefined ||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- ignore
|
|
||||||
typeof amount.AmountEntry !== 'object'
|
|
||||||
) {
|
|
||||||
throw new ValidationError('Remit: invalid Amounts.AmountEntry')
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- ignore
|
|
||||||
if (typeof amount.AmountEntry.Amount === 'string') {
|
|
||||||
// eslint-disable-next-line max-depth -- ignore
|
|
||||||
if (seenXrp) {
|
|
||||||
throw new ValidationError(
|
|
||||||
'Remit: Duplicate Native amounts are not allowed',
|
|
||||||
)
|
|
||||||
}
|
|
||||||
seenXrp = true
|
|
||||||
} else {
|
|
||||||
// eslint-disable-next-line max-len -- ignore
|
|
||||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions, @typescript-eslint/no-unsafe-member-access -- ignore
|
|
||||||
const amountKey = `${amount.AmountEntry.Amount.currency}:${amount.AmountEntry.Amount.issuer}`
|
|
||||||
// eslint-disable-next-line max-depth -- ingore
|
|
||||||
if (seen.has(amountKey)) {
|
|
||||||
throw new ValidationError('Remit: Duplicate amounts are not allowed')
|
|
||||||
}
|
|
||||||
seen.add(amountKey)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkURITokenIDs(tx: Record<string, unknown>): void {
|
|
||||||
if (!Array.isArray(tx.URITokenIDs)) {
|
|
||||||
throw new ValidationError('Remit: invalid field URITokenIDs')
|
|
||||||
}
|
|
||||||
if (tx.URITokenIDs.length < 1) {
|
|
||||||
throw new ValidationError('Remit: empty field URITokenIDs')
|
|
||||||
}
|
|
||||||
if (tx.URITokenIDs.length > MAX_ARRAY_LENGTH) {
|
|
||||||
throw new ValidationError('Remit: max field URITokenIDs')
|
|
||||||
}
|
|
||||||
const seen = new Set<string>()
|
|
||||||
for (const token of tx.URITokenIDs) {
|
|
||||||
if (typeof token !== 'string' || !isHex(token)) {
|
|
||||||
throw new ValidationError('Remit: URITokenID must be a hex string')
|
|
||||||
}
|
|
||||||
if (token.length !== DIGEST_LENGTH) {
|
|
||||||
throw new ValidationError(
|
|
||||||
`Remit: URITokenID must be exactly ${DIGEST_LENGTH} characters`,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (seen.has(token)) {
|
|
||||||
throw new ValidationError('Remit: Duplicate URITokens are not allowed')
|
|
||||||
}
|
|
||||||
seen.add(token)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line complexity -- ignore
|
|
||||||
function checkMintURIToken(tx: Record<string, unknown>): void {
|
|
||||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
||||||
return value !== null && typeof value === 'object'
|
|
||||||
}
|
|
||||||
if (!isRecord(tx.MintURIToken)) {
|
|
||||||
throw new ValidationError('Remit: invalid MintURIToken')
|
|
||||||
}
|
|
||||||
if (tx.MintURIToken.URI === undefined) {
|
|
||||||
throw new ValidationError('Remit: missing field MintURIToken.URI')
|
|
||||||
}
|
|
||||||
if (typeof tx.MintURIToken.URI !== 'string' || !isHex(tx.MintURIToken.URI)) {
|
|
||||||
throw new ValidationError('Remit: MintURIToken.URI must be a hex string')
|
|
||||||
}
|
|
||||||
if (tx.MintURIToken.URI.length > MAX_URI_LENGTH) {
|
|
||||||
throw new ValidationError(
|
|
||||||
`Remit: URI must be less than ${MAX_URI_LENGTH} characters`,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
tx.MintURIToken.Digest !== undefined &&
|
|
||||||
typeof tx.MintURIToken.Digest !== 'string'
|
|
||||||
) {
|
|
||||||
throw new ValidationError(`Remit: MintURIToken.Digest must be a string`)
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
tx.MintURIToken.Digest !== undefined &&
|
|
||||||
!isHex(tx.MintURIToken.Digest) &&
|
|
||||||
tx.MintURIToken.Digest.length !== DIGEST_LENGTH
|
|
||||||
) {
|
|
||||||
throw new ValidationError(
|
|
||||||
`Remit: Digest must be exactly ${DIGEST_LENGTH} characters`,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -46,7 +46,6 @@ import {
|
|||||||
PaymentChannelFund,
|
PaymentChannelFund,
|
||||||
validatePaymentChannelFund,
|
validatePaymentChannelFund,
|
||||||
} from './paymentChannelFund'
|
} from './paymentChannelFund'
|
||||||
import { Remit, validateRemit } from './remit'
|
|
||||||
import { SetHook, validateSetHook } from './setHook'
|
import { SetHook, validateSetHook } from './setHook'
|
||||||
import { SetRegularKey, validateSetRegularKey } from './setRegularKey'
|
import { SetRegularKey, validateSetRegularKey } from './setRegularKey'
|
||||||
import { SignerListSet, validateSignerListSet } from './signerListSet'
|
import { SignerListSet, validateSignerListSet } from './signerListSet'
|
||||||
@@ -91,7 +90,6 @@ export type Transaction =
|
|||||||
| PaymentChannelClaim
|
| PaymentChannelClaim
|
||||||
| PaymentChannelCreate
|
| PaymentChannelCreate
|
||||||
| PaymentChannelFund
|
| PaymentChannelFund
|
||||||
| Remit
|
|
||||||
| SetHook
|
| SetHook
|
||||||
| SetRegularKey
|
| SetRegularKey
|
||||||
| SignerListSet
|
| SignerListSet
|
||||||
@@ -222,18 +220,14 @@ export function validate(transaction: Record<string, unknown>): void {
|
|||||||
validatePaymentChannelFund(tx)
|
validatePaymentChannelFund(tx)
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'Remit':
|
case 'SetRegularKey':
|
||||||
validateRemit(tx)
|
validateSetRegularKey(tx)
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'SetHook':
|
case 'SetHook':
|
||||||
validateSetHook(tx)
|
validateSetHook(tx)
|
||||||
break
|
break
|
||||||
|
|
||||||
case 'SetRegularKey':
|
|
||||||
validateSetRegularKey(tx)
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'SignerListSet':
|
case 'SignerListSet':
|
||||||
validateSignerListSet(tx)
|
validateSignerListSet(tx)
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -2,15 +2,16 @@ import {
|
|||||||
xAddressToClassicAddress,
|
xAddressToClassicAddress,
|
||||||
isValidXAddress,
|
isValidXAddress,
|
||||||
} from '@transia/ripple-address-codec'
|
} from '@transia/ripple-address-codec'
|
||||||
import { encode } from '@transia/ripple-binary-codec'
|
import BigNumber from 'bignumber.js'
|
||||||
|
|
||||||
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 { getFeeEstimateXrp } from './getFeeXrp'
|
import { getFeeXrp } 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
|
||||||
@@ -49,18 +50,17 @@ 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)
|
|
||||||
|
|
||||||
if (tx.Fee == null) {
|
return Promise.all(promises).then(() => tx)
|
||||||
await calculateFeePerTransactionType(this, tx, signersCount)
|
|
||||||
}
|
|
||||||
return tx
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setValidAddresses(tx: Transaction): void {
|
function setValidAddresses(tx: Transaction): void {
|
||||||
@@ -146,17 +146,64 @@ 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> {
|
||||||
const copyTx = { ...tx }
|
// netFee is usually 0.00001 XRP (10 drops)
|
||||||
copyTx.SigningPubKey = ``
|
const netFeeXRP = await getFeeXrp(client)
|
||||||
copyTx.Fee = `0`
|
const netFeeDrops = xrpToDrops(netFeeXRP)
|
||||||
const tx_blob = encode(copyTx)
|
let baseFee = new BigNumber(netFeeDrops)
|
||||||
// eslint-disable-next-line require-atomic-updates, no-param-reassign -- ignore
|
|
||||||
tx.Fee = await getFeeEstimateXrp(client, tx_blob, signersCount)
|
// EscrowFinish Transaction with Fulfillment
|
||||||
|
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,20 +50,15 @@ 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,
|
||||||
})
|
})
|
||||||
const openLedgerFee = response.result.drops.open_ledger_fee
|
return response.result.drops.base_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)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ describe('account_info', function () {
|
|||||||
account_data: {
|
account_data: {
|
||||||
Account: testContext.wallet.classicAddress,
|
Account: testContext.wallet.classicAddress,
|
||||||
Balance: '400000000',
|
Balance: '400000000',
|
||||||
|
AccountIndex: '1',
|
||||||
Flags: 0,
|
Flags: 0,
|
||||||
LedgerEntryType: 'AccountRoot',
|
LedgerEntryType: 'AccountRoot',
|
||||||
OwnerCount: 0,
|
OwnerCount: 0,
|
||||||
@@ -65,12 +66,14 @@ describe('account_info', function () {
|
|||||||
assert.equal(typeof response.result.account_data.Sequence, 'number')
|
assert.equal(typeof response.result.account_data.Sequence, 'number')
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
omit(response.result.account_data, [
|
omit(response.result.account_data, [
|
||||||
|
'AccountIndex',
|
||||||
'PreviousTxnID',
|
'PreviousTxnID',
|
||||||
'PreviousTxnLgrSeq',
|
'PreviousTxnLgrSeq',
|
||||||
'Sequence',
|
'Sequence',
|
||||||
'index',
|
'index',
|
||||||
]),
|
]),
|
||||||
omit(expected.result.account_data, [
|
omit(expected.result.account_data, [
|
||||||
|
'AccountIndex',
|
||||||
'PreviousTxnID',
|
'PreviousTxnID',
|
||||||
'PreviousTxnLgrSeq',
|
'PreviousTxnLgrSeq',
|
||||||
'Sequence',
|
'Sequence',
|
||||||
|
|||||||
@@ -31,12 +31,13 @@ describe('server_info (rippled)', function () {
|
|||||||
id: 0,
|
id: 0,
|
||||||
result: {
|
result: {
|
||||||
info: {
|
info: {
|
||||||
build_version: '1.7.3',
|
build_version: '2023.10.9-release+391',
|
||||||
|
initial_sync_duration_us: '443484',
|
||||||
complete_ledgers: '2563-2928',
|
complete_ledgers: '2563-2928',
|
||||||
hostid: '44578fe64241',
|
hostid: '44578fe64241',
|
||||||
io_latency_ms: 1,
|
io_latency_ms: 1,
|
||||||
jq_trans_overflow: '0',
|
jq_trans_overflow: '0',
|
||||||
last_close: { converge_time_s: 0.1, proposers: 0 },
|
last_close: { converge_time_s: 0.001, proposers: 0 },
|
||||||
load: {
|
load: {
|
||||||
job_types: [
|
job_types: [
|
||||||
{
|
{
|
||||||
@@ -53,6 +54,8 @@ describe('server_info (rippled)', function () {
|
|||||||
threads: 1,
|
threads: 1,
|
||||||
},
|
},
|
||||||
load_factor: 1,
|
load_factor: 1,
|
||||||
|
network_id: 21337,
|
||||||
|
node_size: 'small',
|
||||||
peer_disconnects: '0',
|
peer_disconnects: '0',
|
||||||
peer_disconnects_resources: '0',
|
peer_disconnects_resources: '0',
|
||||||
peers: 0,
|
peers: 0,
|
||||||
@@ -129,7 +132,7 @@ describe('server_info (rippled)', function () {
|
|||||||
)
|
)
|
||||||
assert.equal(
|
assert.equal(
|
||||||
typeof response.result.info.state_accounting[key].transitions,
|
typeof response.result.info.state_accounting[key].transitions,
|
||||||
'number',
|
'string',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -31,12 +31,13 @@ describe('server_state', function () {
|
|||||||
id: 0,
|
id: 0,
|
||||||
result: {
|
result: {
|
||||||
state: {
|
state: {
|
||||||
build_version: '1.7.3',
|
build_version: '2023.10.9-release+391',
|
||||||
|
initial_sync_duration_us: '443484',
|
||||||
complete_ledgers: '2563-2932',
|
complete_ledgers: '2563-2932',
|
||||||
io_latency_ms: 1,
|
io_latency_ms: 1,
|
||||||
jq_trans_overflow: '0',
|
jq_trans_overflow: '0',
|
||||||
last_close: {
|
last_close: {
|
||||||
converge_time: 100,
|
converge_time: 1,
|
||||||
proposers: 0,
|
proposers: 0,
|
||||||
},
|
},
|
||||||
load: {
|
load: {
|
||||||
@@ -60,6 +61,8 @@ describe('server_state', function () {
|
|||||||
load_factor_fee_queue: 256,
|
load_factor_fee_queue: 256,
|
||||||
load_factor_fee_reference: 256,
|
load_factor_fee_reference: 256,
|
||||||
load_factor_server: 256,
|
load_factor_server: 256,
|
||||||
|
network_id: 21337,
|
||||||
|
node_size: 'small',
|
||||||
peer_disconnects: '0',
|
peer_disconnects: '0',
|
||||||
peer_disconnects_resources: '0',
|
peer_disconnects_resources: '0',
|
||||||
peers: 0,
|
peers: 0,
|
||||||
@@ -133,7 +136,7 @@ describe('server_state', function () {
|
|||||||
)
|
)
|
||||||
assert.equal(
|
assert.equal(
|
||||||
typeof response.result.state.state_accounting[key].transitions,
|
typeof response.result.state.state_accounting[key].transitions,
|
||||||
'number',
|
'string',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ describe('subscribe', function () {
|
|||||||
command: 'subscribe',
|
command: 'subscribe',
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.deepEqual(response.result, {})
|
// assert.deepEqual(response.result, {})
|
||||||
assert.equal(response.type, 'response')
|
assert.equal(response.type, 'response')
|
||||||
},
|
},
|
||||||
TIMEOUT,
|
TIMEOUT,
|
||||||
@@ -86,7 +86,7 @@ describe('subscribe', function () {
|
|||||||
command: 'unsubscribe',
|
command: 'unsubscribe',
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.deepEqual(response.result, {})
|
// assert.deepEqual(response.result, {})
|
||||||
assert.equal(response.type, 'response')
|
assert.equal(response.type, 'response')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ describe('tx', function () {
|
|||||||
Fee: txResponse.result.Fee,
|
Fee: txResponse.result.Fee,
|
||||||
Flags: 0,
|
Flags: 0,
|
||||||
LastLedgerSequence: txResponse.result.LastLedgerSequence,
|
LastLedgerSequence: txResponse.result.LastLedgerSequence,
|
||||||
|
NetworkID: txResponse.result.NetworkID,
|
||||||
Sequence: txResponse.result.Sequence,
|
Sequence: txResponse.result.Sequence,
|
||||||
SigningPubKey: testContext.wallet.publicKey,
|
SigningPubKey: testContext.wallet.publicKey,
|
||||||
TxnSignature: txResponse.result.TxnSignature,
|
TxnSignature: txResponse.result.TxnSignature,
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ export async function setupClient(
|
|||||||
client: new Client(server, { timeout: 200000 }),
|
client: new Client(server, { timeout: 200000 }),
|
||||||
wallet: Wallet.generate(),
|
wallet: Wallet.generate(),
|
||||||
}
|
}
|
||||||
|
context.client.networkID = 21337
|
||||||
return connectWithRetry(context.client).then(async () => {
|
return connectWithRetry(context.client).then(async () => {
|
||||||
await fundAccount(context.client, context.wallet, {
|
await fundAccount(context.client, context.wallet, {
|
||||||
count: 20,
|
count: 20,
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
import { Client } from '@transia/xrpl'
|
|
||||||
import { assert } from 'chai'
|
|
||||||
import _ from 'lodash'
|
|
||||||
|
|
||||||
import {
|
|
||||||
convertStringToHex,
|
|
||||||
getNFTokenID,
|
|
||||||
NFTokenMint,
|
|
||||||
TransactionMetadata,
|
|
||||||
} from '../../../src'
|
|
||||||
|
|
||||||
// how long before each test case times out
|
|
||||||
const TIMEOUT = 20000
|
|
||||||
|
|
||||||
describe('NFTokenMint', function () {
|
|
||||||
// TODO: Once we update our integration tests to handle NFTs, replace this client with XrplIntegrationTestContext
|
|
||||||
it(
|
|
||||||
'get NFTokenID',
|
|
||||||
async function () {
|
|
||||||
const client = new Client('wss://s.altnet.rippletest.net:51233/')
|
|
||||||
await client.connect()
|
|
||||||
|
|
||||||
const { wallet, balance: _balance } = await client.fundWallet()
|
|
||||||
|
|
||||||
const tx: NFTokenMint = {
|
|
||||||
TransactionType: 'NFTokenMint',
|
|
||||||
Account: wallet.address,
|
|
||||||
URI: convertStringToHex('https://www.google.com'),
|
|
||||||
NFTokenTaxon: 0,
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const response = await client.submitAndWait(tx, {
|
|
||||||
wallet,
|
|
||||||
})
|
|
||||||
assert.equal(response.type, 'response')
|
|
||||||
assert.equal(
|
|
||||||
(response.result.meta as TransactionMetadata).TransactionResult,
|
|
||||||
'tesSUCCESS',
|
|
||||||
)
|
|
||||||
|
|
||||||
const accountNFTs = await client.request({
|
|
||||||
command: 'account_nfts',
|
|
||||||
account: wallet.address,
|
|
||||||
})
|
|
||||||
|
|
||||||
const nftokenID =
|
|
||||||
getNFTokenID(response.result.meta as TransactionMetadata) ??
|
|
||||||
'undefined'
|
|
||||||
const accountHasNFT = accountNFTs.result.account_nfts.some(
|
|
||||||
(value) => value.NFTokenID === nftokenID,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert.isTrue(
|
|
||||||
accountHasNFT,
|
|
||||||
`Expected to find an NFT with NFTokenID ${nftokenID} in account ${
|
|
||||||
wallet.address
|
|
||||||
} but did not find it.
|
|
||||||
\n\nHere's what was returned from 'account_nfts' for ${
|
|
||||||
wallet.address
|
|
||||||
}: ${JSON.stringify(accountNFTs)}`,
|
|
||||||
)
|
|
||||||
} finally {
|
|
||||||
await client.disconnect()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TIMEOUT,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
@@ -214,6 +214,7 @@ export async function verifySubmittedTransaction(
|
|||||||
assert(data.result)
|
assert(data.result)
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
omit(data.result, [
|
omit(data.result, [
|
||||||
|
'ctid',
|
||||||
'date',
|
'date',
|
||||||
'hash',
|
'hash',
|
||||||
'inLedger',
|
'inLedger',
|
||||||
|
|||||||
@@ -1,369 +0,0 @@
|
|||||||
import { assert } from 'chai'
|
|
||||||
|
|
||||||
import { validate, ValidationError } from '../../src'
|
|
||||||
import { validateRemit } from '../../src/models/transactions/remit'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remit Verification Testing.
|
|
||||||
*
|
|
||||||
* Providing runtime verification testing for each specific transaction type.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// eslint-disable-next-line max-statements -- ignore
|
|
||||||
describe('Remit', function () {
|
|
||||||
let remit
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
remit = {
|
|
||||||
TransactionType: 'Remit',
|
|
||||||
Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo',
|
|
||||||
Destination: 'rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy',
|
|
||||||
DestinationTag: 1,
|
|
||||||
Fee: '12',
|
|
||||||
Flags: 0,
|
|
||||||
LastLedgerSequence: 65953073,
|
|
||||||
Sequence: 65923914,
|
|
||||||
SigningPubKey:
|
|
||||||
'02F9E33F16DF9507705EC954E3F94EB5F10D1FC4A354606DBE6297DBB1096FE654',
|
|
||||||
TxnSignature:
|
|
||||||
'3045022100E3FAE0EDEC3D6A8FF6D81BC9CF8288A61B7EEDE8071E90FF9314CB4621058D10022043545CF631706D700CEE65A1DB83EFDD185413808292D9D90F14D87D3DC2D8CB',
|
|
||||||
Amounts: [
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{
|
|
||||||
AmountEntry: {
|
|
||||||
Amount: {
|
|
||||||
currency: 'USD',
|
|
||||||
issuer: 'rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX',
|
|
||||||
value: '1',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
MintURIToken: {
|
|
||||||
URI: 'DEADBEEF',
|
|
||||||
Digest:
|
|
||||||
'6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B',
|
|
||||||
Flags: 1,
|
|
||||||
},
|
|
||||||
URITokenIDs: [
|
|
||||||
'AED08CC1F50DD5F23A1948AF86153A3F3B7593E5EC77D65A02BB1B29E05AB6AE',
|
|
||||||
],
|
|
||||||
InvoiceID:
|
|
||||||
'6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B',
|
|
||||||
Blob: 'DEADBEEF',
|
|
||||||
Inform: 'rB5Ux4Lv2nRx6eeoAAsZmtctnBQ2LiACnk',
|
|
||||||
} as any
|
|
||||||
})
|
|
||||||
|
|
||||||
it(`verifies valid Remit`, function () {
|
|
||||||
assert.doesNotThrow(() => validateRemit(remit))
|
|
||||||
assert.doesNotThrow(() => validate(remit))
|
|
||||||
})
|
|
||||||
|
|
||||||
it(`throws w/ Bad Amounts`, function () {
|
|
||||||
remit.Amounts = {}
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: Amounts must be an array',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Empty Amounts`, function () {
|
|
||||||
remit.Amounts = []
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: empty field Amounts',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Max Amounts`, function () {
|
|
||||||
remit.Amounts = [
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
]
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: max field Amounts',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Duplicate native amounts`, function () {
|
|
||||||
remit.Amounts = [
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
{ AmountEntry: { Amount: '1000' } },
|
|
||||||
]
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: Duplicate Native amounts are not allowed',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Duplicate amounts`, function () {
|
|
||||||
remit.Amounts = [
|
|
||||||
{
|
|
||||||
AmountEntry: {
|
|
||||||
Amount: {
|
|
||||||
currency: 'USD',
|
|
||||||
issuer: 'rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX',
|
|
||||||
value: '1',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
AmountEntry: {
|
|
||||||
Amount: {
|
|
||||||
currency: 'USD',
|
|
||||||
issuer: 'rcXY84C4g14iFp6taFXjjQGVeHqSCh9RX',
|
|
||||||
value: '1',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: Duplicate amounts are not allowed',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Bad URITokenIDs`, function () {
|
|
||||||
remit.URITokenIDs = {}
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: invalid field URITokenIDs',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Empty URITokenIDs`, function () {
|
|
||||||
remit.URITokenIDs = []
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: empty field URITokenIDs',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Empty URITokenIDs`, function () {
|
|
||||||
remit.URITokenIDs = [
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
'DEADBEEF',
|
|
||||||
]
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: max field URITokenIDs',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Invalid URITokenID`, function () {
|
|
||||||
remit.URITokenIDs = [1]
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: URITokenID must be a hex string',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Invalid URITokenID`, function () {
|
|
||||||
remit.URITokenIDs = ['ZZ11']
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: URITokenID must be a hex string',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Duplicate URITokenIDs`, function () {
|
|
||||||
remit.URITokenIDs = ['DEADBEEF']
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: URITokenID must be exactly 64 characters',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Duplicate URITokenIDs`, function () {
|
|
||||||
remit.URITokenIDs = [
|
|
||||||
'AED08CC1F50DD5F23A1948AF86153A3F3B7593E5EC77D65A02BB1B29E05AB6AE',
|
|
||||||
'AED08CC1F50DD5F23A1948AF86153A3F3B7593E5EC77D65A02BB1B29E05AB6AE',
|
|
||||||
]
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: Duplicate URITokens are not allowed',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
// it(`throws w/ Bad MintURIToken`, function () {
|
|
||||||
// remit.MintURIToken = []
|
|
||||||
// assert.throws(
|
|
||||||
// () => validateRemit(remit),
|
|
||||||
// ValidationError,
|
|
||||||
// 'Remit: invalid MintURIToken',
|
|
||||||
// )
|
|
||||||
// })
|
|
||||||
it(`throws w/ Missing MintURIToken.URI`, function () {
|
|
||||||
remit.MintURIToken = {}
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: missing field MintURIToken.URI',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Bad MintURIToken.URI`, function () {
|
|
||||||
remit.MintURIToken = {
|
|
||||||
URI: 1,
|
|
||||||
}
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: MintURIToken.URI must be a hex string',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Bad MintURIToken.URI`, function () {
|
|
||||||
remit.MintURIToken = {
|
|
||||||
URI: 'ZZ11',
|
|
||||||
}
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: MintURIToken.URI must be a hex string',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Bad MintURIToken Less than 1`, function () {
|
|
||||||
remit.MintURIToken = {
|
|
||||||
URI: '',
|
|
||||||
}
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: MintURIToken.URI must be a hex string',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Bad MintURIToken.Digest`, function () {
|
|
||||||
remit.MintURIToken = {
|
|
||||||
URI: 'DEADBEEF',
|
|
||||||
Digest: 1,
|
|
||||||
}
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: MintURIToken.Digest must be a string',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Bad MintURIToken.Digest`, function () {
|
|
||||||
remit.MintURIToken = {
|
|
||||||
URI: 'DEADBEEF',
|
|
||||||
Digest: 'ZZ11',
|
|
||||||
}
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: Digest must be exactly 64 characters',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Bad Destination`, function () {
|
|
||||||
remit.Destination = 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo'
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: Destination must not be equal to the account',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Bad Destination Tag`, function () {
|
|
||||||
remit.DestinationTag = '1'
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: DestinationTag must be a number',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Bad Inform`, function () {
|
|
||||||
remit.Inform = 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo'
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: Inform must not be equal to the account or destination',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Bad Blob Type`, function () {
|
|
||||||
remit.Blob = 1
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: Blob must be a string',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
it(`throws w/ Bad Blob Not Hex`, function () {
|
|
||||||
remit.Blob = 'ZZ11'
|
|
||||||
assert.throws(
|
|
||||||
() => validateRemit(remit),
|
|
||||||
ValidationError,
|
|
||||||
'Remit: Blob must be a hex string',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
// it(`throws w/ Bad Blob Max Size`, function () {
|
|
||||||
// remit.Blob = ''
|
|
||||||
// assert.throws(
|
|
||||||
// () => validateRemit(remit),
|
|
||||||
// ValidationError,
|
|
||||||
// 'Remit: Blob must be a hex string',
|
|
||||||
// )
|
|
||||||
// })
|
|
||||||
})
|
|
||||||
Reference in New Issue
Block a user