Compare commits

..

9 Commits

Author SHA1 Message Date
Denis Angell
09533116ce add checkId ledger hash 2023-04-23 15:08:36 -04:00
dependabot[bot]
b86f736cab build(deps-dev): bump expect from 29.4.3 to 29.5.0 (#2248) 2023-04-21 21:35:26 +00:00
dependabot[bot]
7a89f8c63e build(deps): bump buffer from 5.6.0 to 6.0.3 (#2249) 2023-04-21 21:11:28 +00:00
Caleb Kniffen
4ffc51ad54 docs: detail how to reference on a cdn (#2271) 2023-04-12 18:57:48 -05:00
Mayukha Vadari
d2224e9cfb remove: remove old sidechain design features (#2060)
* remove federator_info RPC

* remove util

* update history

* fix merge issues
2023-04-11 15:03:13 -04:00
Florian
70745f4c94 Update the applications.md file (#2269) 2023-04-10 11:37:19 -05:00
Jackson Mills
c5433c6ac0 Update docker to use xrpllabs image (#2223)
Added additional documentation and config.
2023-04-06 11:11:46 -07:00
Mayukha Vadari
be2aa32542 fix: don't run ripple-binary-codec tests on install (#2260)
fix rbc scripts
2023-04-06 13:03:23 -04:00
dependabot[bot]
18e777b093 build(deps-dev): bump jest-mock from 29.4.2 to 29.4.3 (#2233) 2023-04-03 14:25:07 +00:00
132 changed files with 2674 additions and 4817 deletions

151
.ci-config/rippled.cfg Normal file
View File

@@ -0,0 +1,151 @@
[server]
port_rpc_admin_local
port_ws_public
port_ws_admin_local
# port_peer
# port_ws_admin_local
# ssl_key = /etc/ssl/private/server.key
# ssl_cert = /etc/ssl/certs/server.crt
# IPs must be 0.0.0.0 instead of 127.0.0.1 to be accessed outside the docker container
[port_rpc_admin_local]
port = 5005
ip = 0.0.0.0
admin = 0.0.0.0
protocol = http
[port_ws_public]
port = 80
ip = 0.0.0.0
protocol = ws
# [port_peer]
# port = 51235
# ip = 0.0.0.0
# protocol = peer
[port_ws_admin_local]
port = 6006
ip = 0.0.0.0
admin = 0.0.0.0
protocol = ws
[node_size]
small
# tiny
# small
# medium
# large
# huge
[node_db]
type=NuDB
path=/var/lib/rippled/db/nudb
advisory_delete=0
# How many ledgers do we want to keep (history)?
# Integer value that defines the number of ledgers
# between online deletion events
online_delete=256
[ledger_history]
# How many ledgers do we want to keep (history)?
# Integer value (ledger count)
# or (if you have lots of TB SSD storage): 'full'
256
[database_path]
/var/lib/rippled/db
[debug_logfile]
/var/log/rippled/debug.log
[sntp_servers]
time.windows.com
time.apple.com
time.nist.gov
pool.ntp.org
[ips]
r.ripple.com 51235
[validators_file]
validators.txt
[rpc_startup]
{ "command": "log_level", "severity": "info" }
# severity (order: lots of information .. only errors)
# debug
# info
# warn
# error
# fatal
[ssl_verify]
1
# The [features] stanza does not currently work for standalone mode: https://github.com/XRPLF/xrpl-dev-portal/issues/1762#issuecomment-1441252450
# In order to enable an amendment which by default would vote "No", you must include its amendment id and name here.
# To get the list of amendments on a network:
# 1. Run this ledger_entry command against the network to get a list of enabled amendment ids. (Command is in the websocket link as an easy way to run it)
# https://xrpl.org/websocket-api-tool.html?server=wss%3A%2F%2Fs1.ripple.com%2F&req=%7B%22command%22%3A%22ledger_entry%22%2C%22index%22%3A%227DB0788C020F02780A673DC74757F23823FA3014C1866E72CC4CD8B226CD6EF4%22%2C%22ledger_index%22%3A%22validated%22%7D
# 2. Strip away the quotes and commas
# 3. Add the amendment name to the same line as each amendment id (You can look them up via hash on https://xrpl.org/known-amendments.html)
# Ex. 4C97EBA926031A7CF7D7B36FDE3ED66DDA5421192D63DE53FFB46E43B9DC8373 Multisign
# The amendment name can be any string (including just a number)
#
# Note: The version of rippled you use this config with must have an implementation for the amendments you attempt to enable or it will crash.
[amendments]
# Devnet amendments as of March 28th, 2023
B4E4F5D2D6FB84DF7399960A732309C9FD530EAE5941838160042833625A6076 NegativeUNL
DF8B4536989BDACE3F934F29423848B9F1D76D09BE6A1FCFE7E7F06AA26ABEAD fixRemoveNFTokenAutoTrustLine
3C43D9A973AA4443EF3FC38E42DD306160FBFFDAB901CD8BAA15D09F2597EB87 NonFungibleTokensV1
98DECF327BF79997AEC178323AD51A830E457BFC6D454DAF3E46E5EC42DC619F CheckCashMakesTrustLine
B6B3EEDC0267AB50491FDC450A398AF30DBCD977CECED8BEF2499CAB5DAC19E2 fixRmSmallIncreasedQOffers
452F5906C46D46F407883344BFDD90E672B672C5E9943DB4891E3A34FEEEB9DB fixSTAmountCanonicalize
AF8DF7465C338AE64B1E937D6C8DA138C0D63AD5134A68792BBBE1F63356C422 FlowSortStrands
955DF3FA5891195A9DAEFA1DDC6BB244B545DDE1BAA84CBB25D5F12A8DA68A0C TicketBatch
B4D44CC3111ADD964E846FC57760C8B50FFCD5A82C86A72756F6B058DDDF96AD fix1201
89308AF3B8B10B7192C4E613E1D2E4D9BA64B2EE2D5232402AE82A6A7220D953 fixQualityUpperBound
3012E8230864E95A58C60FD61430D7E1B4D3353195F2981DC12B0C7C0950FFAC FlowCross
DC9CA96AEA1DCF83E527D1AFC916EFAF5D27388ECA4060A88817C1238CAEE0BF EnforceInvariants
B9E739B8296B4A1BB29BE990B17D66E21B62A300A909F25AC55C22D6C72E1F9D fix1523
1F4AFA8FA1BC8827AD4C0F682C03A8B671DCDF6B5C4DE36D44243A684103EF88 HardenedValidations
3CBC5C4E630A1B82380295CDA84B32B49DD066602E74E39B85EF64137FA65194 DepositPreauth
586480873651E106F1D6339B0C4A8945BA705A777F3F4524626FF1FC07EFE41D MultiSignReserve
58BE9B5968C4DA7C59BA900961828B113E5490699B21877DEF9A31E9D0FE5D5F fix1623
42426C4D4F1009EE67080A9B7965B44656D7714D104A72F9B4369F97ABF044EE FeeEscalation
08DE7D96082187F6E6578530258C77FAABABE4C20474BDB82F04B021F1A68647 PayChan
67A34F2CF55BFC0F93AACD5B281413176FEE195269FA6D95219A2DF738671172 fix1513
00C1FC4A53E60AB02C864641002B3172F38677E29C26C5406685179B37E1EDAC RequireFullyCanonicalSig
CA7C02118BA27599528543DFE77BA6838D1B0F43B447D4D7F53523CE6A0E9AC2 fix1543
532651B4FD58DF8922A49BA101AB3E996E5BFBF95A913B3E392504863E63B164 TickSize
25BA44241B3BD880770BFA4DA21C7180576831855368CBEC6A3154FDE4A7676E fix1781
8F81B066ED20DAECA20DF57187767685EEF3980B228E0667A650BAF24426D3B4 fixCheckThreading
5D08145F0A4983F23AFFFF514E83FAD355C5ABFBB6CAB76FB5BC8519FF5F33BE fix1515
1562511F573A19AE9BD103B5D6B9E01B3B46805AEC5D3C4805C902B514399146 CryptoConditions
1D3463A5891F9E589C5AE839FFAC4A917CE96197098A1EF22304E1BC5B98A454 fix1528
621A0B264970359869E3C0363A899909AAB7A887C8B73519E4ECF952D33258A8 fixPayChanRecipientOwnerDir
CC5ABAE4F3EC92E94A59B1908C2BE82D2228B6485C00AFF8F22DF930D89C194E SortedDirectories
FBD513F1B893AC765B78F250E6FFA6A11B573209D1842ADC787C850696741288 fix1578
7117E2EC2DBF119CA55181D69819F1999ECEE1A0225A7FD2B9ED47940968479C fix1571
4F46DF03559967AC60F2EB272FEFE3928A7594A45FF774B87A7E540DB0F8F068 fixAmendmentMajorityCalc
2CD5286D8D687E98B41102BDD797198E81EA41DF7BD104E6561FEB104EFF2561 fixTakerDryOfferRemoval
C4483A1896170C66C098DEA5B0E024309C60DC960DE5F01CD7AF986AA3D9AD37 fixMasterKeyAsRegularKey
740352F2412A9909880C23A559FCECEDA3BE2126FED62FC7660D628A06927F11 Flow
07D43DCE529B15A10827E5E04943B496762F9A88E3268269D69C44BE49E21104 Escrow
6781F8368C4771B83E8B821D88F580202BCB4228075297B19E4FDC5233F1EFDC TrustSetAuth
30CD365592B8EE40489BA01AE2F7555CAC9C983145871DC82A42A31CF5BAE7D9 DeletableAccounts
F64E1EABBE79D55B3BB82020516CEC2C582A98A6BFE20FBE9BB6A0D233418064 DepositAuth
E2E6F2866106419B88C50045ACE96368558C345566AC8F2BDF5A5B5587F0E6FA fix1368
6C92211186613F9647A89DFFBAB8F94C99D4C7E956D495270789128569177DA1 fix1512
42EEA5E28A97824821D4EF97081FE36A54E9593C6E4F20CBAE098C69D2E072DC fix1373
4C97EBA926031A7CF7D7B36FDE3ED66DDA5421192D63DE53FFB46E43B9DC8373 MultiSign
157D2D480E006395B76F948E3E07A45A05FE10230D88A7993C71F97AE4B1F2D1 Checks

View File

@@ -100,15 +100,13 @@ jobs:
matrix:
node-version: [14.x, 16.x, 18.x]
services:
rippled:
image: natenichols/rippled-standalone:latest
ports:
- 6006:6006
options: --health-cmd="wget localhost:6006 || exit 1" --health-interval=5s --health-retries=10 --health-timeout=2s
steps:
- uses: actions/checkout@v3
- name: Run docker in background
run: |
docker run --detach --rm --name rippled-service -p 6006:6006 --volume "${{ github.workspace }}/.ci-config/":"/config/" --health-cmd="wget localhost:6006 || exit 1" --health-interval=5s --health-retries=10 --health-timeout=2s --env "ENV_ARGS=-a --start" --env GITHUB_ACTIONS=true --env CI=true xrpllabsofficial/xrpld:latest
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
@@ -138,10 +136,13 @@ jobs:
run: npm ci
- run: npm run build
- run: npm run test:integration
env:
HOST: localhost
PORT: ${{ job.services.rippled.ports['6006'] }}
- name: Run integration test
run: npm run test:integration
- name: Stop docker container
if: always()
run: docker stop rippled-service
browser:
runs-on: ubuntu-latest
@@ -151,20 +152,18 @@ jobs:
matrix:
node-version: [14.x] # This just needs to be compatible w/ puppeteer
services:
rippled:
image: natenichols/rippled-standalone:latest
ports:
- 6006:6006
options: --health-cmd="wget localhost:6006 || exit 1" --health-interval=5s --health-retries=10 --health-timeout=2s
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Run docker in background
run: |
docker run --detach --rm --name rippled-service -p 6006:6006 --volume "${{ github.workspace }}/.ci-config/":"/config/" --health-cmd="wget localhost:6006 || exit 1" --health-interval=5s --health-retries=10 --health-timeout=2s --env "ENV_ARGS=-a --start" --env GITHUB_ACTIONS=true --env CI=true xrpllabsofficial/xrpld:latest
- name: Setup npm version 7
run: |
npm i -g npm@7 --registry=https://registry.npmjs.org
@@ -189,4 +188,10 @@ jobs:
run: npm ci
- run: npm run build
- run: npm run test:browser
- name: Run integration test
run: npm run test:browser
- name: Stop docker container
if: always()
run: docker stop rippled-service

2
.gitignore vendored
View File

@@ -39,8 +39,6 @@ db/*.db
db/*.db-*
# Ignore customized configs
rippled.cfg
validators.txt
test/config.js
# Ignore coverage files

View File

@@ -29,7 +29,7 @@
"enable": true
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
"source.fixAll.eslint": true
},
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,

View File

@@ -74,6 +74,10 @@ Warning: Use at your own risk.
## Wallets and wallet tools
- **[GemWallet](https://gemwallet.app/)**
Users can use the GemWallet (non-custodial) web extension to interact with the XRPL from their browser. The documentation is available at [https://gemwallet.app/](https://gemwallet.app/docs/user-guide/introduction).
- **[XUMM](https://xumm.app/)**
Users can use the xumm application to track their accounts, balances and transactions. The true power of xumm is the platform available for developers.

View File

@@ -47,7 +47,7 @@ npm run lint
## Running Tests
For integration and browser tests, we use a `rippled` node in standalone mode to test xrpl.js code against. To set this up, you can either run `rippled` locally, or set up the Docker container `natenichols/rippled-standalone:latest` for this purpose. The latter will require you to [install Docker](https://docs.docker.com/get-docker/).
For integration and browser tests, we use a `rippled` node in standalone mode to test xrpl.js code against. To set this up, you can either configure and run `rippled` locally, or set up the Docker container `xrpllabsofficial/xrpld:latest` by [following these instructions](#integration-tests). The latter will require you to [install Docker](https://docs.docker.com/get-docker/).
### Unit Tests
@@ -59,14 +59,25 @@ npm test
### Integration Tests
From the top-level xrpl.js folder (one level above `packages`), run the following commands:
```bash
npm install
# sets up the rippled standalone Docker container - you can skip this step if you already have it set up
docker run -p 6006:6006 -it natenichols/rippled-standalone:latest
docker run -p 6006:6006 --interactive -t --volume $PWD/.ci-config:/config/ xrpllabsofficial/xrpld:latest -a --start
npm run build
npm run test:integration
```
Breaking down the command:
* `docker run -p 6006:6006` starts a Docker container with an open port for admin WebSocket requests.
* `--interactive` allows you to interact with the container.
* `-t` starts a terminal in the container for you to send commands to.
* `--volume $PWD/.ci-config:/config/` identifies the `rippled.cfg` and `validators.txt` to import. It must be an absolute path, so we use `$PWD` instead of `./`.
* `xrpllabsofficial/xrpld:latest` is an image that is regularly updated with the latest `rippled` releases and can be found here: https://github.com/WietseWind/docker-rippled
* `-a` starts `rippled` in standalone mode
* `--start` signals to start `rippled` with the specified amendments in `rippled.cfg` enabled immediately instead of voting for 2 weeks on them.
### Browser Tests
There are two ways to run browser tests.
@@ -75,10 +86,12 @@ One is in the browser - run `npm run build:browserTests` and open `test/localInt
The other is in the command line (this is what we use for CI) -
This should be run from the `xrpl.js` top level folder (one above the `packages` folder).
```bash
npm run build
# sets up the rippled standalone Docker container - you can skip this step if you already have it set up
docker run -p 6006:6006 -it natenichols/rippled-standalone:latest
docker run -p 6006:6006 -it -v $PWD/.ci-config:/config/ xrpllabsofficial/xrpld:latest -a --start
npm run test:browser
```

View File

@@ -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:
```
$ npm install --save @transia/xrpl
$ npm install --save xrpl
```
Or with `yarn`:
```
$ yarn add @transia/xrpl
$ yarn add xrpl
```
Example usage:
```js
const xrpl = require("@transia/xrpl");
const xrpl = require("xrpl");
async function main() {
const client = new xrpl.Client("wss://s.altnet.rippletest.net:51233");
await client.connect();
@@ -74,6 +74,7 @@ It goes through:
If you're using xrpl.js with React or Deno, you'll need to do a couple extra steps to set it up:
- [Using xrpl.js with a CDN](./UNIQUE_SETUPS.md#using-xrpljs-from-a-cdn)
- [Using xrpl.js with `create-react-app`](./UNIQUE_SETUPS.md#using-xrpljs-with-create-react-app)
- [Using xrpl.js with `React Native`](./UNIQUE_SETUPS.md#using-xrpljs-with-react-native)
- [Using xrpl.js with `Vite React`](./UNIQUE_SETUPS.md#using-xrpljs-with-vite-react)

View File

@@ -2,6 +2,15 @@
For when you need to do more than just install `xrpl.js` for it to work (especially for React projects in the browser).
### Using xrpl.js from a CDN
You can avoid setting up your build system to handle `xrpl.js` by using a cdn version that is prebuilt for the browser.
- unpkg `<script src="https://unpkg.com/xrpl@2.3.0/build/xrpl-latest-min.js"></script>`
- jsdelivr `<script src="https://cdn.jsdelivr.net/npm/xrpl@2.3.0/build/xrpl-latest-min.js"></script>`
Ensure that the full path is provided so the browser can find the sourcemaps.
### Using xrpl.js with `create-react-app`
To use `xrpl.js` with React, you need to install shims for core NodeJS modules. Starting with version 5, Webpack stopped including shims by default, so you must modify your Webpack configuration to add the shims you need. Either you can eject your config and modify it, or you can use a library such as `react-app-rewired`. The example below uses `react-app-rewired`.

4177
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -13,10 +13,10 @@
"update:confirm": "npx npm-check-updates --configFileName .ncurc.json -u"
},
"dependencies": {
"@transia/ripple-address-codec": "file:packages/ripple-address-codec",
"@transia/ripple-binary-codec": "file:packages/ripple-binary-codec",
"@transia/ripple-keypairs": "file:packages/ripple-keypairs",
"@transia/xrpl": "file:packages/xrpl"
"ripple-address-codec": "file:packages/ripple-address-codec",
"ripple-binary-codec": "file:packages/ripple-binary-codec",
"ripple-keypairs": "file:packages/ripple-keypairs",
"xrpl": "file:packages/xrpl"
},
"devDependencies": {
"@types/brorand": "^1.0.30",

View File

@@ -1,12 +1,12 @@
{
"name": "ripple-address-codec",
"version": "4.2.8-alpha.0",
"version": "4.2.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "ripple-address-codec",
"version": "4.2.8-alpha.0",
"version": "4.2.4",
"license": "ISC",
"dependencies": {
"base-x": "^3.0.9",

View File

@@ -1,6 +1,6 @@
{
"name": "@transia/ripple-address-codec",
"version": "4.2.8-alpha.0",
"name": "ripple-address-codec",
"version": "4.2.5",
"description": "encodes/decodes base58 encoded XRP Ledger identifiers",
"files": [
"dist/*",
@@ -15,7 +15,7 @@
},
"repository": {
"type": "git",
"url": "git@github.com/Transia-RnD/xrpl.js/tree/beta"
"url": "git@github.com:XRPLF/xrpl.js.git"
},
"prepublish": "tsc -b",
"prepublishOnly": "tslint -b ./ && jest",

View File

@@ -1,6 +1,6 @@
{
"name": "@transia/ripple-binary-codec",
"version": "1.4.6-alpha.8",
"name": "ripple-binary-codec",
"version": "1.4.3",
"description": "XRP Ledger binary codec",
"files": [
"dist/*",
@@ -12,23 +12,23 @@
"test": "test"
},
"dependencies": {
"@transia/ripple-address-codec": "^4.2.8-alpha.0",
"assert": "^2.0.0",
"big-integer": "^1.6.48",
"buffer": "5.6.0",
"buffer": "6.0.3",
"create-hash": "^1.2.0",
"decimal.js": "^10.2.0"
"decimal.js": "^10.2.0",
"ripple-address-codec": "^4.2.5"
},
"scripts": {
"build": "tsc -b && copyfiles ./src/enums/definitions.json ./dist/enums/",
"clean": "rm -rf ./dist && rm -rf tsconfig.tsbuildinfo",
"prepare": "npm run build && npm test",
"test": "jest --verbose false --silent=false ./test/*.test.js",
"prepublishOnly": "npm test",
"test": "npm run build && jest --verbose false --silent=false ./test/*.test.js",
"lint": "eslint . --ext .ts --ext .test.js"
},
"repository": {
"type": "git",
"url": "git@github.com/Transia-RnD/xrpl.js/tree/beta"
"url": "git@github.com:XRPLF/xrpl.js.git"
},
"bugs": {
"url": "https://github.com/XRPLF/xrpl.js/issues"

View File

@@ -15,7 +15,6 @@ import { STObject } from './types/st-object'
import { JsonObject } from './types/serialized-type'
import { Buffer } from 'buffer/'
import bigInt = require('big-integer')
import { AmountObject } from './types/amount'
/**
* Construct a BinaryParser
@@ -123,7 +122,7 @@ function signingData(
*/
interface ClaimObject extends JsonObject {
channel: string
amount: AmountObject
amount: string | number
}
/**
@@ -134,19 +133,16 @@ interface ClaimObject extends JsonObject {
* @returns the serialized object with appropriate prefix
*/
function signingClaimData(claim: ClaimObject): Buffer {
const num = bigInt(String(claim.amount))
const prefix = HashPrefix.paymentChannelClaim
const channel = coreTypes.Hash256.from(claim.channel).toBytes()
const amount = coreTypes.UInt64.from(num).toBytes()
const bytesList = new BytesList()
bytesList.put(prefix)
bytesList.put(channel)
if (typeof claim.amount === 'string') {
const num = bigInt(String(claim.amount))
const amount = coreTypes.UInt64.from(num).toBytes()
bytesList.put(amount)
} else {
const amount = coreTypes.Amount.from(claim.amount).toBytes()
bytesList.put(amount)
}
return bytesList.toBytes()
}

View File

@@ -37,7 +37,6 @@
"LedgerHashes": 104,
"Amendments": 102,
"FeeSettings": 115,
"ImportVLSequence": 73,
"Escrow": 117,
"PayChannel": 120,
"Check": 67,
@@ -45,17 +44,11 @@
"NegativeUNL": 78,
"NFTokenPage": 80,
"NFTokenOffer": 55,
"URIToken": 85,
"UNLReport": 82,
"Any": -3,
"Child": -2,
"Nickname": 110,
"Contract": 99,
"GeneratorMap": 103,
"Hook": 72,
"HookState": 118,
"HookDefinition": 68,
"EmittedTxn": 69
"GeneratorMap": 103
},
"FIELDS": [
[
@@ -328,16 +321,6 @@
"type": "UInt16"
}
],
[
"NetworkID",
{
"nth": 1,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt32"
}
],
[
"Flags",
{
@@ -778,76 +761,6 @@
"type": "UInt32"
}
],
[
"LockCount",
{
"nth": 49,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt32"
}
],
[
"FirstNFTokenSequence",
{
"nth": 50,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt32"
}
],
[
"XahauActivationLgrSeq",
{
"nth": 96,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt32"
}
],
[
"ImportSequence",
{
"nth": 97,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt32"
}
],
[
"RewardTime",
{
"nth": 98,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt32"
}
],
[
"RewardLgrFirst",
{
"nth": 99,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt32"
}
],
[
"RewardLgrLast",
{
"nth": 100,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt32"
}
],
[
"IndexNext",
{
@@ -978,6 +891,16 @@
"type": "UInt64"
}
],
[
"HookOn",
{
"nth": 16,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt64"
}
],
[
"HookInstructionCount",
{
@@ -1008,36 +931,6 @@
"type": "UInt64"
}
],
[
"AccountIndex",
{
"nth": 98,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt64"
}
],
[
"AccountCount",
{
"nth": 99,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt64"
}
],
[
"RewardAccumulator",
{
"nth": 100,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt64"
}
],
[
"EmailHash",
{
@@ -1258,16 +1151,6 @@
"type": "Hash256"
}
],
[
"HookOn",
{
"nth": 20,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "Hash256"
}
],
[
"Digest",
{
@@ -1398,66 +1281,6 @@
"type": "Hash256"
}
],
[
"OfferID",
{
"nth": 34,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "Hash256"
}
],
[
"EscrowID",
{
"nth": 35,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "Hash256"
}
],
[
"URITokenID",
{
"nth": 36,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "Hash256"
}
],
[
"GovernanceFlags",
{
"nth": 99,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "Hash256"
}
],
[
"GovernanceMarks",
{
"nth": 98,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "Hash256"
}
],
[
"EmittedTxnID",
{
"nth": 97,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "Hash256"
}
],
[
"Amount",
{
@@ -1598,56 +1421,6 @@
"type": "Amount"
}
],
[
"HookCallbackFee",
{
"nth": 20,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "Amount"
}
],
[
"LockedBalance",
{
"nth": 21,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "Amount"
}
],
[
"BaseFeeDrops",
{
"nth": 22,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "Amount"
}
],
[
"ReserveBaseDrops",
{
"nth": 23,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "Amount"
}
],
[
"ReserveIncrementDrops",
{
"nth": 24,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "Amount"
}
],
[
"PublicKey",
{
@@ -1888,16 +1661,6 @@
"type": "Blob"
}
],
[
"Blob",
{
"nth": 26,
"isVLEncoded": true,
"isSerialized": true,
"isSigningField": true,
"type": "Blob"
}
],
[
"Account",
{
@@ -2038,16 +1801,6 @@
"type": "Vector256"
}
],
[
"HookNamespaces",
{
"nth": 5,
"isVLEncoded": true,
"isSerialized": true,
"isSigningField": true,
"type": "Vector256"
}
],
[
"Paths",
{
@@ -2268,46 +2021,6 @@
"type": "STObject"
}
],
[
"GenesisMint",
{
"nth": 96,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "STObject"
}
],
[
"ActiveValidator",
{
"nth": 95,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "STObject"
}
],
[
"ImportVLKey",
{
"nth": 94,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "STObject"
}
],
[
"HookEmission",
{
"nth": 93,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "STObject"
}
],
[
"Signers",
{
@@ -2447,46 +2160,6 @@
"isSigningField": true,
"type": "STArray"
}
],
[
"GenesisMints",
{
"nth": 96,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "STArray"
}
],
[
"ActiveValidators",
{
"nth": 95,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "STArray"
}
],
[
"ImportVLKeys",
{
"nth": 94,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "STArray"
}
],
[
"HookEmissions",
{
"nth": 93,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "STArray"
}
]
],
"TRANSACTION_RESULTS": {
@@ -2503,12 +2176,6 @@
"telCAN_NOT_QUEUE_BLOCKED": -389,
"telCAN_NOT_QUEUE_FEE": -388,
"telCAN_NOT_QUEUE_FULL": -387,
"telWRONG_NETWORK": -386,
"telREQUIRES_NETWORK_ID": -385,
"telNETWORK_ID_MAKES_TX_NON_CANONICAL": -384,
"telNON_LOCAL_EMITTED_TXN": -383,
"telIMPORT_VL_KEY_NOT_RECOGNISED": -382,
"telCAN_NOT_QUEUE_IMPORT": -381,
"temMALFORMED": -299,
"temBAD_AMOUNT": -298,
@@ -2521,11 +2188,11 @@
"temBAD_PATH": -291,
"temBAD_PATH_LOOP": -290,
"temBAD_REGKEY": -289,
"temBAD_SEND_NATIVE_LIMIT": -288,
"temBAD_SEND_NATIVE_MAX": -287,
"temBAD_SEND_NATIVE_NO_DIRECT": -286,
"temBAD_SEND_NATIVE_PARTIAL": -285,
"temBAD_SEND_NATIVE_PATHS": -284,
"temBAD_SEND_XRP_LIMIT": -288,
"temBAD_SEND_XRP_MAX": -287,
"temBAD_SEND_XRP_NO_DIRECT": -286,
"temBAD_SEND_XRP_PARTIAL": -285,
"temBAD_SEND_XRP_PATHS": -284,
"temBAD_SEQUENCE": -283,
"temBAD_SIGNATURE": -282,
"temBAD_SRC_ACCOUNT": -281,
@@ -2548,15 +2215,6 @@
"temUNKNOWN": -264,
"temSEQ_AND_TICKET": -263,
"temBAD_NFTOKEN_TRANSFER_FEE": -262,
"temAMM_BAD_TOKENS": -261,
"temXCHAIN_EQUAL_DOOR_ACCOUNTS": -260,
"temXCHAIN_BAD_PROOF": -259,
"temXCHAIN_BRIDGE_BAD_ISSUES": -258,
"temXCHAIN_BRIDGE_NONDOOR_OWNER": -257,
"temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT": -256,
"temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT": -255,
"temXCHAIN_TOO_MANY_ATTESTATIONS": -254,
"temHOOK_DATA_TOO_LARGE": -253,
"tefFAILURE": -199,
"tefALREADY": -198,
@@ -2579,9 +2237,6 @@
"tefTOO_BIG": -181,
"tefNO_TICKET": -180,
"tefNFTOKEN_IS_NOT_TRANSFERABLE": -179,
"tefPAST_IMPORT_SEQ": -178,
"tefPAST_IMPORT_VL_SEQ": -177,
"tefNONDIR_EMIT": -176,
"terRETRY": -99,
"terFUNDS_SPENT": -98,
@@ -2595,8 +2250,6 @@
"terNO_RIPPLE": -90,
"terQUEUED": -89,
"terPRE_TICKET": -88,
"terNO_AMM": -87,
"terNO_HOOK": -86,
"tesSUCCESS": 0,
@@ -2610,7 +2263,7 @@
"tecINSUF_RESERVE_LINE": 122,
"tecINSUF_RESERVE_OFFER": 123,
"tecNO_DST": 124,
"tecNO_DST_INSUF_NATIVE": 125,
"tecNO_DST_INSUF_XRP": 125,
"tecNO_LINE_INSUF_RESERVE": 126,
"tecNO_LINE_REDUNDANT": 127,
"tecPATH_DRY": 128,
@@ -2638,7 +2291,6 @@
"tecKILLED": 150,
"tecHAS_OBLIGATIONS": 151,
"tecTOO_SOON": 152,
"tecHOOK_REJECTED": 153,
"tecMAX_SEQUENCE_REACHED": 154,
"tecNO_SUITABLE_NFTOKEN_PAGE": 155,
"tecNFTOKEN_BUY_SELL_MISMATCH": 156,
@@ -2646,34 +2298,7 @@
"tecCANT_ACCEPT_OWN_NFTOKEN_OFFER": 158,
"tecINSUFFICIENT_FUNDS": 159,
"tecOBJECT_NOT_FOUND": 160,
"tecINSUFFICIENT_PAYMENT": 161,
"tecAMM_UNFUNDED": 162,
"tecAMM_BALANCE": 163,
"tecAMM_FAILED_DEPOSIT": 164,
"tecAMM_FAILED_WITHDRAW": 165,
"tecAMM_INVALID_TOKENS": 166,
"tecAMM_FAILED_BID": 167,
"tecAMM_FAILED_VOTE": 168,
"tecREQUIRES_FLAG": 169,
"tecPRECISION_LOSS": 170,
"tecBAD_XCHAIN_TRANSFER_ISSUE": 171,
"tecXCHAIN_NO_CLAIM_ID": 172,
"tecXCHAIN_BAD_CLAIM_ID": 173,
"tecXCHAIN_CLAIM_NO_QUORUM": 174,
"tecXCHAIN_PROOF_UNKNOWN_KEY": 175,
"tecXCHAIN_CREATE_ACCOUNT_NONXRP_ISSUE": 176,
"tecXCHAIN_WRONG_CHAIN": 177,
"tecXCHAIN_REWARD_MISMATCH": 178,
"tecXCHAIN_NO_SIGNERS_LIST": 179,
"tecXCHAIN_SENDING_ACCOUNT_MISMATCH": 180,
"tecXCHAIN_INSUFF_CREATE_AMOUNT": 181,
"tecXCHAIN_ACCOUNT_CREATE_PAST": 182,
"tecXCHAIN_ACCOUNT_CREATE_TOO_MANY": 183,
"tecXCHAIN_PAYMENT_FAILED": 184,
"tecXCHAIN_SELF_COMMIT": 185,
"tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR": 186,
"tecINSUF_RESERVE_SELLER": 187,
"tecLAST_POSSIBLE_ENTRY": 255
"tecINSUFFICIENT_PAYMENT": 161
},
"TRANSACTION_TYPES": {
"Invalid": -1,
@@ -2705,19 +2330,8 @@
"NFTokenCreateOffer": 27,
"NFTokenCancelOffer": 28,
"NFTokenAcceptOffer": 29,
"URITokenMint": 45,
"URITokenBurn": 46,
"URITokenBuy": 47,
"URITokenCreateSellOffer": 48,
"URITokenCancelSellOffer": 49,
"GenesisMint": 96,
"Import": 97,
"ClaimReward": 98,
"Invoke": 99,
"EnableAmendment": 100,
"SetFee": 101,
"UNLModify": 102,
"EmitFailure": 103,
"UNLReport": 104
"UNLModify": 102
}
}

View File

@@ -19,7 +19,6 @@ const Field = DEFAULT_DEFINITIONS.field
* @brief: All valid transaction types
*/
const TRANSACTION_TYPES = DEFAULT_DEFINITIONS.transactionNames
const TRANSACTION_TYPE_MAP = DEFAULT_DEFINITIONS.transactionMap
export {
Bytes,
@@ -32,5 +31,4 @@ export {
TransactionResult,
TransactionType,
TRANSACTION_TYPES,
TRANSACTION_TYPE_MAP,
}

View File

@@ -33,8 +33,6 @@ class XrplDefinitionsBase {
transactionType: BytesLookup
// Valid transaction names
transactionNames: string[]
// Valid transaction names
transactionMap: Record<string, number>
// Maps serializable types to their TypeScript class implementation
dataTypes: Record<string, typeof SerializedType>
@@ -70,20 +68,10 @@ class XrplDefinitionsBase {
enums.FIELDS as Array<[string, FieldInfo]>,
enums.TYPES,
)
this.transactionNames = Object.entries(enums.TRANSACTION_TYPES)
.filter(([_key, value]) => value >= 0)
.map(([key, _value]) => key)
const ignoreList = ['EnableAmendment', 'SetFee', 'UNLModify', 'EmitFailure']
this.transactionMap = Object.assign(
{},
...Object.entries(enums.TRANSACTION_TYPES)
.filter(([_key, _value]) => _value >= 0 || ignoreList.includes(_key))
.map(([key, value]) => ({ [key]: value })),
)
this.dataTypes = {} // Filled in via associateTypes
this.associateTypes(types)
}

View File

@@ -6,7 +6,6 @@ import { JsonObject } from './types/serialized-type'
import {
XrplDefinitionsBase,
TRANSACTION_TYPES,
TRANSACTION_TYPE_MAP,
DEFAULT_DEFINITIONS,
} from './enums'
import { XrplDefinitions } from './enums/xrpl-definitions'
@@ -135,7 +134,6 @@ export {
decodeQuality,
decodeLedgerData,
TRANSACTION_TYPES,
TRANSACTION_TYPE_MAP,
XrplDefinitions,
XrplDefinitionsBase,
DEFAULT_DEFINITIONS,

View File

@@ -3,7 +3,7 @@ import {
encodeAccountID,
isValidXAddress,
xAddressToClassicAddress,
} from '@transia/ripple-address-codec'
} from 'ripple-address-codec'
import { Hash160 } from './hash-160'
import { Buffer } from 'buffer/'

View File

@@ -12,7 +12,7 @@ const STANDARD_FORMAT_HEX_REGEX = /^0{24}[\x00-\x7F]{6}0{10}$/
*/
function isoToBytes(iso: string): Buffer {
const bytes = Buffer.alloc(20)
if (iso !== 'XAH') {
if (iso !== 'XRP') {
const isoBytes = iso.split('').map((c) => c.charCodeAt(0))
bytes.set(isoBytes, 12)
}
@@ -28,7 +28,7 @@ function isIsoCode(iso: string): boolean {
function isoCodeFromHex(code: Buffer): string | null {
const iso = code.toString()
if (iso === 'XAH') {
if (iso === 'XRP') {
return null
}
if (isIsoCode(iso)) {
@@ -89,7 +89,7 @@ class Currency extends Hash160 {
const hex = this.bytes.toString('hex')
if (XRP_HEX_REGEX.test(hex)) {
this._iso = 'XAH'
this._iso = 'XRP'
} else if (STANDARD_FORMAT_HEX_REGEX.test(hex)) {
this._iso = isoCodeFromHex(this.bytes.slice(12, 15))
} else {

View File

@@ -36,7 +36,7 @@ const coreTypes: Record<string, typeof SerializedType> = {
// Ensures that the DEFAULT_DEFINITIONS object connects these types to fields for serializing/deserializing
// This is done here instead of in enums/index.ts to avoid a circular dependency
// because some of the above types depend on BinarySerailizer which depends on enums/index.ts.
// because some of the above types depend on BinarySerializer which depends on enums/index.ts.
DEFAULT_DEFINITIONS.associateTypes(coreTypes)
export {

View File

@@ -5,10 +5,7 @@ import {
XrplDefinitionsBase,
} from '../enums'
import { SerializedType, JsonObject } from './serialized-type'
import {
xAddressToClassicAddress,
isValidXAddress,
} from '@transia/ripple-address-codec'
import { xAddressToClassicAddress, isValidXAddress } from 'ripple-address-codec'
import { BinaryParser } from '../serdes/binary-parser'
import { BinarySerializer, BytesList } from '../serdes/binary-serializer'
import { Buffer } from 'buffer/'

View File

@@ -1,7 +1,7 @@
const { coreTypes } = require('../src/types')
const Decimal = require('decimal.js')
const { encodeAccountID } = require('@transia/ripple-address-codec')
const { encodeAccountID } = require('ripple-address-codec')
const { binary } = require('../src/coretypes')
const { Amount, Hash160 } = coreTypes
const { makeParser, readJSON } = binary
@@ -369,7 +369,7 @@ function pathSetBinaryTests() {
currency: 'BTC',
issuer: 'r3AWbdp2jQLXLywJypdoNwVSvr81xs3uhn',
},
{ currency: 'XAH' },
{ currency: 'XRP' },
{
currency: 'USD',
issuer: 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B',

View File

@@ -105,11 +105,6 @@ let json_omitted = {
}
const NegativeUNL = require('./fixtures/negative-unl.json')
const UNLReport = {
tx: require('./fixtures/unl-report.json'),
binary: require('./fixtures/unl-report-binary.json'),
meta: require('./fixtures/unl-report-meta-binary.json'),
}
function bytesListTest() {
const list = new BytesList()
@@ -234,18 +229,6 @@ function NegativeUNLTest() {
})
}
function UNLReportTest() {
test('can serialize UNLReport', () => {
expect(encode(UNLReport.tx)).toEqual(UNLReport.binary)
})
test('can serialize UNLReport metadata', () => {
expect(encode(UNLReport.tx.meta)).toEqual(UNLReport.meta)
})
test('can deserialize UNLReport metadata', () => {
expect(decode(UNLReport.meta)).toEqual(UNLReport.tx.meta)
})
}
function omitUndefinedTest() {
test('omits fields with undefined value', () => {
let encodedOmitted = encode(json_omitted)
@@ -303,5 +286,4 @@ describe('Binary Serialization', function () {
describe('OmitUndefined', omitUndefinedTest)
describe('TicketTest', ticketTest)
describe('NFToken', nfTokenTest)
describe('UNLReport', UNLReportTest)
})

View File

@@ -44,7 +44,7 @@ describe('encode and decode using new types as a parameter', function () {
definitions.FIELDS.push([
'NewFieldDefinition',
{
nth: 101,
nth: 100,
isVLEncoded: false,
isSerialized: true,
isSigningField: true,

View File

@@ -2904,7 +2904,7 @@
"type_id": 6,
"is_native": true,
"type": "Amount",
"error": "1000000000000 absolute XAH is bigger than max native value 100000000000.0",
"error": "1000000000000 absolute XRP is bigger than max native value 100000000000.0",
"is_negative": false
},
{
@@ -2912,7 +2912,7 @@
"type_id": 6,
"is_native": true,
"type": "Amount",
"error": "10000000000000000000 absolute XAH is bigger than max native value 100000000000.0",
"error": "10000000000000000000 absolute XRP is bigger than max native value 100000000000.0",
"is_negative": true
}
]

View File

@@ -1 +0,0 @@
"120068240000000026006D2E00684000000000000000730081140000000000000000000000000000000000000000E05F7121ED93B2BE467CAD2F9F56FB3A82BDFF17F84B09E34232DDE8FAF2FC72382F142655E1"

View File

@@ -1 +0,0 @@
"201C00000000F8E51100525661E32E7A24A238F1C619D5F9DDCC41A94B33B66C0163F7EFCC8A19C9FD6F28DCE6F05FE05F7121ED3ABC6740983BFB13FFD9728EBCC365A2877877D368FC28990819522300C92A698114A53F8465478D79DC0C764F0FB2B67AE92465FD5EE1E05F7121ED49F82B2FFD537F224A1E0A10DEEFC3C25CE3882979E6B327C9F18603D21F0A2281142BF2A77E25382EC1DEF521D81D24BC0FDD35BC9BE1E05F7121ED79EB0F6A9F01A039235E536D19F812B55ACF540C9E22CF62C271E0D42BFF51748114C45147960400DB6B763110CBCE8D641E9365F24EE1E05F7121ED93B2BE467CAD2F9F56FB3A82BDFF17F84B09E34232DDE8FAF2FC72382F142655811408BCFB092DEE1BF0F2662AECE4DCC62C4AECCB8AE1E05F7121ED96F581FED430E8CBE1F08B37408857001D4118D49FBB594B0BE007C2DBFFD3678114A4EF485B50A7D91DF45450A680FAC31C53367B2DE1E05F7121EDCF31B8F683345E1C49B4A1D85BF2731E55E7D6781F3D4BF45EE7ADF2D2FB340281144D854497B48F1A41EF04E09DB656A11AAD01A703E1E05F7121EDDF197FC59A7FAA09EB1AD60A4638BA6201DD51497B5C08A1745115098E229E0E811446550CBD2B655081662AE3159B0488DE27EC0592E1F1E1E72200000000F05EE05E7121ED264807102805220DA0F312E71FC2C69E1552C9C5790F6C25E3729DEB573D5860811478339DD5880A994A5CB6E56CB7ED13FEEF201928E1F1F05FE05F7121ED93B2BE467CAD2F9F56FB3A82BDFF17F84B09E34232DDE8FAF2FC72382F142655811408BCFB092DEE1BF0F2662AECE4DCC62C4AECCB8AE1F1E1E1F1031000"

View File

@@ -1,89 +0,0 @@
{
"Account": "",
"ActiveValidator": {
"PublicKey": "ED93B2BE467CAD2F9F56FB3A82BDFF17F84B09E34232DDE8FAF2FC72382F142655"
},
"Fee": "0",
"LedgerSequence": 7155200,
"Sequence": 0,
"SigningPubKey": "",
"TransactionType": "UNLReport",
"hash": "0878863F758F74A5CBD35691CDAB625A3BCD35B21B440E20545C4757DDB0CA43",
"meta": {
"AffectedNodes": [
{
"ModifiedNode": {
"FinalFields": {
"ActiveValidators": [
{
"ActiveValidator": {
"Account": "roUo3ygV92bdhfE1v9LGpPETXvJv2kQv5",
"PublicKey": "ED93B2BE467CAD2F9F56FB3A82BDFF17F84B09E34232DDE8FAF2FC72382F142655"
}
}
],
"Flags": 0,
"ImportVLKeys": [
{
"ImportVLKey": {
"Account": "rBxZvQBY551DJ21g9AC1Qc9ASQowqcskbF",
"PublicKey": "ED264807102805220DA0F312E71FC2C69E1552C9C5790F6C25E3729DEB573D5860"
}
}
]
},
"LedgerEntryType": "UNLReport",
"LedgerIndex": "61E32E7A24A238F1C619D5F9DDCC41A94B33B66C0163F7EFCC8A19C9FD6F28DC",
"PreviousFields": {
"ActiveValidators": [
{
"ActiveValidator": {
"Account": "rGhk2uLd8ShzX2Zrcgn8sQk1LWBG4jjEwf",
"PublicKey": "ED3ABC6740983BFB13FFD9728EBCC365A2877877D368FC28990819522300C92A69"
}
},
{
"ActiveValidator": {
"Account": "rnr4kwS1VkJhvjVRuq2fbWZtEdN2HbpVVu",
"PublicKey": "ED49F82B2FFD537F224A1E0A10DEEFC3C25CE3882979E6B327C9F18603D21F0A22"
}
},
{
"ActiveValidator": {
"Account": "rJupFrPPYgUNFBdoSqhMEJ22hiHKiZSHXQ",
"PublicKey": "ED79EB0F6A9F01A039235E536D19F812B55ACF540C9E22CF62C271E0D42BFF5174"
}
},
{
"ActiveValidator": {
"Account": "roUo3ygV92bdhfE1v9LGpPETXvJv2kQv5",
"PublicKey": "ED93B2BE467CAD2F9F56FB3A82BDFF17F84B09E34232DDE8FAF2FC72382F142655"
}
},
{
"ActiveValidator": {
"Account": "rGsa7f4arJ8JE9ok9LCht6jCu5xBKUKVMq",
"PublicKey": "ED96F581FED430E8CBE1F08B37408857001D4118D49FBB594B0BE007C2DBFFD367"
}
},
{
"ActiveValidator": {
"Account": "r3htgPchiR2r8kMGzPK3Wfv3WTrpaRKjtU",
"PublicKey": "EDCF31B8F683345E1C49B4A1D85BF2731E55E7D6781F3D4BF45EE7ADF2D2FB3402"
}
},
{
"ActiveValidator": {
"Account": "rfQtB8m51sdbWgcmddRX2mMjMpSxzX1AGr",
"PublicKey": "EDDF197FC59A7FAA09EB1AD60A4638BA6201DD51497B5C08A1745115098E229E0E"
}
}
]
}
}
}
],
"TransactionIndex": 0,
"TransactionResult": "tesSUCCESS"
}
}

View File

@@ -77,7 +77,7 @@ describe('Hash256', function () {
describe('Currency', function () {
test('Decoding allows dodgy XRP without throwing', function () {
const currencyCode = '0000000000000000000000005841480000000000'
const currencyCode = '0000000000000000000000005852500000000000'
expect(Currency.from(currencyCode).toJSON()).toBe(currencyCode)
})
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 () {
const xrp = new Currency(Buffer.alloc(20))
expect(xrp.iso()).toBe('XAH')
expect(xrp.iso()).toBe('XRP')
})
test('Can handle non-standard currency codes', () => {
const currency = '015841551A748AD2C1F76FF6ECB0CCCD00000000'

View File

@@ -170,7 +170,59 @@ describe('Signing data', function () {
].join(''),
)
})
test('can create native claim blob', function () {
test('can create multi signing blobs with custom definitions', function () {
const customPaymentDefinitions = JSON.parse(
JSON.stringify(normalDefinitions),
)
customPaymentDefinitions.TRANSACTION_TYPES.Payment = 31
const newDefs = new XrplDefinitions(customPaymentDefinitions)
const signingAccount = 'rJZdUusLDtY9NEsGea7ijqhVrXv98rYBYN'
const signingJson = { ...tx_json, SigningPubKey: '' }
const actual = encodeForMultisigning(signingJson, signingAccount, newDefs)
expect(actual).toBe(
[
'534D5400', // signingPrefix
// TransactionType
'12',
'001F',
// Flags
'22',
'80000000',
// Sequence
'24',
'00000001',
// Amount
'61',
// native amount
'40000000000003E8',
// Fee
'68',
// native amount
'400000000000000A',
// SigningPubKey
'73',
// VLLength
'00',
// '',
// Account
'81',
// VLLength
'14',
'5B812C9D57731E27A2DA8B1830195F88EF32A3B6',
// Destination
'83',
// VLLength
'14',
'B5F762798A53D543A014CAF8B297CFF8F2F937E8',
// signingAccount suffix
'C0A5ABEF242802EFED4B041E8F2D4A8CC86AE3D1',
].join(''),
)
})
test('can create claim blob', function () {
const channel =
'43904CBFCDCEC530B4037871F86EE90BF799DF8D2E0EA564BC8A3F332E4F5FB1'
const amount = '1000'
@@ -187,27 +239,4 @@ describe('Signing data', function () {
].join(''),
)
})
test('can create ic claim blob', function () {
const channel =
'43904CBFCDCEC530B4037871F86EE90BF799DF8D2E0EA564BC8A3F332E4F5FB1'
const amount = {
issuer: 'rJZdUusLDtY9NEsGea7ijqhVrXv98rYBYN',
currency: 'USD',
value: '10',
}
const json = { channel, amount }
const actual = encodeForSigningClaim(json)
expect(actual).toBe(
[
// hash prefix
'434C4D00',
// channel ID
'43904CBFCDCEC530B4037871F86EE90BF799DF8D2E0EA564BC8A3F332E4F5FB1',
// amount as a uint64
'D4C38D7EA4C680000000000000000000000000005553440000000000C0A5ABEF',
// amount as a uint64
'242802EFED4B041E8F2D4A8CC86AE3D1',
].join(''),
)
})
})

View File

@@ -58,7 +58,7 @@ describe('encoding and decoding tx_json', function () {
Sequence: 19,
LimitAmount: {
value: '200',
currency: '0000000000000000000000005841480000000000',
currency: '0000000000000000000000005852500000000000',
issuer: 'r9hEDb4xBGRfBCcX3E4FirDWQBAYtpxC8K',
},
Fee: '10',

View File

@@ -1,6 +1,6 @@
{
"name": "@transia/ripple-keypairs",
"version": "1.1.8-alpha.0",
"name": "ripple-keypairs",
"version": "1.1.5",
"description": "Cryptographic key pairs for the XRP Ledger",
"scripts": {
"build": "tsc -b",
@@ -17,15 +17,15 @@
"test": "test"
},
"dependencies": {
"@transia/ripple-address-codec": "^4.2.8-alpha.0",
"bn.js": "^5.1.1",
"brorand": "^1.0.5",
"elliptic": "^6.5.4",
"hash.js": "^1.0.3"
"hash.js": "^1.0.3",
"ripple-address-codec": "^4.2.5"
},
"repository": {
"type": "git",
"url": "git@github.com/Transia-RnD/xrpl.js/tree/beta"
"url": "git@github.com:XRPLF/xrpl.js.git"
},
"license": "ISC",
"prettier": "@xrplf/prettier-config",

View File

@@ -3,7 +3,7 @@ import brorand = require('brorand')
import * as hashjs from 'hash.js'
import * as elliptic from 'elliptic'
import * as addressCodec from '@transia/ripple-address-codec'
import * as addressCodec from 'ripple-address-codec'
import { derivePrivateKey, accountPublicFromPublicGenerator } from './secp256k1'
import * as utils from './utils'

View File

@@ -1,5 +1,5 @@
import assert from 'assert'
import * as api from '@transia/ripple-address-codec'
import * as api from 'ripple-address-codec'
function toHex(bytes) {
return Buffer.from(bytes).toString('hex').toUpperCase()

View File

@@ -1,5 +1,5 @@
import assert from 'assert'
import * as api from '@transia/ripple-address-codec'
import * as api from 'ripple-address-codec'
function toHex(bytes: Buffer) {
return Buffer.from(bytes).toString('hex').toUpperCase()

View File

@@ -7,8 +7,12 @@ Subscribe to [the **xrpl-announce** mailing list](https://groups.google.com/g/xr
* Null and undefined values in transactions are now treated as though the field was not passed in.
### Fixed
* Fixed `ServerState.transitions` typing, it is now a string instead of a number. (Only used in return from `server_state` request)
* Added `destination_amount` to `PathOption` which is returned as part of a `path_find` request
### Removed
* RPCs and utils related to the old sidechain design
## 2.7.0 (2023-03-08)
### Fixed
@@ -1698,7 +1702,7 @@ __OTHER CHANGES__
parseBinary: false
}
```
+ Added full currency name support, e.g. `Currency.from_json('XAH').to_human({full_name:'Ripples'})` will return `XAH - Ripples`
+ Added full currency name support, e.g. `Currency.from_json('XRP').to_human({full_name:'Ripples'})` will return `XRP - Ripples`
+ Improved interest bearing currency support, e.g. `Currency.from_human('USD - US Dollar (2.5%pa)')`
+ 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)

View File

@@ -1,6 +1,6 @@
{
"name": "@transia/xrpl",
"version": "2.7.3-alpha.24",
"name": "xrpl",
"version": "2.7.0",
"license": "ISC",
"description": "A TypeScript/JavaScript API for interacting with the XRP Ledger in Node.js and the browser",
"files": [
@@ -22,14 +22,14 @@
"https-proxy-agent": false
},
"dependencies": {
"@transia/ripple-address-codec": "^4.2.8-alpha.0",
"@transia/ripple-binary-codec": "^1.4.6-alpha.8",
"@transia/ripple-keypairs": "^1.1.8-alpha.0",
"bignumber.js": "^9.0.0",
"bip32": "^2.0.6",
"bip39": "^3.0.4",
"https-proxy-agent": "^5.0.0",
"lodash": "^4.17.4",
"ripple-address-codec": "^4.2.5",
"ripple-binary-codec": "^1.4.3",
"ripple-keypairs": "^1.1.5",
"ws": "^8.2.2"
},
"devDependencies": {
@@ -75,11 +75,10 @@
"prettier": "@xrplf/prettier-config",
"repository": {
"type": "git",
"url": "git@github.com/Transia-RnD/xrpl.js/tree/beta"
"url": "git@github.com:XRPLF/xrpl.js.git"
},
"readmeFilename": "README.md",
"engines": {
"node": ">=10.13.0"
},
"gitHead": "3b234ec8ec1c677e0f3f534fd2985c985871c87e"
}
}

View File

@@ -18,7 +18,7 @@ async function createTxWithPaths(): Promise<void> {
source_account: wallet.classicAddress,
source_currencies: [
{
currency: 'XAH',
currency: 'XRP',
},
],
destination_account,

View File

@@ -1,7 +1,7 @@
import { IncomingMessage } from 'http'
import { request as httpsRequest, RequestOptions } from 'https'
import { isValidClassicAddress } from '@transia/ripple-address-codec'
import { isValidClassicAddress } from 'ripple-address-codec'
import type { Client } from '../client'
import { RippledError, XRPLFaucetError } from '../errors'

View File

@@ -1,28 +1,28 @@
/* eslint-disable max-lines -- There are lots of equivalent constructors which make sense to have here. */
import BigNumber from 'bignumber.js'
import { fromSeed } from 'bip32'
import { mnemonicToSeedSync, validateMnemonic } from 'bip39'
import isEqual from 'lodash/isEqual'
import omitBy from 'lodash/omitBy'
import {
classicAddressToXAddress,
isValidXAddress,
xAddressToClassicAddress,
encodeSeed,
} from '@transia/ripple-address-codec'
} from 'ripple-address-codec'
import {
decode,
encodeForSigning,
encodeForMultisigning,
encode,
} from '@transia/ripple-binary-codec'
} from 'ripple-binary-codec'
import {
deriveAddress,
deriveKeypair,
generateSeed,
verify,
sign,
} from '@transia/ripple-keypairs'
import BigNumber from 'bignumber.js'
import { fromSeed } from 'bip32'
import { mnemonicToSeedSync, validateMnemonic } from 'bip39'
import isEqual from 'lodash/isEqual'
import omitBy from 'lodash/omitBy'
} from 'ripple-keypairs'
import ECDSA from '../ECDSA'
import { ValidationError, XrplError } from '../errors'
@@ -485,10 +485,10 @@ class Wallet {
if (
txCurrency.length === standard_currency_code_len &&
txCurrency.toUpperCase() === 'XAH'
txCurrency.toUpperCase() === 'XRP'
) {
throw new XrplError(
`Trying to sign an issued currency with a similar standard code to XAH (received '${txCurrency}'). XAH is not an issued currency.`,
`Trying to sign an issued currency with a similar standard code to XRP (received '${txCurrency}'). XRP 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 */
function isoToHex(iso: string): string {
const bytes = Buffer.alloc(20)
if (iso !== 'XAH') {
if (iso !== 'XRP') {
const isoBytes = iso.split('').map((chr) => chr.charCodeAt(0))
bytes.set(isoBytes, 12)
}

View File

@@ -1,13 +1,13 @@
import { decodeAccountID } from '@transia/ripple-address-codec'
import { BigNumber } from 'bignumber.js'
import { flatMap } from 'lodash'
import { decodeAccountID } from 'ripple-address-codec'
import {
decode,
encode,
encodeForSigning,
encodeForSigningClaim,
} from '@transia/ripple-binary-codec'
import { sign as signWithKeypair, verify } from '@transia/ripple-keypairs'
import { BigNumber } from 'bignumber.js'
import { flatMap } from 'lodash'
} from 'ripple-binary-codec'
import { sign as signWithKeypair, verify } from 'ripple-keypairs'
import { ValidationError } from '../errors'
import { Signer } from '../models/common'

View File

@@ -101,7 +101,6 @@ import {
getXrpBalance,
submit,
submitAndWait,
getNetworkID,
} from '../sugar'
import fundWallet from '../Wallet/fundWallet'
@@ -201,13 +200,6 @@ class Client extends EventEmitter {
*/
public readonly maxFeeXRP: string
/**
* Network ID of the server this sdk is connected to
*
* @category Fee
*/
public networkID: number
/**
* Creates a new Client with a websocket connection to a rippled server.
*
@@ -226,7 +218,6 @@ class Client extends EventEmitter {
this.feeCushion = options.feeCushion ?? DEFAULT_FEE_CUSHION
this.maxFeeXRP = options.maxFeeXRP ?? DEFAULT_MAX_FEE_XRP
this.networkID = 1
this.connection = new Connection(server, options)
@@ -643,11 +634,6 @@ class Client extends EventEmitter {
*/
public getLedgerIndex = getLedgerIndex
/**
* @category Abstraction
*/
public getNetworkID = getNetworkID
/**
* @category Faucet
*/

View File

@@ -1,5 +1,5 @@
import { decode } from '@transia/ripple-binary-codec'
import BigNumber from 'bignumber.js'
import { decode } from 'ripple-binary-codec'
import type {
AccountTxResponse,

View File

@@ -1,7 +1,7 @@
export type LedgerIndex = number | ('validated' | 'closed' | 'current')
interface XRP {
currency: 'XAH'
currency: 'XRP'
}
interface IssuedCurrency {
@@ -51,84 +51,6 @@ interface PathStep {
export type Path = PathStep[]
/**
* The object that describes the grant in HookGrants.
*/
export interface HookGrant {
/**
* The object that describes the grant in HookGrants.
*/
HookGrant: {
/**
* The hook hash of the grant.
*/
HookHash: string
/**
* The account authorized on the grant.
*/
Authorize?: string
}
}
/**
* The object that describes the parameter in HookParameters.
*/
export interface HookParameter {
/**
* The object that describes the parameter in HookParameters.
*/
HookParameter: {
/**
* The name of the parameter.
*/
HookParameterName: string
/**
* The value of the parameter.
*/
HookParameterValue: string
}
}
/**
* The object that describes the hook in Hooks.
*/
export interface Hook {
/**
* The object that describes the hook in Hooks.
*/
Hook: {
HookHash?: string
/**
* The code that is executed when the hook is triggered.
*/
CreateCode?: string
/**
* The flags that are set on the hook.
*/
Flags?: number
/**
* The transactions that triggers the hook. Represented as a 256Hash
*/
HookOn?: string
/**
* The namespace of the hook.
*/
HookNamespace?: string
/**
* The API version of the hook.
*/
HookApiVersion?: number
/**
* The parameters of the hook.
*/
HookParameters?: HookParameter[]
/**
* The grants of the hook.
*/
HookGrants?: HookGrant[]
}
}
/**
* The object that describes the signer in SignerEntries.
*/
@@ -195,13 +117,3 @@ export interface NFTOffer {
destination?: string
expiration?: number
}
/**
* This information is added to emitted Transactions.
*/
export interface EmitDetails {
EmitBurden: number
EmitGeneration: number
EmitHookHash: string
EmitParentTxnID: string
}

View File

@@ -72,10 +72,6 @@ export default interface AccountRoot extends BaseLedgerEntry {
* account to each other.
*/
TransferRate?: number
ImportSequence?: string
GovernanceFlags?: string
GovernanceMarks?: string
AccountIndex?: number
}
/**

View File

@@ -1,20 +0,0 @@
import { Transaction } from '../transactions'
import BaseLedgerEntry from './BaseLedgerEntry'
/**
* The EmittedTxn object type contains the
*
* @category Ledger Entries
*/
export default interface EmittedTxn extends BaseLedgerEntry {
LedgerEntryType: 'EmittedTxn'
EmittedTxn: Transaction
/**
* A hint indicating which page of the sender's owner directory links to this
* object, in case the directory consists of multiple pages.
*/
OwnerNode: string
}

View File

@@ -1,9 +1,7 @@
import { Amount } from '../common'
import BaseLedgerEntry from './BaseLedgerEntry'
/**
* The Escrow object type represents a held payment waiting to be
* The Escrow object type represents a held payment of XRP waiting to be
* executed or canceled.
*
* @category Ledger Entries
@@ -12,17 +10,17 @@ export default interface Escrow extends BaseLedgerEntry {
LedgerEntryType: 'Escrow'
/**
* The address of the owner (sender) of this held payment. This is the
* account that provided the amounts, and gets it back if the held payment is
* account that provided the XRP, and gets it back if the held payment is
* canceled.
*/
Account: string
/**
* The destination address where the amounts are paid if the held payment is
* The destination address where the XRP is paid if the held payment is
* successful.
*/
Destination: string
/** The amount to be delivered by the held payment. */
Amount: Amount
/** The amount of XRP, in drops, to be delivered by the held payment. */
Amount: string
/**
* A PREIMAGE-SHA-256 crypto-condition, as hexadecimal. If present, the
* EscrowFinish transaction must contain a fulfillment that satisfies this
@@ -73,9 +71,4 @@ export default interface Escrow extends BaseLedgerEntry {
* modified this object.
*/
PreviousTxnLgrSeq: number
/**
* The fee to charge when users finish an escrow, initially set on the
* creation of an escrow contract, and updated on subsequent finish transactions
*/
TransferRate?: number
}

View File

@@ -24,6 +24,4 @@ export default interface FeeSettings extends BaseLedgerEntry {
* type.
*/
Flags: number
XahauActivationLgrSeq?: number
AccountCount?: number
}

View File

@@ -1,27 +0,0 @@
import { Hook as WHook } from '../common'
import BaseLedgerEntry from './BaseLedgerEntry'
/**
* The Hook object type contains the
*
* @category Ledger Entries
*/
export default interface Hook extends BaseLedgerEntry {
LedgerEntryType: 'Hook'
/** The identifying (classic) address of this account. */
Account: string
/**
* A hint indicating which page of the sender's owner directory links to this
* object, in case the directory consists of multiple pages.
*/
OwnerNode: string
PreviousTxnID: string
PreviousTxnLgrSeq: number
Hooks: WHook[]
}

View File

@@ -1,67 +0,0 @@
import { HookParameter } from '../common'
import BaseLedgerEntry from './BaseLedgerEntry'
/**
* The HookDefintion object type contains the
*
* @category Ledger Entries
*/
export default interface HookDefintion extends BaseLedgerEntry {
LedgerEntryType: 'HookDefintion'
/**
* The flags that are set on the hook.
*/
Flags: number
/**
* This field contains a string that is used to uniquely identify the hook.
*/
HookHash: string
/**
* The transactions that triggers the hook. Represented as a 256Hash
*/
HookOn?: string
/**
* The namespace of the hook.
*/
HookNamespace?: string
/**
* The API version of the hook.
*/
HookApiVersion?: string
/**
* The parameters of the hook.
*/
HookParameters?: HookParameter[]
/**
* The code that is executed when the hook is triggered.
*/
CreateCode?: string
/**
* This is an optional field that contains the transaction ID of the hook set.
*/
HookSetTxnID?: string
/**
* This is an optional field that contains the number of references to this hook.
*/
ReferenceCount?: number
/**
* This is an optional field that contains the fee associated with the hook.
*/
Fee?: string
/**
* This is an optional field that contains the callback fee associated with the hook.
*/
HookCallbackFee?: number
}

View File

@@ -1,29 +0,0 @@
import BaseLedgerEntry from './BaseLedgerEntry'
/**
* The HookState object type contains the
*
* @category Ledger Entries
*/
export default interface HookState extends BaseLedgerEntry {
LedgerEntryType: 'HookState'
/**
* A hint indicating which page of the sender's owner directory links to this
* object, in case the directory consists of multiple pages.
*/
OwnerNode: string
/**
* The HookStateKey property contains the key associated with this hook state,
* and the HookStateData property contains the data associated with this hook state.
*/
HookStateKey: string
/**
* The `HookStateData` property contains the data associated with this hook state.
* It is typically a string containing the data associated with this hook state,
* such as an identifier or other information.
*/
HookStateData: string
}

View File

@@ -1,19 +0,0 @@
import BaseLedgerEntry from './BaseLedgerEntry'
/**
*
*
*
* @category Ledger Entries
*/
export default interface ImportVLSequence extends BaseLedgerEntry {
LedgerEntryType: 'ImportVLSequence'
/**
*
*/
PublicKey: string
/**
*
*/
ImportSequence: string
}

View File

@@ -3,13 +3,8 @@ import Amendments from './Amendments'
import Check from './Check'
import DepositPreauth from './DepositPreauth'
import DirectoryNode from './DirectoryNode'
import EmittedTxn from './EmittedTxn'
import Escrow from './Escrow'
import FeeSettings from './FeeSettings'
import Hook from './Hook'
import HookDefinition from './HookDefinition'
import HookState from './HookState'
import ImportVLSequence from './ImportVLSequence'
import LedgerHashes from './LedgerHashes'
import NegativeUNL from './NegativeUNL'
import Offer from './Offer'
@@ -17,8 +12,6 @@ import PayChannel from './PayChannel'
import RippleState from './RippleState'
import SignerList from './SignerList'
import Ticket from './Ticket'
import UNLReport from './UNLReport'
import URIToken from './URIToken'
type LedgerEntry =
| AccountRoot
@@ -26,13 +19,8 @@ type LedgerEntry =
| Check
| DepositPreauth
| DirectoryNode
| EmittedTxn
| Escrow
| FeeSettings
| Hook
| HookDefinition
| HookState
| ImportVLSequence
| LedgerHashes
| NegativeUNL
| Offer
@@ -40,7 +28,5 @@ type LedgerEntry =
| RippleState
| SignerList
| Ticket
| UNLReport
| URIToken
export default LedgerEntry

View File

@@ -1,11 +1,9 @@
import { Amount } from '../common'
import BaseLedgerEntry from './BaseLedgerEntry'
/**
* The PayChannel object type represents a payment channel. Payment channels
* enable small, rapid off-ledger payments that can be later reconciled
* with the consensus ledger. A payment channel holds a balance that can
* enable small, rapid off-ledger payments of XRP that can be later reconciled
* with the consensus ledger. A payment channel holds a balance of XRP that can
* only be paid out to a specific destination address until the channel is
* closed.
*
@@ -20,37 +18,37 @@ export default interface PayChannel extends BaseLedgerEntry {
Account: string
/**
* The destination address for this payment channel. While the payment
* channel is open, this address is the only one that can receive amounts from the
* channel is open, this address is the only one that can receive XRP from the
* channel. This comes from the Destination field of the transaction that
* created the channel.
*/
Destination: string
/**
* Total amount that has been allocated to this channel. This includes amounts
* that have been paid to the destination address. This is initially set by the
* transaction that created the channel and can be increased if the source
* address sends a PaymentChannelFund transaction.
* Total XRP, in drops, that has been allocated to this channel. This
* includes XRP that has been paid to the destination address. This is
* initially set by the transaction that created the channel and can be
* increased if the source address sends a PaymentChannelFund transaction.
*/
Amount: Amount
Amount: string
/**
* Total amount already paid out by the channel. The difference between this value
* and the Amount field is how much can still be paid to the destination address
* with PaymentChannelClaim transactions. If the channel closes, the remaining
* difference is returned to the source address.
* Total XRP, in drops, already paid out by the channel. The difference
* between this value and the Amount field is how much XRP can still be paid
* to the destination address with PaymentChannelClaim transactions. If the
* channel closes, the remaining difference is returned to the source address.
*/
Balance: Amount
Balance: string
/**
* Public key, in hexadecimal, of the key pair that can be used to sign
* claims against this channel. This can be any valid secp256k1 or Ed25519
* public key. This is set by the transaction that created the channel and
* must match the public key used in claims against the channel. The channel
* source address can also send amounts from this channel to the destination
* source address can also send XRP from this channel to the destination
* without signed claims.
*/
PublicKey: string
/**
* Number of seconds the source address must wait to close the channel if
* it still has any amount in it. Smaller values mean that the destination
* it still has any XRP in it. Smaller values mean that the destination
* address has less time to redeem any outstanding claims after the source
* address requests to close the channel. Can be any value that fits in a
* 32-bit unsigned integer (0 to 2^32-1). This is set by the transaction that
@@ -106,10 +104,4 @@ export default interface PayChannel extends BaseLedgerEntry {
* this object, in case the directory consists of multiple pages.
*/
DestinationNode?: string
/**
* The fee to charge when users make claims on a payment channel, initially
* set on the creation of a payment channel and updated on subsequent funding
* or claim transactions.
*/
TransferRate?: number
}

View File

@@ -1,42 +0,0 @@
import BaseLedgerEntry from './BaseLedgerEntry'
interface ImportVLKey {
ImportVLKey: {
PublicKey: string
Account?: string
}
}
interface ActiveValidator {
ActiveValidator: {
PublicKey: string
Account?: string
}
}
/**
*
*
*
* @category Ledger Entries
*/
export default interface UNLReport extends BaseLedgerEntry {
LedgerEntryType: 'UNLReport'
/**
*
*/
ImportVLKeys?: ImportVLKey[]
/**
*
*/
ActiveValidators?: ActiveValidator[]
/**
* The identifying hash of the transaction that most recently modified this
* object.
*/
PreviousTxnID: string
/**
* The index of the ledger that contains the transaction that most recently
* modified this object.
*/
PreviousTxnLgrSeq: number
}

View File

@@ -1,53 +0,0 @@
import { Amount } from '../common'
import BaseLedgerEntry from './BaseLedgerEntry'
/**
* The URIToken object type contains the
*
* @category Ledger Entries
*/
export default interface URIToken extends BaseLedgerEntry {
LedgerEntryType: 'URIToken'
/**
*/
Owner: string
/**
* A hint indicating which page of the sender's owner directory links to this
* object, in case the directory consists of multiple pages.
*/
OwnerNode: string
/**
*/
Issuer: string
/**
*/
URI: string
/**
*/
Digest: string
/**
*/
Amount: Amount
/**
*/
Destination: string
/**
* The identifying hash of the transaction that most recently modified this
* object.
*/
PreviousTxnID: string
/**
* The index of the ledger that contains the transaction that most recently
* modified this object.
*/
PreviousTxnLgrSeq: number
}

View File

@@ -6,13 +6,8 @@ import Amendments from './Amendments'
import Check from './Check'
import DepositPreauth from './DepositPreauth'
import DirectoryNode from './DirectoryNode'
import EmittedTxn from './EmittedTxn'
import Escrow from './Escrow'
import FeeSettings from './FeeSettings'
import Hook from './Hook'
import HookDefinition from './HookDefinition'
import HookState from './HookState'
import ImportVLSequence from './ImportVLSequence'
import Ledger from './Ledger'
import LedgerEntry from './LedgerEntry'
import LedgerHashes from './LedgerHashes'
@@ -22,8 +17,6 @@ import PayChannel from './PayChannel'
import RippleState, { RippleStateFlags } from './RippleState'
import SignerList, { SignerListFlags } from './SignerList'
import Ticket from './Ticket'
import UNLReport from './UNLReport'
import URIToken from './URIToken'
export {
AccountRoot,
@@ -33,13 +26,8 @@ export {
Check,
DepositPreauth,
DirectoryNode,
EmittedTxn,
Escrow,
FeeSettings,
Hook,
HookDefinition,
HookState,
ImportVLSequence,
Ledger,
LedgerEntry,
LedgerHashes,
@@ -52,6 +40,4 @@ export {
SignerList,
SignerListFlags,
Ticket,
UNLReport,
URIToken,
}

View File

@@ -1,10 +1,10 @@
import { Amount, LedgerIndex } from '../common'
import { LedgerIndex } from '../common'
import { BaseRequest, BaseResponse } from './baseMethod'
interface Channel {
account: string
amount: Amount
amount: string
balance: string
channel_id: string
destination_account: string
@@ -15,7 +15,6 @@ interface Channel {
cancel_after?: number
source_tab?: number
destination_tag?: number
transfer_rate?: number
}
/**

View File

@@ -1,4 +1,4 @@
import { Amount, LedgerIndex } from '../common'
import { LedgerIndex } from '../common'
import { BaseRequest, BaseResponse } from './baseMethod'
@@ -64,14 +64,6 @@ export interface Trustline {
* false.
*/
freeze_peer?: boolean
/**
* The total amount of FT, in drops/Amount locked in payment channels or escrow.
*/
locked_balance?: Amount
/**
* The total number of lock balances on a RippleState ledger object.
*/
lock_count?: number
}
/**

View File

@@ -3,13 +3,11 @@ import {
Check,
DepositPreauth,
Escrow,
Hook,
Offer,
PayChannel,
RippleState,
SignerList,
Ticket,
URIToken,
} from '../ledger'
import { BaseRequest, BaseResponse } from './baseMethod'
@@ -18,14 +16,12 @@ type AccountObjectType =
| 'check'
| 'deposit_preauth'
| 'escrow'
| 'hook'
| 'nft_offer'
| 'offer'
| 'payment_channel'
| 'signer_list'
| 'state'
| 'ticket'
| 'uritoken'
/**
* The account_objects command returns the raw ledger format for all objects
@@ -77,13 +73,11 @@ type AccountObject =
| Check
| DepositPreauth
| Escrow
| Hook
| Offer
| PayChannel
| SignerList
| RippleState
| Ticket
| URIToken
/**
* Response expected from an {@link AccountObjectsRequest}.

View File

@@ -9,7 +9,7 @@ import { BaseRequest, BaseResponse } from './baseMethod'
*/
export interface ChannelVerifyRequest extends BaseRequest {
command: 'channel_verify'
/** The amount the provided signature authorizes. */
/** The amount of XRP, in drops, the provided signature authorizes. */
amount: string
/**
* The Channel ID of the channel that provides the XRP. This is a

View File

@@ -1,78 +0,0 @@
import { BaseRequest, BaseResponse } from './baseMethod'
/**
* The `federator_info` command asks the federator for information
* about the door account and other bridge-related information. This
* method only exists on sidechain federators. Expects a response in
* the form of a {@link FederatorInfoResponse}.
*
* @category Requests
*/
export interface FederatorInfoRequest extends BaseRequest {
command: 'federator_info'
}
/**
* Response expected from a {@link FederatorInfoRequest}.
*
* @category Responses
*/
export interface FederatorInfoResponse extends BaseResponse {
result: {
info: {
mainchain: {
door_status: {
initialized: boolean
status: 'open' | 'opening' | 'closed' | 'closing'
}
last_transaction_sent_seq: number
listener_info: {
state: 'syncing' | 'normal'
}
pending_transactions: Array<{
amount: string
destination_account: string
signatures: Array<{
public_key: string
seq: number
}>
}>
sequence: number
tickets: {
initialized: boolean
tickets: Array<{
status: 'taken' | 'available'
ticket_seq: number
}>
}
}
public_key: string
sidechain: {
door_status: {
initialized: boolean
status: 'open' | 'opening' | 'closed' | 'closing'
}
last_transaction_sent_seq: number
listener_info: {
state: 'syncing' | 'normal'
}
pending_transactions: Array<{
amount: string
destination_account: string
signatures: Array<{
public_key: string
seq: number
}>
}>
sequence: number
tickets: {
initialized: boolean
tickets: Array<{
status: 'taken' | 'available'
ticket_seq: number
}>
}
}
}
}
}

View File

@@ -23,7 +23,6 @@ import {
DepositAuthorizedRequest,
DepositAuthorizedResponse,
} from './depositAuthorized'
import { FederatorInfoRequest, FederatorInfoResponse } from './federatorInfo'
import { FeeRequest, FeeResponse } from './fee'
import {
GatewayBalancesRequest,
@@ -121,8 +120,6 @@ type Request =
// NFT methods
| NFTBuyOffersRequest
| NFTSellOffersRequest
// sidechain methods
| FederatorInfoRequest
/**
* @category Responses
@@ -171,8 +168,6 @@ type Response =
// NFT methods
| NFTBuyOffersResponse
| NFTSellOffersResponse
// sidechain methods
| FederatorInfoResponse
export {
Request,
@@ -268,7 +263,4 @@ export {
NFTBuyOffersResponse,
NFTSellOffersRequest,
NFTSellOffersResponse,
// sidechain methods
FederatorInfoRequest,
FederatorInfoResponse,
}

View File

@@ -79,11 +79,6 @@ export interface LedgerEntryRequest extends BaseRequest {
}
| string
/**
* The object ID of a transaction emitted by the ledger entry.
*/
emitted_txn?: string
/**
* The Escrow object to retrieve. If a string, must be the object ID of the
* escrow, as hexadecimal. If an object, requires owner and seq sub-fields.
@@ -97,47 +92,6 @@ export interface LedgerEntryRequest extends BaseRequest {
}
| string
/**
* The hash of the Hook object to retrieve.
*/
hook_definition?: string
/**
* The Hook object to retrieve. If a string, must be the object ID of the Hook.
* If an object, requires `account` sub-field.
*/
hook?:
| {
/** The account of the Hook object. */
account: string
}
| string
/**
* Object specifying the HookState object to retrieve. Requires the sub-fields
* `account`, `key`, and `namespace_id` to uniquely specify the HookState entry
* to retrieve.
*/
hook_state?: {
/** The account of the Hook object. */
account: string
/** The key of the state. */
key: string
/** The namespace of the state. */
namespace_id: string
}
/**
* The Import VL Sequence object to retrieve. If a string, must be the object ID of the VLSequence.
* If an object, requires `public_key` sub-field.
*/
import_vlseq?:
| {
/** The public_key of the Import VL Sequence object. */
public_key: string
}
| string
/**
* The Offer object to retrieve. If a string, interpret as the unique object
* ID to the Offer. If an object, requires the sub-fields `account` and `seq`
@@ -183,20 +137,6 @@ export interface LedgerEntryRequest extends BaseRequest {
ticket_sequence: number
}
| string
/**
* The URIToken object to retrieve. If a string, must be the object ID of the
* URIToken, as hexadecimal. If an object, the `issuer` and `uri`
* sub-fields are required to uniquely specify the URIToken entry.
*/
uri_token?:
| {
/** The issuer of the URIToken object. */
issuer: string
/** The URIToken uri string (ascii). */
uri: string
}
| string
}
/**

View File

@@ -22,7 +22,7 @@ export type ServerState =
export interface StateAccounting {
duration_us: string
transitions: number
transitions: string
}
export interface JobType {
@@ -136,10 +136,6 @@ export interface ServerInfoResponse extends BaseResponse {
* overall network's load factor.
*/
load_factor?: number
/**
* The network id of the server.
*/
network_id?: number
/**
* Current multiplier to the transaction cost based on
* load to this server.

View File

@@ -1,6 +1,6 @@
/* eslint-disable complexity -- Necessary for validateAccountSet */
import { isValidClassicAddress } from '@transia/ripple-address-codec'
import { isValidClassicAddress } from 'ripple-address-codec'
import { ValidationError } from '../../errors'
@@ -48,7 +48,6 @@ export enum AccountSetAsfFlags {
*/
asfAuthorizedNFTokenMinter = 10,
/** asf 11 is reserved for Hooks amendment */
asfTshCollect = 11,
/** Disallow other accounts from creating incoming NFTOffers */
asfDisallowIncomingNFTokenOffer = 12,
/** Disallow other accounts from creating incoming Checks */

View File

@@ -1,28 +0,0 @@
import { ValidationError } from '../../errors'
import { BaseTransaction, validateBaseTransaction } from './common'
/**
* ClaimReward is a transaction model that allows an account to claim rewards.
*
* @category Transaction Models
*/
export interface ClaimReward extends BaseTransaction {
TransactionType: 'ClaimReward'
/** The unique address of the issuer where the reward.c hook is installed. */
Issuer?: string
}
/**
* Verify the form and type of an ClaimReward at runtime.
*
* @param tx - An ClaimReward Transaction.
* @throws When the ClaimReward is Malformed.
*/
export function validateClaimReward(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)
if (tx.Issuer !== undefined && typeof tx.Issuer !== 'string') {
throw new ValidationError('ClaimReward: invalid Issuer')
}
}

View File

@@ -1,17 +1,10 @@
/* eslint-disable max-lines-per-function -- Necessary for validateBaseTransaction */
/* eslint-disable complexity -- Necessary for validateBaseTransaction */
/* eslint-disable max-statements -- Necessary for validateBaseTransaction */
import { TRANSACTION_TYPES } from '@transia/ripple-binary-codec'
import { TRANSACTION_TYPES } from 'ripple-binary-codec'
import { ValidationError } from '../../errors'
import {
Amount,
HookParameter,
IssuedCurrencyAmount,
Memo,
Signer,
EmitDetails,
} from '../common'
import { Amount, IssuedCurrencyAmount, Memo, Signer } from '../common'
import { onlyHasFields } from '../utils'
const MEMO_SIZE = 3
@@ -166,18 +159,6 @@ export interface BaseTransaction {
* account it says it is from.
*/
TxnSignature?: string
/**
* The network id of the transaction.
*/
NetworkID?: number
/**
* The hook parameters of the transaction.
*/
HookParameters?: HookParameter[]
/**
* The hook parameters of the transaction.
*/
EmitDetails?: EmitDetails
}
/**
@@ -271,9 +252,6 @@ export function validateBaseTransaction(common: Record<string, unknown>): void {
) {
throw new ValidationError('BaseTransaction: invalid TxnSignature')
}
if (common.NetworkID !== undefined && typeof common.NetworkID !== 'number') {
throw new ValidationError('BaseTransaction: invalid NetworkID')
}
}
/**

View File

@@ -3,7 +3,7 @@ import { ValidationError } from '../../errors'
import { BaseTransaction, validateBaseTransaction } from './common'
/**
* Return escrowed amount to the sender.
* Return escrowed XRP to the sender.
*
* @category Transaction Models
*/

View File

@@ -1,23 +1,22 @@
/* eslint-disable complexity -- Necessary for validateEscrowCreate */
import { ValidationError } from '../../errors'
import { Amount } from '../common'
import { BaseTransaction, isAmount, validateBaseTransaction } from './common'
import { BaseTransaction, validateBaseTransaction } from './common'
/**
* Sequester amount until the escrow process either finishes or is canceled.
* Sequester XRP until the escrow process either finishes or is canceled.
*
* @category Transaction Models
*/
export interface EscrowCreate extends BaseTransaction {
TransactionType: 'EscrowCreate'
/**
* Amount to deduct from the sender's balance and escrow. Once escrowed, the
* amount can either go to the Destination address (after the FinishAfter time)
* or returned to the sender (after the CancelAfter time).
* Amount of XRP, in drops, to deduct from the sender's balance and escrow.
* Once escrowed, the XRP can either go to the Destination address (after the.
* FinishAfter time) or returned to the sender (after the CancelAfter time).
*/
Amount: Amount
/** Address to receive escrowed amount. */
Amount: string
/** Address to receive escrowed XRP. */
Destination: string
/**
* The time, in seconds since the Ripple Epoch, when this escrow expires.
@@ -26,7 +25,7 @@ export interface EscrowCreate extends BaseTransaction {
*/
CancelAfter?: number
/**
* The time, in seconds since the Ripple Epoch, when the escrowed amount can be
* The time, in seconds since the Ripple Epoch, when the escrowed XRP can be
* released to the recipient. This value is immutable; the funds cannot move.
* until this time is reached.
*/
@@ -56,8 +55,8 @@ export function validateEscrowCreate(tx: Record<string, unknown>): void {
throw new ValidationError('EscrowCreate: missing field Amount')
}
if (typeof tx.Amount !== 'string' && !isAmount(tx.Amount)) {
throw new ValidationError('EscrowCreate: Amount must be an Amount')
if (typeof tx.Amount !== 'string') {
throw new ValidationError('EscrowCreate: Amount must be a string')
}
if (tx.Destination === undefined) {

View File

@@ -3,7 +3,7 @@ import { ValidationError } from '../../errors'
import { BaseTransaction, validateBaseTransaction } from './common'
/**
* Deliver amount from a held payment to the recipient.
* Deliver XRP from a held payment to the recipient.
*
* @category Transaction Models
*/

View File

@@ -1,38 +0,0 @@
import { ValidationError } from '../../errors'
import { BaseTransaction, validateBaseTransaction } from './common'
/**
*
*
* @category Transaction Models
*/
export interface Import extends BaseTransaction {
TransactionType: 'Import'
/**
*
*/
Issuer?: string
/**
* Hex value representing a VL Blob.
*/
Blob?: string
}
/**
* Verify the form and type of an Import at runtime.
*
* @param tx - An Import Transaction.
* @throws When the Import is Malformed.
*/
export function validateImport(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)
if (tx.Issuer !== undefined && typeof tx.Issuer !== 'string') {
throw new ValidationError('Import: Issuer must be a string')
}
if (tx.Account === tx.Issuer) {
throw new ValidationError('Import: Issuer and Account must not be equal')
}
}

View File

@@ -10,13 +10,10 @@ export { AccountDelete } from './accountDelete'
export { CheckCancel } from './checkCancel'
export { CheckCash } from './checkCash'
export { CheckCreate } from './checkCreate'
export { ClaimReward } from './claimReward'
export { DepositPreauth } from './depositPreauth'
export { EscrowCancel } from './escrowCancel'
export { EscrowCreate } from './escrowCreate'
export { EscrowFinish } from './escrowFinish'
export { Import } from './import'
export { Invoke } from './invoke'
export { NFTokenAcceptOffer } from './NFTokenAcceptOffer'
export { NFTokenBurn } from './NFTokenBurn'
export { NFTokenCancelOffer } from './NFTokenCancelOffer'
@@ -45,16 +42,6 @@ export {
export { PaymentChannelCreate } from './paymentChannelCreate'
export { PaymentChannelFund } from './paymentChannelFund'
export { SetRegularKey } from './setRegularKey'
export { SetHookFlagsInterface, SetHookFlags, SetHook } from './setHook'
export { SignerListSet } from './signerListSet'
export { TicketCreate } from './ticketCreate'
export { TrustSetFlagsInterface, TrustSetFlags, TrustSet } from './trustSet'
export {
URITokenMintFlagsInterface,
URITokenMintFlags,
URITokenMint,
} from './uriTokenMint'
export { URITokenBurn } from './uriTokenBurn'
export { URITokenCreateSellOffer } from './uriTokenCreateSellOffer'
export { URITokenBuy } from './uriTokenBuy'
export { URITokenCancelSellOffer } from './uriTokenCancelSellOffer'

View File

@@ -1,36 +0,0 @@
import { ValidationError } from '../../errors'
import { BaseTransaction, validateBaseTransaction } from './common'
/**
*
*
* @category Transaction Models
*/
export interface Invoke extends BaseTransaction {
TransactionType: 'Invoke'
/**
* If present, invokes the Hook on the Destination account.
*/
Destination?: string
/**
* Hex value representing a VL Blob.
*/
Blob?: string
}
/**
* Verify the form and type of an Invoke at runtime.
*
* @param tx - An Invoke Transaction.
* @throws When the Invoke is Malformed.
*/
export function validateInvoke(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)
if (tx.Account === tx.Destination) {
throw new ValidationError(
'Invoke: Destination and Account must not be equal',
)
}
}

View File

@@ -1,30 +1,5 @@
import { Amount } from '../common'
export interface HookExecution {
HookExecution: {
HookAccount: string
HookEmitCount: number
HookExecutionIndex: number
HookHash: string
HookInstructionCount: string
HookResult: number
HookReturnCode: string
HookReturnString: string
HookStateChangeCount: number
}
}
export interface HookEmission {
HookEmission: {
EmitGeneration: number
EmitBurden: string
EmitParentTxnID: string
EmitNonce: string
EmitCallback: string
EmitHookHash: string
}
}
export interface CreatedNode {
CreatedNode: {
LedgerEntryType: string
@@ -85,8 +60,6 @@ export function isDeletedNode(node: Node): node is DeletedNode {
}
export interface TransactionMetadata {
HookExecutions?: HookExecution[]
HookEmissions?: HookEmission[]
AffectedNodes: Node[]
DeliveredAmount?: Amount
// "unavailable" possible for transactions before 2014-01-20

View File

@@ -1,13 +1,7 @@
/* eslint-disable complexity -- Necessary for validatePaymentChannelClaim */
import { ValidationError } from '../../errors'
import { Amount } from '../common'
import {
BaseTransaction,
GlobalFlags,
validateBaseTransaction,
isAmount,
} from './common'
import { BaseTransaction, GlobalFlags, validateBaseTransaction } from './common'
/**
* Enum representing values for PaymentChannelClaim transaction flags.
@@ -24,15 +18,15 @@ export enum PaymentChannelClaimFlags {
/**
* Request to close the channel. Only the channel source and destination
* addresses can use this flag. This flag closes the channel immediately if it
* has no more funds allocated to it after processing the current claim, or if
* has no more XRP allocated to it after processing the current claim, or if
* the destination address uses it. If the source address uses this flag when
* the channel still holds an amount, this schedules the channel to close after
* the channel still holds XRP, this schedules the channel to close after
* SettleDelay seconds have passed. (Specifically, this sets the Expiration of
* the channel to the close time of the previous ledger plus the channel's
* SettleDelay time, unless the channel already has an earlier Expiration
* time.) If the destination address uses this flag when the channel still
* holds an amount, any amount that remains after processing the claim is
* returned to the source address.
* holds XRP, any XRP that remains after processing the claim is returned to
* the source address.
*/
tfClose = 0x00020000,
}
@@ -84,21 +78,21 @@ export interface PaymentChannelClaimFlagsInterface extends GlobalFlags {
/**
* Request to close the channel. Only the channel source and destination
* addresses can use this flag. This flag closes the channel immediately if it
* has no more funds allocated to it after processing the current claim, or if
* has no more XRP allocated to it after processing the current claim, or if
* the destination address uses it. If the source address uses this flag when
* the channel still holds an amount, this schedules the channel to close after
* the channel still holds XRP, this schedules the channel to close after
* SettleDelay seconds have passed. (Specifically, this sets the Expiration of
* the channel to the close time of the previous ledger plus the channel's
* SettleDelay time, unless the channel already has an earlier Expiration
* time.) If the destination address uses this flag when the channel still
* holds an amount, any amount that remains after processing the claim is
* returned to the source address.
* holds XRP, any XRP that remains after processing the claim is returned to
* the source address.
*/
tfClose?: boolean
}
/**
* Claim amount from a payment channel, adjust the payment channel's expiration,
* Claim XRP from a payment channel, adjust the payment channel's expiration,
* or both.
*
* @category Transaction Models
@@ -109,18 +103,18 @@ export interface PaymentChannelClaim extends BaseTransaction {
/** The unique ID of the channel as a 64-character hexadecimal string. */
Channel: string
/**
* Total amount delivered by this channel after processing this claim. Required
* to deliver amount. Must be more than the total amount delivered by the channel
* so far, but not greater than the Amount of the signed claim. Must be provided
* except when closing the channel.
* Total amount of XRP, in drops, delivered by this channel after processing
* this claim. Required to deliver XRP. Must be more than the total amount
* delivered by the channel so far, but not greater than the Amount of the
* signed claim. Must be provided except when closing the channel.
*/
Balance?: Amount
Balance?: string
/**
* The amount authorized by the Signature. This must match the amount in the
* signed message. This is the cumulative amount that can be dispensed by the
* channel, including amounts previously redeemed. Required unless closing the channel.
* The amount of XRP, in drops, authorized by the Signature. This must match
* the amount in the signed message. This is the cumulative amount of XRP that
* can be dispensed by the channel, including XRP previously redeemed.
*/
Amount?: Amount
Amount?: string
/**
* The signature of this claim, as hexadecimal. The signed message contains
* the channel ID and the amount of the claim. Required unless the sender of
@@ -153,12 +147,12 @@ export function validatePaymentChannelClaim(tx: Record<string, unknown>): void {
throw new ValidationError('PaymentChannelClaim: Channel must be a string')
}
if (tx.Balance !== undefined && !isAmount(tx.Balance)) {
throw new ValidationError('PaymentChannelClaim: Balance must be an Amount')
if (tx.Balance !== undefined && typeof tx.Balance !== 'string') {
throw new ValidationError('PaymentChannelClaim: Balance must be a string')
}
if (tx.Amount !== undefined && !isAmount(tx.Amount)) {
throw new ValidationError('PaymentChannelClaim: Amount must be an Amount')
if (tx.Amount !== undefined && typeof tx.Amount !== 'string') {
throw new ValidationError('PaymentChannelClaim: Amount must be a string')
}
if (tx.Signature !== undefined && typeof tx.Signature !== 'string') {

View File

@@ -1,11 +1,10 @@
/* eslint-disable complexity -- Necessary for validatePaymentChannelCreate */
import { ValidationError } from '../../errors'
import { Amount } from '../common'
import { BaseTransaction, validateBaseTransaction, isAmount } from './common'
import { BaseTransaction, validateBaseTransaction } from './common'
/**
* Create a unidirectional channel and fund it. The address sending
* Create a unidirectional channel and fund it with XRP. The address sending
* this transaction becomes the "source address" of the payment channel.
*
* @category Transaction Models
@@ -13,20 +12,20 @@ import { BaseTransaction, validateBaseTransaction, isAmount } from './common'
export interface PaymentChannelCreate extends BaseTransaction {
TransactionType: 'PaymentChannelCreate'
/**
* Amount to deduct from the sender's balance and set aside in this channel.
* While the channel is open, the amount can only go to the Destination
* address. When the channel closes, any unclaimed amount is returned to
* the source address's balance.
* Amount of XRP, in drops, to deduct from the sender's balance and set aside
* in this channel. While the channel is open, the XRP can only go to the
* Destination address. When the channel closes, any unclaimed XRP is returned
* to the source address's balance.
*/
Amount: Amount
Amount: string
/**
* Address to receive claims against this channel. This is also known as
* Address to receive XRP claims against this channel. This is also known as
* the "destination address" for the channel.
*/
Destination: string
/**
* Amount of time the source address must wait before closing the channel if
* it has unclaimed amount.
* it has unclaimed XRP.
*/
SettleDelay: number
/**
@@ -66,8 +65,8 @@ export function validatePaymentChannelCreate(
throw new ValidationError('PaymentChannelCreate: missing Amount')
}
if (typeof tx.Amount !== 'string' && !isAmount(tx.Amount)) {
throw new ValidationError('PaymentChannelCreate: Amount must be an Amount')
if (typeof tx.Amount !== 'string') {
throw new ValidationError('PaymentChannelCreate: Amount must be a string')
}
if (tx.Destination === undefined) {

View File

@@ -1,10 +1,9 @@
import { ValidationError } from '../../errors'
import { Amount } from '../common'
import { BaseTransaction, validateBaseTransaction, isAmount } from './common'
import { BaseTransaction, validateBaseTransaction } from './common'
/**
* Add additional amount to an open payment channel, and optionally update the
* Add additional XRP to an open payment channel, and optionally update the
* expiration time of the channel. Only the source address of the channel can
* use this transaction.
*
@@ -18,15 +17,16 @@ export interface PaymentChannelFund extends BaseTransaction {
*/
Channel: string
/**
* Amount to add to the channel. Must be a positive amount
* Amount of XRP in drops to add to the channel. Must be a positive amount
* of XRP.
*/
Amount: Amount
Amount: string
/**
* New Expiration time to set for the channel in seconds since the Ripple
* Epoch. This must be later than either the current time plus the SettleDelay
* of the channel, or the existing Expiration of the channel. After the
* Expiration time, any transaction that would access the channel closes the
* channel without taking its normal action. Any unspent amount is returned to
* channel without taking its normal action. Any unspent XRP is returned to
* the source address when the channel closes. (Expiration is separate from
* the channel's immutable CancelAfter time.) For more information, see the
* PayChannel ledger object type.
@@ -55,8 +55,8 @@ export function validatePaymentChannelFund(tx: Record<string, unknown>): void {
throw new ValidationError('PaymentChannelFund: missing Amount')
}
if (typeof tx.Amount !== 'string' && !isAmount(tx.Amount)) {
throw new ValidationError('PaymentChannelFund: Amount must be an Amount')
if (typeof tx.Amount !== 'string') {
throw new ValidationError('PaymentChannelFund: Amount must be a string')
}
if (tx.Expiration !== undefined && typeof tx.Expiration !== 'number') {

View File

@@ -1,81 +0,0 @@
import { ValidationError } from '../../errors'
import { Hook } from '../common'
import { BaseTransaction, GlobalFlags, validateBaseTransaction } from './common'
/**
* Enum representing values for Set Hook Transaction Flags.
*
* @category Transaction Flags
*/
export enum SetHookFlags {
/**
*/
hsfOverride = 0x00000001,
/**
*/
hsfNSDelete = 0x0000002,
/**
*/
hsfCollect = 0x00000004,
}
export interface SetHookFlagsInterface extends GlobalFlags {
hsfOverride?: boolean
hsfNSDelete?: boolean
hsfCollect?: boolean
}
/**
*
*
* @category Transaction Models
*/
export interface SetHook extends BaseTransaction {
TransactionType: 'SetHook'
/**
*
*/
Hooks: Hook[]
Flags?: number | SetHookFlagsInterface
}
const MAX_HOOKS = 10
const HEX_REGEX = /^[0-9A-Fa-f]{64}$/u
/**
* Verify the form and type of an SetHook at runtime.
*
* @param tx - An SetHook Transaction.
* @throws When the SetHook is Malformed.
*/
export function validateSetHook(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)
if (!Array.isArray(tx.Hooks)) {
throw new ValidationError('SetHook: invalid Hooks')
}
if (tx.Hooks.length > MAX_HOOKS) {
throw new ValidationError(
`SetHook: maximum of ${MAX_HOOKS} hooks allowed in Hooks`,
)
}
for (const hook of tx.Hooks) {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Should be a Hook
const hookObject = hook as Hook
const { HookOn, HookNamespace } = hookObject.Hook
if (HookOn !== undefined && !HEX_REGEX.test(HookOn)) {
throw new ValidationError(
`SetHook: HookOn in Hook must be a 256-bit (32-byte) hexadecimal value`,
)
}
if (HookNamespace !== undefined && !HEX_REGEX.test(HookNamespace)) {
throw new ValidationError(
`SetHook: HookNamespace in Hook must be a 256-bit (32-byte) hexadecimal value`,
)
}
}
}

View File

@@ -23,7 +23,7 @@ export interface SignerListSet extends BaseTransaction {
* more than 32 members. No address may appear more than once in the list, nor
* may the Account submitting the transaction appear in the list.
*/
SignerEntries?: SignerEntry[]
SignerEntries: SignerEntry[]
}
const MAX_SIGNERS = 32
@@ -36,7 +36,6 @@ const HEX_WALLET_LOCATOR_REGEX = /^[0-9A-Fa-f]{64}$/u
* @param tx - An SignerListSet Transaction.
* @throws When the SignerListSet is Malformed.
*/
// eslint-disable-next-line complexity -- validation can be complex
export function validateSignerListSet(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)
@@ -48,10 +47,6 @@ export function validateSignerListSet(tx: Record<string, unknown>): void {
throw new ValidationError('SignerListSet: invalid SignerQuorum')
}
if (tx.SignerQuorum === 0) {
return
}
if (tx.SignerEntries === undefined) {
throw new ValidationError('SignerListSet: missing field SignerEntries')
}

View File

@@ -9,13 +9,10 @@ import { AccountSet, validateAccountSet } from './accountSet'
import { CheckCancel, validateCheckCancel } from './checkCancel'
import { CheckCash, validateCheckCash } from './checkCash'
import { CheckCreate, validateCheckCreate } from './checkCreate'
import { ClaimReward, validateClaimReward } from './claimReward'
import { DepositPreauth, validateDepositPreauth } from './depositPreauth'
import { EscrowCancel, validateEscrowCancel } from './escrowCancel'
import { EscrowCreate, validateEscrowCreate } from './escrowCreate'
import { EscrowFinish, validateEscrowFinish } from './escrowFinish'
import { Import, validateImport } from './import'
import { Invoke, validateInvoke } from './invoke'
import { TransactionMetadata } from './metadata'
import {
NFTokenAcceptOffer,
@@ -46,22 +43,10 @@ import {
PaymentChannelFund,
validatePaymentChannelFund,
} from './paymentChannelFund'
import { SetHook, validateSetHook } from './setHook'
import { SetRegularKey, validateSetRegularKey } from './setRegularKey'
import { SignerListSet, validateSignerListSet } from './signerListSet'
import { TicketCreate, validateTicketCreate } from './ticketCreate'
import { TrustSet, validateTrustSet } from './trustSet'
import { URITokenBurn, validateURITokenBurn } from './uriTokenBurn'
import { URITokenBuy, validateURITokenBuy } from './uriTokenBuy'
import {
URITokenCancelSellOffer,
validateURITokenCancelSellOffer,
} from './uriTokenCancelSellOffer'
import {
URITokenCreateSellOffer,
validateURITokenCreateSellOffer,
} from './uriTokenCreateSellOffer'
import { URITokenMint, validateURITokenMint } from './uriTokenMint'
/**
* @category Transaction Models
@@ -72,13 +57,10 @@ export type Transaction =
| CheckCancel
| CheckCash
| CheckCreate
| ClaimReward
| DepositPreauth
| EscrowCancel
| EscrowCreate
| EscrowFinish
| Import
| Invoke
| NFTokenAcceptOffer
| NFTokenBurn
| NFTokenCancelOffer
@@ -90,16 +72,10 @@ export type Transaction =
| PaymentChannelClaim
| PaymentChannelCreate
| PaymentChannelFund
| SetHook
| SetRegularKey
| SignerListSet
| TicketCreate
| TrustSet
| URITokenBurn
| URITokenBuy
| URITokenCancelSellOffer
| URITokenMint
| URITokenCreateSellOffer
/**
* @category Transaction Models
@@ -148,10 +124,6 @@ export function validate(transaction: Record<string, unknown>): void {
validateCheckCreate(tx)
break
case 'ClaimReward':
validateClaimReward(tx)
break
case 'DepositPreauth':
validateDepositPreauth(tx)
break
@@ -168,14 +140,6 @@ export function validate(transaction: Record<string, unknown>): void {
validateEscrowFinish(tx)
break
case 'Import':
validateImport(tx)
break
case 'Invoke':
validateInvoke(tx)
break
case 'NFTokenAcceptOffer':
validateNFTokenAcceptOffer(tx)
break
@@ -224,10 +188,6 @@ export function validate(transaction: Record<string, unknown>): void {
validateSetRegularKey(tx)
break
case 'SetHook':
validateSetHook(tx)
break
case 'SignerListSet':
validateSignerListSet(tx)
break
@@ -240,26 +200,6 @@ export function validate(transaction: Record<string, unknown>): void {
validateTrustSet(tx)
break
case 'URITokenMint':
validateURITokenMint(tx)
break
case 'URITokenBurn':
validateURITokenBurn(tx)
break
case 'URITokenCreateSellOffer':
validateURITokenCreateSellOffer(tx)
break
case 'URITokenBuy':
validateURITokenBuy(tx)
break
case 'URITokenCancelSellOffer':
validateURITokenCancelSellOffer(tx)
break
default:
throw new ValidationError(
`Invalid field TransactionType: ${tx.TransactionType}`,

View File

@@ -1,60 +0,0 @@
import { ValidationError } from '../../errors'
import { BaseTransaction, validateBaseTransaction } from './common'
/**
* Map of flags to boolean values representing {@link URITokenBurn} transaction
* flags.
*
* @category Transaction Flags
*
* @example
* ```typescript
* const tx: URITokenBurn = {
* Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd',
* URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB',
* TransactionType: 'URITokenBurn',
* }
*
* // Autofill the tx to see how flags actually look compared to the interface usage.
* const autofilledTx = await client.autofill(tx)
* console.log(autofilledTx)
* // {
* // Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd',
* // URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB',
* // TransactionType: 'URITokenBurn',
* // Sequence: 21970384,
* // Fee: '12',
* // LastLedgerSequence: 21970404
* // }
* ```
*/
/**
* An URITokenBurn transaction is effectively a limit order . It defines an
* intent to exchange currencies, and creates an Offer object if not completely.
* Fulfilled when placed. Offers can be partially fulfilled.
*
* @category Transaction Models
*/
export interface URITokenBurn extends BaseTransaction {
TransactionType: 'URITokenBurn'
/**
* Identifies the URIToken object to be removed by the transaction.
*/
URITokenID: string
}
/**
* Verify the form and type of an URITokenBurn at runtime.
*
* @param tx - An URITokenBurn Transaction.
* @throws When the URITokenBurn is Malformed.
*/
export function validateURITokenBurn(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)
if (tx.URITokenID == null) {
throw new ValidationError('NFTokenBurn: missing field URITokenID')
}
}

View File

@@ -1,83 +0,0 @@
import { ValidationError } from '../../errors'
import { Amount } from '../common'
import { BaseTransaction, isAmount, validateBaseTransaction } from './common'
/**
* Map of flags to boolean values representing {@link URITokenBuy} transaction
* flags.
*
* @category Transaction Flags
*
* @example
* ```typescript
* const tx: URITokenBuy = {
* Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd',
* URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB',
* Amount: '1000000',
* TransactionType: 'URITokenBuy',
* }
*
* // Autofill the tx to see how flags actually look compared to the interface usage.
* const autofilledTx = await client.autofill(tx)
* console.log(autofilledTx)
* // {
* // Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd',
* // URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB',
* // Amount: '1000000',
* // TransactionType: 'URITokenBuy',
* // Sequence: 21970384,
* // Fee: '12',
* // LastLedgerSequence: 21970404
* // }
* ```
*/
/**
* An URITokenBuy transaction is effectively a limit order . It defines an
* intent to exchange currencies, and creates an Offer object if not completely.
* Fulfilled when placed. Offers can be partially fulfilled.
*
* @category Transaction Models
*/
export interface URITokenBuy extends BaseTransaction {
TransactionType: 'URITokenBuy'
/**
* Identifies the URITokenID of the NFToken object that the
* offer references.
*/
URITokenID: string
/**
* Indicates the amount expected or offered for the Token.
*
* The amount must be non-zero, except when this is a sell
* offer and the asset is XRP. This would indicate that the current
* owner of the token is giving it away free, either to anyone at all,
* or to the account identified by the Destination field.
*/
Amount: Amount
}
/**
* Verify the form and type of an URITokenBuy at runtime.
*
* @param tx - An URITokenBuy Transaction.
* @throws When the URITokenBuy is Malformed.
*/
export function validateURITokenBuy(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)
if (tx.Account === tx.Destination) {
throw new ValidationError(
'URITokenBuy: Destination and Account must not be equal',
)
}
if (tx.URITokenID == null) {
throw new ValidationError('URITokenBuy: missing field URITokenID')
}
if (!isAmount(tx.Amount)) {
throw new ValidationError('URITokenBuy: invalid Amount')
}
}

View File

@@ -1,65 +0,0 @@
import { ValidationError } from '../../errors'
import { BaseTransaction, validateBaseTransaction } from './common'
/**
* Map of flags to boolean values representing {@link URITokenCancelSellOffer} transaction
* flags.
*
* @category Transaction Flags
*
* @example
* ```typescript
* const tx: URITokenCancelSellOffer = {
* Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd',
* URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB',
* TransactionType: 'URITokenCancelSellOffer',
* }
*
* // Autofill the tx to see how flags actually look compared to the interface usage.
* const autofilledTx = await client.autofill(tx)
* console.log(autofilledTx)
* // {
* // Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd',
* // URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB',
* // TransactionType: 'URITokenCancelSellOffer',
* // Sequence: 21970384,
* // Fee: '12',
* // LastLedgerSequence: 21970404
* // }
* ```
*/
/**
* An URITokenCancelSellOffer transaction is effectively a limit order . It defines an
* intent to exchange currencies, and creates an Offer object if not completely.
* Fulfilled when placed. Offers can be partially fulfilled.
*
* @category Transaction Models
*/
export interface URITokenCancelSellOffer extends BaseTransaction {
TransactionType: 'URITokenCancelSellOffer'
/**
* Identifies the URITokenID of the NFToken object that the
* offer references.
*/
URITokenID: string
}
/**
* Verify the form and type of an URITokenCancelSellOffer at runtime.
*
* @param tx - An URITokenCancelSellOffer Transaction.
* @throws When the URITokenCancelSellOffer is Malformed.
*/
export function validateURITokenCancelSellOffer(
tx: Record<string, unknown>,
): void {
validateBaseTransaction(tx)
if (tx.URITokenID == null) {
throw new ValidationError(
'URITokenCancelSellOffer: missing field URITokenID',
)
}
}

View File

@@ -1,93 +0,0 @@
import { ValidationError } from '../../errors'
import { Amount } from '../common'
import { BaseTransaction, isAmount, validateBaseTransaction } from './common'
/**
* Map of flags to boolean values representing {@link URITokenCreateSellOffer} transaction
* flags.
*
* @category Transaction Flags
*
* @example
* ```typescript
* const tx: URITokenCreateSellOffer = {
* Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd',
* URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB',
* Amount: '1000000',
* TransactionType: 'URITokenCreateSellOffer',
* }
*
* // Autofill the tx to see how flags actually look compared to the interface usage.
* const autofilledTx = await client.autofill(tx)
* console.log(autofilledTx)
* // {
* // Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd',
* // URITokenID: '7AFCE32EBA8BD310CC2D00BE10B76E2183337EA20444D4580E4DBDB396C101FB',
* // Amount: '1000000',
* // TransactionType: 'URITokenCreateSellOffer',
* // Sequence: 21970384,
* // Fee: '12',
* // LastLedgerSequence: 21970404
* // }
* ```
*/
/**
* An URITokenCreateSellOffer transaction is effectively a limit order . It defines an
* intent to exchange currencies, and creates an Offer object if not completely.
* Fulfilled when placed. Offers can be partially fulfilled.
*
* @category Transaction Models
*/
export interface URITokenCreateSellOffer extends BaseTransaction {
TransactionType: 'URITokenCreateSellOffer'
/**
* Identifies the URITokenID of the NFToken object that the
* offer references.
*/
URITokenID: string
/**
* Indicates the amount expected or offered for the Token.
*
* The amount must be non-zero, except when this is a sell
* offer and the asset is XRP. This would indicate that the current
* owner of the token is giving it away free, either to anyone at all,
* or to the account identified by the Destination field.
*/
Amount: Amount
/**
* If present, indicates that this offer may only be
* accepted by the specified account. Attempts by other
* accounts to accept this offer MUST fail.
*/
Destination?: string
}
/**
* Verify the form and type of an URITokenCreateSellOffer at runtime.
*
* @param tx - An URITokenCreateSellOffer Transaction.
* @throws When the URITokenCreateSellOffer is Malformed.
*/
export function validateURITokenCreateSellOffer(
tx: Record<string, unknown>,
): void {
validateBaseTransaction(tx)
if (tx.Account === tx.Destination) {
throw new ValidationError(
'URITokenCreateSellOffer: Destination and Account must not be equal',
)
}
if (tx.URITokenID == null) {
throw new ValidationError(
'URITokenCreateSellOffer: missing field URITokenID',
)
}
if (!isAmount(tx.Amount)) {
throw new ValidationError('URITokenCreateSellOffer: invalid Amount')
}
}

View File

@@ -1,110 +0,0 @@
import { ValidationError } from '../../errors'
import { Amount } from '../common'
import { isHex } from '../utils'
import { BaseTransaction, GlobalFlags, validateBaseTransaction } from './common'
/**
* Transaction Flags for an URITokenMint Transaction.
*
* @category Transaction Flags
*/
export enum URITokenMintFlags {
/**
* If set, indicates that the minted token may be burned by the issuer even
* if the issuer does not currently hold the token. The current holder of
* the token may always burn it.
*/
tfBurnable = 0x00000001,
}
/**
* Map of flags to boolean values representing {@link URITokenMint} transaction
* flags.
*
* @category Transaction Flags
*
* @example
* ```typescript
* const tx: URITokenMint = {
* Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd',
* URI: '697066733A2F2F434944',
* TransactionType: 'URITokenMint',
* Flags: {
* tfBurnable: true,
* },
* }
*
* // Autofill the tx to see how flags actually look compared to the interface usage.
* const autofilledTx = await client.autofill(tx)
* console.log(autofilledTx)
* // {
* // Account: 'rhFcpWDHLqpBmX4ezWiA5VLSS4e1BHqhHd',
* // URI: '697066733A2F2F434944',
* // TransactionType: 'URITokenMint',
* // Flags: 0,
* // Sequence: 21970384,
* // Fee: '12',
* // LastLedgerSequence: 21970404
* // }
* ```
*/
export interface URITokenMintFlagsInterface extends GlobalFlags {
tfBurnable?: boolean
}
/**
* An URITokenMint transaction is effectively a limit order . It defines an
* intent to exchange currencies, and creates an Offer object if not completely.
* Fulfilled when placed. Offers can be partially fulfilled.
*
* @category Transaction Models
*/
export interface URITokenMint extends BaseTransaction {
TransactionType: 'URITokenMint'
Flags?: number | URITokenMintFlagsInterface
/**
* URI that points to the data and/or metadata associated with the NFT.
* This field need not be an HTTP or HTTPS URL; it could be an IPFS URI, a
* magnet link, immediate data encoded as an RFC2379 "data" URL, or even an
* opaque issuer-specific encoding. The URI is NOT checked for validity, but
* the field is limited to a maximum length of 256 bytes.
*
* This field must be hex-encoded. You can use `convertStringToHex` to
* convert this field to the proper encoding.
*/
URI: string
/**
* Indicates the amount expected or offered for the Token.
*
* The amount must be non-zero, except when this is a sell
* offer and the asset is XRP. This would indicate that the current
* owner of the token is giving it away free, either to anyone at all,
* or to the account identified by the Destination field.
*/
Amount?: Amount
/**
* If present, indicates that this offer may only be
* accepted by the specified account. Attempts by other
* accounts to accept this offer MUST fail.
*/
Destination?: string
Digest?: string
}
/**
* Verify the form and type of an URITokenMint at runtime.
*
* @param tx - An URITokenMint Transaction.
* @throws When the URITokenMint is Malformed.
*/
export function validateURITokenMint(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)
if (typeof tx.URI === 'string' && !isHex(tx.URI)) {
throw new ValidationError('URITokenMint: URI must be in hex format')
}
}

View File

@@ -2,7 +2,6 @@
/* eslint-disable no-bitwise -- flags require bitwise operations */
import { ValidationError } from '../../errors'
import { Hook } from '../common'
import {
AccountRootFlagsInterface,
AccountRootFlags,
@@ -21,7 +20,6 @@ import {
PaymentChannelClaimFlagsInterface,
PaymentChannelClaimFlags,
} from '../transactions/paymentChannelClaim'
import { SetHookFlagsInterface, SetHookFlags } from '../transactions/setHook'
import type { Transaction } from '../transactions/transaction'
import { TrustSetFlagsInterface, TrustSetFlags } from '../transactions/trustSet'
@@ -77,15 +75,6 @@ export function setTransactionFlagsToNumber(tx: Transaction): void {
case 'TrustSet':
tx.Flags = convertTrustSetFlagsToNumber(tx.Flags)
return
case 'SetHook':
tx.Flags = convertSetHookFlagsToNumber(tx.Flags)
tx.Hooks.forEach((hook: Hook) => {
hook.Hook.Flags = convertSetHookFlagsToNumber(
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- idk
hook.Hook.Flags as SetHookFlagsInterface,
)
})
return
default:
tx.Flags = 0
}
@@ -119,10 +108,6 @@ function convertTrustSetFlagsToNumber(flags: TrustSetFlagsInterface): number {
return reduceFlags(flags, TrustSetFlags)
}
function convertSetHookFlagsToNumber(flags: SetHookFlagsInterface): number {
return reduceFlags(flags, SetHookFlags)
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- added ValidationError check for flagEnum
function reduceFlags(flags: GlobalFlags, flagEnum: any): number {
return Object.keys(flags).reduce((resultFlags, flag) => {

View File

@@ -1,20 +1,17 @@
import {
xAddressToClassicAddress,
isValidXAddress,
} from '@transia/ripple-address-codec'
import { encode } from '@transia/ripple-binary-codec'
import BigNumber from 'bignumber.js'
import { xAddressToClassicAddress, isValidXAddress } from 'ripple-address-codec'
import type { Client } from '..'
import { ValidationError, XrplError } from '../errors'
import { AccountInfoRequest, AccountObjectsRequest } from '../models/methods'
import { Transaction } from '../models/transactions'
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
const LEDGER_OFFSET = 20
const RESTRICTED_NETWORKS = 1024
interface ClassicAccountAndTag {
classicAccount: string
tag: number | false | undefined
@@ -42,25 +39,22 @@ async function autofill<T extends Transaction>(
setValidAddresses(tx)
setTransactionFlagsToNumber(tx)
const promises: Array<Promise<void>> = []
if (this.networkID > RESTRICTED_NETWORKS && tx.NetworkID == null) {
tx.NetworkID = this.networkID
}
if (tx.Sequence == null) {
promises.push(setNextValidSequenceNumber(this, tx))
}
if (tx.Fee == null) {
promises.push(calculateFeePerTransactionType(this, tx, signersCount))
}
if (tx.LastLedgerSequence == null) {
promises.push(setLatestValidatedLedgerSequence(this, tx))
}
if (tx.TransactionType === 'AccountDelete') {
promises.push(checkAccountDeleteBlockers(this, tx))
}
await Promise.all(promises).then(() => tx)
if (tx.Fee == null) {
await calculateFeePerTransactionType(this, tx, signersCount)
}
return tx
return Promise.all(promises).then(() => tx)
}
function setValidAddresses(tx: Transaction): void {
@@ -146,17 +140,64 @@ async function setNextValidSequenceNumber(
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(
client: Client,
tx: Transaction,
signersCount = 0,
): Promise<void> {
const copyTx = { ...tx }
copyTx.SigningPubKey = ``
copyTx.Fee = `0`
const tx_blob = encode(copyTx)
// eslint-disable-next-line require-atomic-updates, no-param-reassign -- ignore
tx.Fee = await getFeeEstimateXrp(client, tx_blob, signersCount)
// netFee is usually 0.00001 XRP (10 drops)
const netFeeXRP = await getFeeXrp(client)
const netFeeDrops = xrpToDrops(netFeeXRP)
let baseFee = new BigNumber(netFeeDrops)
// 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(

View File

@@ -115,7 +115,7 @@ async function getBalances(
formatBalances(response.result.lines),
)
if (xrpBalance !== '') {
balances.push({ currency: 'XAH', value: xrpBalance })
balances.push({ currency: 'XRP', value: xrpBalance })
}
balances.push(...accountLinesBalance)
},

View File

@@ -14,7 +14,7 @@ const BASE_10 = 10
* @param cushion - The fee cushion to use.
* @returns The transaction fee.
*/
export async function getFeeXrp(
export default async function getFeeXrp(
client: Client,
cushion?: number,
): Promise<string> {
@@ -43,27 +43,3 @@ export async function getFeeXrp(
// Round fee to 6 decimal places
return new BigNumber(fee.toFixed(NUM_DECIMAL_PLACES)).toString(BASE_10)
}
/**
* Calculates the estimated transaction fee.
* Note: This is a public API that can be called directly.
*
* @param client - The Client used to connect to the ledger.
* @param txBlob - The encoded transaction to estimate the fee for.
* @param signersCount - The number of multisigners.
* @returns The transaction fee.
*/
export async function getFeeEstimateXrp(
client: Client,
txBlob: string,
signersCount = 0,
): Promise<string> {
const response = await client.request({
command: 'fee',
tx_blob: txBlob,
})
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)
}

View File

@@ -1,15 +0,0 @@
import type { Client } from '..'
// import { XrplError } from '../errors'
/**
* Returns the network ID of the rippled server.
*
* @param this - The Client used to connect to the ledger.
* @returns The network id.
*/
export default async function getNetworkID(this: Client): Promise<number> {
const response = await this.request({
command: 'server_info',
})
return response.result.info.network_id ?? 1
}

View File

@@ -5,9 +5,6 @@ export { getBalances, getXrpBalance } from './balances'
export { default as getLedgerIndex } from './getLedgerIndex'
export { default as getOrderbook } from './getOrderbook'
export { getFeeXrp, getFeeEstimateXrp } from './getFeeXrp'
export { default as getNetworkID } from './getNetworkID'
export * from './submit'

View File

@@ -1,4 +1,4 @@
import { decode, encode } from '@transia/ripple-binary-codec'
import { decode, encode } from 'ripple-binary-codec'
import type { Client, SubmitRequest, SubmitResponse, Wallet } from '..'
import { ValidationError, XrplError } from '../errors'

View File

@@ -1,7 +1,4 @@
import {
xAddressToClassicAddress,
isValidXAddress,
} from '@transia/ripple-address-codec'
import { xAddressToClassicAddress, isValidXAddress } from 'ripple-address-codec'
/**
* If an address is an X-Address, converts it to a classic address.

View File

@@ -1,40 +0,0 @@
import { XrplError } from '../errors'
import { Payment } from '../models'
import { Memo } from '../models/common'
import { convertStringToHex } from './stringConversion'
/**
* Creates a cross-chain payment transaction.
*
* @param payment - The initial payment transaction. If the transaction is
* signed, then it will need to be re-signed. There must be no more than 2
* memos, since one memo is used for the sidechain destination account. The
* destination must be the sidechain's door account.
* @param destAccount - the destination account on the sidechain.
* @returns A cross-chain payment transaction, where the mainchain door account
* is the `Destination` and the destination account on the sidechain is encoded
* in the memos.
* @throws XrplError - if there are more than 2 memos.
* @category Utilities
*/
export default function createCrossChainPayment(
payment: Payment,
destAccount: string,
): Payment {
const destAccountHex = convertStringToHex(destAccount)
const destAccountMemo: Memo = { Memo: { MemoData: destAccountHex } }
const memos = payment.Memos ?? []
if (memos.length > 2) {
throw new XrplError(
'Cannot have more than 2 memos in a cross-chain transaction.',
)
}
const newMemos = [destAccountMemo, ...memos]
const newPayment = { ...payment, Memos: newMemos }
delete newPayment.TxnSignature
return newPayment
}

View File

@@ -1,5 +1,5 @@
import { classicAddressToXAddress } from '@transia/ripple-address-codec'
import { deriveKeypair, deriveAddress } from '@transia/ripple-keypairs'
import { classicAddressToXAddress } from 'ripple-address-codec'
import { deriveKeypair, deriveAddress } from 'ripple-keypairs'
/**
* Derive an X-Address from a public key and a destination tag.

View File

@@ -105,7 +105,7 @@ function getXRPQuantity(
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- okay here
account: (node.FinalFields?.Account ?? node.NewFields?.Account) as string,
balance: {
currency: 'XAH',
currency: 'XRP',
value: dropsToXrp(value).toString(),
},
}

View File

@@ -3,8 +3,8 @@
/* eslint-disable no-bitwise -- this file mimics behavior in rippled. It uses
bitwise operators for and-ing numbers with a mask and bit shifting. */
import { decode, encode } from '@transia/ripple-binary-codec'
import BigNumber from 'bignumber.js'
import { decode, encode } from 'ripple-binary-codec'
import { ValidationError, XrplError } from '../../errors'
import type { Ledger } from '../../models/ledger'
@@ -83,11 +83,7 @@ export function hashSignedTx(tx: Transaction | string): string {
txObject = tx
}
if (
!txObject.EmitDetails &&
txObject.TxnSignature === undefined &&
txObject.Signers === undefined
) {
if (txObject.TxnSignature === undefined && txObject.Signers === undefined) {
throw new ValidationError('The transaction must be signed to hash it.')
}

View File

@@ -3,10 +3,8 @@
/* eslint-disable no-bitwise -- this file mimics behavior in rippled. It uses
bitwise operators for and-ing numbers with a mask and bit shifting. */
import { decodeAccountID } from '@transia/ripple-address-codec'
import BigNumber from 'bignumber.js'
import { convertStringToHex } from '../stringConversion'
import { decodeAccountID } from 'ripple-address-codec'
import hashLedger, {
hashLedgerHeader,
@@ -187,17 +185,21 @@ export function hashPaymentChannel(
}
/**
* Compute the Hash of an URIToken LedgerEntry.
* Compute the Hash of an Check LedgerEntry.
*
* @param issuer - Address of the issuer of the URIToken.
* @param uri - string uri of the URIToken (not the hex).
* @returns The hash of the URIToken LedgerEntry.
* @param address - Address of the Check.
* @param sequence - Sequence of the CreateCheck tx.
* @returns The hash of the Check LedgerEntry.
* @category Utilities
*/
export function hashURIToken(issuer: string, uri: string): string {
return sha512Half(
ledgerSpaceHex('uriToken') + addressToHex(issuer) + convertStringToHex(uri),
)
export function hashCheckId(address: string, sequence: number): string {
const hexPrefix = ledgerSpaces.check
.charCodeAt(0)
.toString(HEX)
.padStart(2, '0')
const hexSequence = sequence.toString(HEX).padStart(8, '0')
const prefix = `00${hexPrefix}`
return sha512Half(prefix + addressToHex(address) + hexSequence)
}
export { hashLedgerHeader, hashSignedTx, hashLedger, hashStateTree, hashTxTree }

Some files were not shown because too many files have changed in this diff Show More