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
79 changed files with 2412 additions and 3570 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

@@ -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.
@@ -109,7 +113,7 @@ Warning: Use at your own risk.
- **[XRP Account Mnemonic Recovery](https://github.com/WietseWind/xrp-mnemonic-recovery)** (uses `ripple-keypairs`)
Recover a 24 word mnemonic if one word is wrong or one word is missing.
- **[Trustline](https://trustline.co)**
A decentralized stablecoin wallet that runs on the XRP Ledger.

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
```
@@ -203,7 +216,7 @@ npm uninstall abbrev -w xrpl
1. Actually publish the packages with one of the following:
- Stable release: Run `npx lerna publish from-package --yes`
- Beta release: Run `npx lerna publish from-package --dist-tag beta --yes`
- Beta release: Run `npx lerna publish from-package --dist-tag beta --yes`
Notice this allows developers to install the package with `npm add xrpl@beta`
1. If requested, enter your [npmjs.com](https://npmjs.com) OTP (one-time password) to complete publication.

View File

@@ -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`.

4171
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.1",
"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

@@ -44,16 +44,11 @@
"NegativeUNL": 78,
"NFTokenPage": 80,
"NFTokenOffer": 55,
"URIToken": 85,
"Any": -3,
"Child": -2,
"Nickname": 110,
"Contract": 99,
"GeneratorMap": 103,
"Hook": 72,
"HookState": 118,
"HookDefinition": 68,
"EmittedTxn": 69
"GeneratorMap": 103
},
"FIELDS": [
[
@@ -326,16 +321,6 @@
"type": "UInt16"
}
],
[
"NetworkID",
{
"nth": 1,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt32"
}
],
[
"Flags",
{
@@ -776,36 +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"
}
],
[
"ImportSequence",
{
"nth": 97,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt32"
}
],
[
"IndexNext",
{
@@ -936,6 +891,16 @@
"type": "UInt64"
}
],
[
"HookOn",
{
"nth": 16,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "UInt64"
}
],
[
"HookInstructionCount",
{
@@ -1186,16 +1151,6 @@
"type": "Hash256"
}
],
[
"HookOn",
{
"nth": 20,
"isVLEncoded": false,
"isSerialized": true,
"isSigningField": true,
"type": "Hash256"
}
],
[
"Digest",
{
@@ -1326,36 +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"
}
],
[
"Amount",
{
@@ -1496,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",
{
@@ -1786,16 +1661,6 @@
"type": "Blob"
}
],
[
"Blob",
{
"nth": 26,
"isVLEncoded": true,
"isSerialized": true,
"isSigningField": true,
"type": "Blob"
}
],
[
"Account",
{
@@ -1936,16 +1801,6 @@
"type": "Vector256"
}
],
[
"HookNamespaces",
{
"nth": 5,
"isVLEncoded": true,
"isSerialized": true,
"isSigningField": true,
"type": "Vector256"
}
],
[
"Paths",
{
@@ -2321,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,
@@ -2366,16 +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,
"temHOOK_REJECTED": -252,
"tefFAILURE": -199,
"tefALREADY": -198,
@@ -2398,7 +2237,6 @@
"tefTOO_BIG": -181,
"tefNO_TICKET": -180,
"tefNFTOKEN_IS_NOT_TRANSFERABLE": -179,
"tefPAST_IMPORT_SEQ": -178,
"terRETRY": -99,
"terFUNDS_SPENT": -98,
@@ -2412,8 +2250,6 @@
"terNO_RIPPLE": -90,
"terQUEUED": -89,
"terPRE_TICKET": -88,
"terNO_AMM": -87,
"terNO_HOOK": -86,
"tesSUCCESS": 0,
@@ -2455,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,
@@ -2463,33 +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,
"tecLAST_POSSIBLE_ENTRY": 255
"tecINSUFFICIENT_PAYMENT": 161
},
"TRANSACTION_TYPES": {
"Invalid": -1,
@@ -2521,16 +2330,8 @@
"NFTokenCreateOffer": 27,
"NFTokenCancelOffer": 28,
"NFTokenAcceptOffer": 29,
"URITokenMint": 45,
"URITokenBurn": 46,
"URITokenBuy": 47,
"URITokenCreateSellOffer": 48,
"URITokenCancelSellOffer": 49,
"Import": 97,
"Invoke": 99,
"EnableAmendment": 100,
"SetFee": 101,
"UNLModify": 102,
"EmitFailure": 103
"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

@@ -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,7 +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

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

View File

@@ -1,6 +1,6 @@
{
"name": "@transia/xrpl",
"version": "2.7.3-alpha.1",
"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.1",
"@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,7 +75,7 @@
"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": {

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

@@ -9,20 +9,20 @@ import {
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'
} from 'ripple-keypairs'
import ECDSA from '../ECDSA'
import { ValidationError, XrplError } from '../errors'

View File

@@ -1,13 +1,13 @@
import { BigNumber } from 'bignumber.js'
import { flatMap } from 'lodash'
import { decodeAccountID } from '@transia/ripple-address-codec'
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'
} 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 BigNumber from 'bignumber.js'
import { decode } from '@transia/ripple-binary-codec'
import { decode } from 'ripple-binary-codec'
import type {
AccountTxResponse,

View File

@@ -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.
*/

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,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

@@ -3,12 +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 LedgerHashes from './LedgerHashes'
import NegativeUNL from './NegativeUNL'
import Offer from './Offer'
@@ -23,12 +19,8 @@ type LedgerEntry =
| Check
| DepositPreauth
| DirectoryNode
| EmittedTxn
| Escrow
| FeeSettings
| Hook
| HookDefinition
| HookState
| LedgerHashes
| NegativeUNL
| Offer

View File

@@ -6,12 +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 Ledger from './Ledger'
import LedgerEntry from './LedgerEntry'
import LedgerHashes from './LedgerHashes'
@@ -30,12 +26,8 @@ export {
Check,
DepositPreauth,
DirectoryNode,
EmittedTxn,
Escrow,
FeeSettings,
Hook,
HookDefinition,
HookState,
Ledger,
LedgerEntry,
LedgerHashes,

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

@@ -137,40 +137,6 @@ export interface LedgerEntryRequest extends BaseRequest {
ticket_sequence: number
}
| string
/**
* The object ID of a transaction emitted by the ledger entry.
*/
emitted_txn?: 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
}
}
/**

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'

View File

@@ -1,16 +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,
} from '../common'
import { Amount, IssuedCurrencyAmount, Memo, Signer } from '../common'
import { onlyHasFields } from '../utils'
const MEMO_SIZE = 3
@@ -165,14 +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[]
}
/**
@@ -266,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

@@ -1,24 +0,0 @@
import { BaseTransaction, validateBaseTransaction } from './common'
/**
*
*
* @category Transaction Models
*/
export interface Import extends BaseTransaction {
TransactionType: 'Import'
/**
* 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)
}

View File

@@ -14,8 +14,6 @@ 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'
@@ -44,7 +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'

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,19 +1,5 @@
import { Amount } from '../common'
export interface HookExecution {
HookExecution: {
HookAccount: string
HookEmitCount: number
HookExecutionIndex: number
HookHash: string
HookInstructionCount: string
HookResult: number
HookReturnCode: number
HookReturnString: string
HookStateChangeCount: number
}
}
export interface CreatedNode {
CreatedNode: {
LedgerEntryType: string
@@ -74,7 +60,6 @@ export function isDeletedNode(node: Node): node is DeletedNode {
}
export interface TransactionMetadata {
HookExecutions: HookExecution[]
AffectedNodes: Node[]
DeliveredAmount?: Amount
// "unavailable" possible for transactions before 2014-01-20

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 = 0x00000010,
/**
*/
hsfCollect = 0x00000100,
}
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 = 4
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

@@ -13,8 +13,6 @@ 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,
@@ -45,7 +43,6 @@ 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'
@@ -64,8 +61,6 @@ export type Transaction =
| EscrowCancel
| EscrowCreate
| EscrowFinish
| Import
| Invoke
| NFTokenAcceptOffer
| NFTokenBurn
| NFTokenCancelOffer
@@ -77,7 +72,6 @@ export type Transaction =
| PaymentChannelClaim
| PaymentChannelCreate
| PaymentChannelFund
| SetHook
| SetRegularKey
| SignerListSet
| TicketCreate
@@ -146,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
@@ -202,10 +188,6 @@ export function validate(transaction: Record<string, unknown>): void {
validateSetRegularKey(tx)
break
case 'SetHook':
validateSetHook(tx)
break
case 'SignerListSet':
validateSignerListSet(tx)
break

View File

@@ -20,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'
@@ -76,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((h) => {
h.Hook.Flags = convertSetHookFlagsToNumber(
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- idk
h.Hook.Flags as SetHookFlagsInterface,
)
})
return
default:
tx.Flags = 0
}
@@ -118,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,5 +1,5 @@
import BigNumber from 'bignumber.js'
import { xAddressToClassicAddress, isValidXAddress } from '@transia/ripple-address-codec'
import { xAddressToClassicAddress, isValidXAddress } from 'ripple-address-codec'
import type { Client } from '..'
import { ValidationError, XrplError } from '../errors'
@@ -8,11 +8,10 @@ import { Transaction } from '../models/transactions'
import { setTransactionFlagsToNumber } from '../models/utils/flags'
import { xrpToDrops } from '../utils'
import { getFeeXrp } 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
@@ -40,10 +39,8 @@ 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))
}

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,22 +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.
* @returns The transaction fee.
*/
export async function getFeeEstimateXrp(
client: Client,
txBlob: string,
): Promise<string> {
const response = await client.request({
command: 'fee',
tx_blob: txBlob,
})
return response.result.drops.base_fee
}

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,4 +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

@@ -4,7 +4,7 @@
bitwise operators for and-ing numbers with a mask and bit shifting. */
import BigNumber from 'bignumber.js'
import { decode, encode } from '@transia/ripple-binary-codec'
import { decode, encode } from 'ripple-binary-codec'
import { ValidationError, XrplError } from '../../errors'
import type { Ledger } from '../../models/ledger'

View File

@@ -4,7 +4,7 @@
bitwise operators for and-ing numbers with a mask and bit shifting. */
import BigNumber from 'bignumber.js'
import { decodeAccountID } from '@transia/ripple-address-codec'
import { decodeAccountID } from 'ripple-address-codec'
import hashLedger, {
hashLedgerHeader,
@@ -184,4 +184,22 @@ export function hashPaymentChannel(
)
}
/**
* Compute the Hash of an Check 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 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 }

View File

@@ -1,125 +0,0 @@
/**
* @module tts
* @description
* This module contains the transaction types and the function to calculate the hook on
*/
import {
TRANSACTION_TYPES,
TRANSACTION_TYPE_MAP,
} from '@transia/ripple-binary-codec'
import createHash = require('create-hash')
import { XrplError } from '../errors'
import { HookParameter } from '../models/common'
/**
* @constant tts
* @description
* Transaction types
*/
/**
* @typedef TTS
* @description
* Transaction types
*/
export type TTS = typeof TRANSACTION_TYPE_MAP
/**
* Calculate the hook on
*
* @param arr - array of transaction types
* @returns the hook on
*/
export function calculateHookOn(arr: Array<keyof TTS>): string {
let hash =
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff'
arr.forEach((nth) => {
if (typeof nth !== 'string') {
throw new XrplError(`HookOn transaction type must be string`)
}
if (!TRANSACTION_TYPES.includes(String(nth))) {
throw new XrplError(
`invalid transaction type '${String(nth)}' in HookOn array`,
)
}
const tts: Record<string, number> = TRANSACTION_TYPE_MAP
let value = BigInt(hash)
// eslint-disable-next-line no-bitwise -- Required
value ^= BigInt(1) << BigInt(tts[nth])
// eslint-disable-next-line @typescript-eslint/no-magic-numbers -- Required
hash = `0x${value.toString(16)}`
})
hash = hash.replace('0x', '')
// eslint-disable-next-line @typescript-eslint/no-magic-numbers -- Required
hash = hash.padStart(64, '0')
return hash.toUpperCase()
}
/**
* Calculate the sha256 of a string
*
* @param string - the string to calculate the sha256
* @returns the sha256
*/
export async function sha256(string: string): Promise<string> {
const hash = createHash('sha256')
hash.update(string)
const hashBuffer = hash.digest()
const hashArray = Array.from(new Uint8Array(hashBuffer))
const hashHex = hashArray
// eslint-disable-next-line @typescript-eslint/no-magic-numbers -- Required
.map((bytes) => bytes.toString(16).padStart(2, '0'))
.join('')
return hashHex
}
/**
* Calculate the hex of a namespace
*
* @param namespace - the namespace to calculate the hex
* @returns the hex
*/
export async function hexNamespace(namespace: string): Promise<string> {
return (await sha256(namespace)).toUpperCase()
}
function isHex(value: string): boolean {
return /^[0-9A-F]+$/iu.test(value)
}
function hexValue(value: string): string {
return Buffer.from(value, 'utf8').toString('hex').toUpperCase()
}
/**
* Calculate the hex of the hook parameters
*
* @param data - the hook parameters
* @returns the hex of the hook parameters
*/
export function hexHookParameters(data: HookParameter[]): HookParameter[] {
const hookParameters: HookParameter[] = []
for (const parameter of data) {
let hookPName = parameter.HookParameter.HookParameterName
let hookPValue = parameter.HookParameter.HookParameterValue
if (!isHex(hookPName)) {
hookPName = hexValue(hookPName)
}
if (!isHex(hookPValue)) {
hookPValue = hexValue(hookPValue)
}
hookParameters.push({
HookParameter: {
HookParameterName: hookPName,
HookParameterValue: hookPValue,
},
})
}
return hookParameters
}

View File

@@ -13,16 +13,15 @@ import {
isValidClassicAddress,
isValidXAddress,
xAddressToClassicAddress,
} from '@transia/ripple-address-codec'
import * as rbc from '@transia/ripple-binary-codec'
import { verify as verifyKeypairSignature } from '@transia/ripple-keypairs'
} from 'ripple-address-codec'
import * as rbc from 'ripple-binary-codec'
import { verify as verifyKeypairSignature } from 'ripple-keypairs'
import { LedgerEntry } from '../models/ledger'
import { Response } from '../models/methods'
import { PaymentChannelClaim } from '../models/transactions/paymentChannelClaim'
import { Transaction } from '../models/transactions/transaction'
import createCrossChainPayment from './createCrossChainPayment'
import { deriveKeypair, deriveAddress, deriveXAddress } from './derive'
import getBalanceChanges from './getBalanceChanges'
import getNFTokenID from './getNFTokenID'
@@ -40,7 +39,6 @@ import {
hashEscrow,
hashPaymentChannel,
} from './hashes'
import { calculateHookOn, hexNamespace, hexHookParameters, TTS } from './hooks'
import parseNFTokenID from './parseNFTokenID'
import {
percentToTransferRate,
@@ -221,10 +219,5 @@ export {
encodeForSigning,
encodeForSigningClaim,
getNFTokenID,
createCrossChainPayment,
parseNFTokenID,
calculateHookOn,
hexNamespace,
hexHookParameters,
TTS,
}

View File

@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-magic-numbers -- Doing hex string parsing. */
import BigNumber from 'bignumber.js'
import { encodeAccountID } from '@transia/ripple-address-codec'
import { encodeAccountID } from 'ripple-address-codec'
import { XrplError } from '../errors'

View File

@@ -1,5 +1,5 @@
import { encodeForSigningClaim } from '@transia/ripple-binary-codec'
import { sign } from '@transia/ripple-keypairs'
import { encodeForSigningClaim } from 'ripple-binary-codec'
import { sign } from 'ripple-keypairs'
import { xrpToDrops } from './xrpConversion'

View File

@@ -1,5 +1,5 @@
import { encodeForSigningClaim } from '@transia/ripple-binary-codec'
import { verify } from '@transia/ripple-keypairs'
import { encodeForSigningClaim } from 'ripple-binary-codec'
import { verify } from 'ripple-keypairs'
import { xrpToDrops } from './xrpConversion'

View File

@@ -1,6 +1,6 @@
import { assert } from 'chai'
import { getFeeXrp } from '../../src/sugar/getFeeXrp'
import getFeeXrp from '../../src/sugar/getFeeXrp'
import rippled from '../fixtures/rippled'
import {
setupClient,

View File

@@ -1,5 +1,7 @@
To run integration tests:
1. Run rippled-standalone node, either in a docker container (preferred) or by installing rippled.
* With docker, run `docker run -p 6006:6006 -it natenichols/rippled-standalone:latest`
* Or [download and build rippled](https://xrpl.org/install-rippled.html) and run `./rippled -a`
1. Run rippled in standalone node, either in a docker container (preferred) or by installing rippled.
* Go to the top-level of the `xrpl.js` repo, just above the `packages` folder.
* With docker, run `docker run -p 6006:6006 --interactive -t --volume $PWD/.ci-config:/config/ xrpllabsofficial/xrpld:latest -a --start`
* Or [download and build rippled](https://xrpl.org/install-rippled.html) and run `./rippled -a --start`
* If you'd like to use the latest rippled amendments, you should modify your `rippled.cfg` file to enable amendments in the `[amendments]` section. You can view `.ci-config/rippled.cfg` in the top level folder as an example of this.
2. Run `npm test:integration` or `npm test:browser`

View File

@@ -61,11 +61,11 @@ describe('server_info (rippled)', function () {
server_state: 'full',
server_state_duration_us: '8752395105',
state_accounting: {
connected: { duration_us: '0', transitions: 0 },
disconnected: { duration_us: '41860', transitions: 1 },
full: { duration_us: '20723121268', transitions: 1 },
syncing: { duration_us: '0', transitions: 0 },
tracking: { duration_us: '0', transitions: 0 },
connected: { duration_us: '0', transitions: '0' },
disconnected: { duration_us: '41860', transitions: '1' },
full: { duration_us: '20723121268', transitions: '1' },
syncing: { duration_us: '0', transitions: '0' },
tracking: { duration_us: '0', transitions: '0' },
},
time: '2021-Sep-23 22:56:55.320858 UTC',
uptime: 8752,
@@ -108,6 +108,9 @@ describe('server_info (rippled)', function () {
'pubkey_node',
'server_state_duration_us',
'validated_ledger',
'build_version',
'node_size',
'initial_sync_duration_us',
]
assert.deepEqual(
omit(response.result.info, removeKeys),
@@ -129,7 +132,7 @@ describe('server_info (rippled)', function () {
)
assert.equal(
typeof response.result.info.state_accounting[key].transitions,
'number',
'string',
)
})

View File

@@ -68,11 +68,11 @@ describe('server_state', function () {
server_state: 'full',
server_state_duration_us: '8752487389',
state_accounting: {
connected: { duration_us: '0', transitions: 0 },
disconnected: { duration_us: '41860', transitions: 1 },
full: { duration_us: '20723121268', transitions: 1 },
syncing: { duration_us: '0', transitions: 0 },
tracking: { duration_us: '0', transitions: 0 },
connected: { duration_us: '0', transitions: '0' },
disconnected: { duration_us: '41860', transitions: '1' },
full: { duration_us: '20723121268', transitions: '1' },
syncing: { duration_us: '0', transitions: '0' },
tracking: { duration_us: '0', transitions: '0' },
},
time: '2021-Sep-23 22:56:55.413151 UTC',
uptime: 8752,
@@ -112,6 +112,9 @@ describe('server_state', function () {
'server_state_duration_us',
'validated_ledger',
'io_latency_ms',
'build_version',
'node_size',
'initial_sync_duration_us',
]
assert.deepEqual(
omit(response.result.state, removeKeys),
@@ -133,7 +136,7 @@ describe('server_state', function () {
)
assert.equal(
typeof response.result.state.state_accounting[key].transitions,
'number',
'string',
)
})

View File

@@ -1,5 +1,5 @@
import { assert } from 'chai'
import { decode } from '@transia/ripple-binary-codec'
import { decode } from 'ripple-binary-codec'
import {
AccountSet,

View File

@@ -1,5 +1,5 @@
import { assert } from 'chai'
import { decode } from '@transia/ripple-binary-codec'
import { decode } from 'ripple-binary-codec'
import {
AccountSet,

View File

@@ -1,7 +1,7 @@
import { assert } from 'chai'
import omit from 'lodash/omit'
import throttle from 'lodash/throttle'
import { decode } from '@transia/ripple-binary-codec'
import { decode } from 'ripple-binary-codec'
import {
Client,

View File

@@ -1,150 +0,0 @@
import { assert } from 'chai'
import { validate, ValidationError } from '../../src'
import { validateSetHook } from '../../src/models/transactions/setHook'
/**
* SetHook Transaction Verification Testing.
*
* Providing runtime verification testing for each specific transaction type.
*/
describe('SetHook', function () {
let setHookTx
beforeEach(function () {
setHookTx = {
Flags: 0,
TransactionType: 'SetHook',
Account: 'rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn',
Fee: '12',
Hooks: [
{
Hook: {
CreateCode:
'0061736D01000000011C0460057F7F7F7F7F017E60037F7F7E017E60027F7F017F60017F017E02230303656E76057472616365000003656E7606616363657074000103656E76025F670002030201030503010002062B077F0141B088040B7F004180080B7F0041A6080B7F004180080B7F0041B088040B7F0041000B7F0041010B07080104686F6F6B00030AC4800001C0800001017F230041106B220124002001200036020C41920841134180084112410010001A410022002000420010011A41012200200010021A200141106A240042000B0B2C01004180080B254163636570742E633A2043616C6C65642E00224163636570742E633A2043616C6C65642E22',
HookOn:
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFF7',
Flags: 1,
HookApiVersion: 0,
HookNamespace:
'4FF9961269BF7630D32E15276569C94470174A5DA79FA567C0F62251AA9A36B9',
},
},
],
} as any
})
it(`verifies valid SetHook`, function () {
assert.doesNotThrow(() => validateSetHook(setHookTx))
assert.doesNotThrow(() => validate(setHookTx))
})
// it(`throws w/ empty Hooks`, function () {
// setHookTx.Hooks = []
// assert.throws(
// () => validateSetHook(setHookTx),
// ValidationError,
// 'SetHook: need at least 1 member in Hooks',
// )
// assert.throws(
// () => validate(setHookTx),
// ValidationError,
// 'SetHook: need at least 1 member in Hooks',
// )
// })
it(`throws w/ invalid Hooks`, function () {
setHookTx.Hooks = 'khgfgyhujk'
assert.throws(
() => validateSetHook(setHookTx),
ValidationError,
'SetHook: invalid Hooks',
)
assert.throws(
() => validate(setHookTx),
ValidationError,
'SetHook: invalid Hooks',
)
})
it(`throws w/ maximum of 4 members allowed in Hooks`, function () {
setHookTx.Hooks = []
const hook = {
Hook: {
CreateCode:
'0061736D01000000011C0460057F7F7F7F7F017E60037F7F7E017E60027F7F017F60017F017E02230303656E76057472616365000003656E7606616363657074000103656E76025F670002030201030503010002062B077F0141B088040B7F004180080B7F0041A6080B7F004180080B7F0041B088040B7F0041000B7F0041010B07080104686F6F6B00030AC4800001C0800001017F230041106B220124002001200036020C41920841134180084112410010001A410022002000420010011A41012200200010021A200141106A240042000B0B2C01004180080B254163636570742E633A2043616C6C65642E00224163636570742E633A2043616C6C65642E22',
HookOn:
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFF7',
Flags: 1,
HookApiVersion: 0,
HookNamespace:
'4FF9961269BF7630D32E15276569C94470174A5DA79FA567C0F62251AA9A36B9',
},
}
setHookTx.Hooks.push(hook)
setHookTx.Hooks.push(hook)
setHookTx.Hooks.push(hook)
setHookTx.Hooks.push(hook)
setHookTx.Hooks.push(hook)
const errorMessage = 'SetHook: maximum of 4 hooks allowed in Hooks'
assert.throws(
() => validateSetHook(setHookTx),
ValidationError,
errorMessage,
)
assert.throws(() => validate(setHookTx), ValidationError, errorMessage)
})
it(`throws w/ invalid HookOn in Hooks`, function () {
setHookTx.SignerQuorum = 2
setHookTx.Hooks = [
{
Hook: {
CreateCode:
'0061736D01000000011C0460057F7F7F7F7F017E60037F7F7E017E60027F7F017F60017F017E02230303656E76057472616365000003656E7606616363657074000103656E76025F670002030201030503010002062B077F0141B088040B7F004180080B7F0041A6080B7F004180080B7F0041B088040B7F0041000B7F0041010B07080104686F6F6B00030AC4800001C0800001017F230041106B220124002001200036020C41920841134180084112410010001A410022002000420010011A41012200200010021A200141106A240042000B0B2C01004180080B254163636570742E633A2043616C6C65642E00224163636570742E633A2043616C6C65642E22',
HookOn: '',
Flags: 1,
HookApiVersion: 0,
HookNamespace:
'4FF9961269BF7630D32E15276569C94470174A5DA79FA567C0F62251AA9A36B9',
},
},
]
const errorMessage =
'SetHook: HookOn in Hook must be a 256-bit (32-byte) hexadecimal value'
assert.throws(
() => validateSetHook(setHookTx),
ValidationError,
errorMessage,
)
assert.throws(() => validate(setHookTx), ValidationError, errorMessage)
})
it(`throws w/ invalid HookNamespace in Hooks`, function () {
setHookTx.SignerQuorum = 2
setHookTx.Hooks = [
{
Hook: {
CreateCode:
'0061736D01000000011C0460057F7F7F7F7F017E60037F7F7E017E60027F7F017F60017F017E02230303656E76057472616365000003656E7606616363657074000103656E76025F670002030201030503010002062B077F0141B088040B7F004180080B7F0041A6080B7F004180080B7F0041B088040B7F0041000B7F0041010B07080104686F6F6B00030AC4800001C0800001017F230041106B220124002001200036020C41920841134180084112410010001A410022002000420010011A41012200200010021A200141106A240042000B0B2C01004180080B254163636570742E633A2043616C6C65642E00224163636570742E633A2043616C6C65642E22',
HookOn:
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFF7',
Flags: 1,
HookApiVersion: 0,
HookNamespace: '',
},
},
]
const errorMessage =
'SetHook: HookNamespace in Hook must be a 256-bit (32-byte) hexadecimal value'
assert.throws(
() => validateSetHook(setHookTx),
ValidationError,
errorMessage,
)
assert.throws(() => validate(setHookTx), ValidationError, errorMessage)
})
})

View File

@@ -1,124 +0,0 @@
import { assert } from 'chai'
import { createCrossChainPayment, convertStringToHex, Payment } from '../../src'
describe('createCrossChainPayment', function () {
it('successful xchain payment creation', function () {
const payment: Payment = {
TransactionType: 'Payment',
Account: 'rRandom',
Destination: 'rRandom2',
Amount: '3489303',
}
const sidechainAccount = 'rSidechain'
const expectedPayment = {
...payment,
Memos: [
{
Memo: {
MemoData: convertStringToHex(sidechainAccount),
},
},
],
}
const resultPayment = createCrossChainPayment(payment, sidechainAccount)
assert.deepEqual(resultPayment, expectedPayment)
// ensure that the original object wasn't modified
assert.notDeepEqual(resultPayment, payment)
})
it('successful xchain payment creation with memo', function () {
const memo = {
Memo: {
MemoData: 'deadbeef',
},
}
const payment: Payment = {
TransactionType: 'Payment',
Account: 'rRandom',
Destination: 'rRandom2',
Amount: '3489303',
Memos: [memo],
}
const sidechainAccount = 'rSidechain'
const expectedPayment = {
...payment,
Memos: [
{
Memo: {
MemoData: convertStringToHex(sidechainAccount),
},
},
memo,
],
}
const resultPayment = createCrossChainPayment(payment, sidechainAccount)
assert.deepEqual(resultPayment, expectedPayment)
// ensure that the original object wasn't modified
assert.notDeepEqual(resultPayment, payment)
})
it('removes TxnSignature', function () {
const payment: Payment = {
TransactionType: 'Payment',
Account: 'rRandom',
Destination: 'rRandom2',
Amount: '3489303',
TxnSignature: 'asodfiuaosdfuaosd',
}
const sidechainAccount = 'rSidechain'
const expectedPayment = {
...payment,
Memos: [
{
Memo: {
MemoData: convertStringToHex(sidechainAccount),
},
},
],
}
delete expectedPayment.TxnSignature
const resultPayment = createCrossChainPayment(payment, sidechainAccount)
assert.deepEqual(resultPayment, expectedPayment)
// ensure that the original object wasn't modified
assert.notDeepEqual(resultPayment, payment)
})
it('fails with 3 memos', function () {
const payment: Payment = {
TransactionType: 'Payment',
Account: 'rRandom',
Destination: 'rRandom2',
Amount: '3489303',
Memos: [
{
Memo: {
MemoData: '2934723843ace',
},
},
{
Memo: {
MemoData: '2934723843ace',
},
},
{
Memo: {
MemoData: '2934723843ace',
},
},
],
}
assert.throws(() => {
createCrossChainPayment(payment, 'rSidechain')
}, /Cannot have more than 2 memos/u)
})
})

View File

@@ -2,7 +2,7 @@ import fs from 'fs'
import path from 'path'
import { assert } from 'chai'
import { encode } from '@transia/ripple-binary-codec'
import { encode } from 'ripple-binary-codec'
import { OfferCreate, Transaction, ValidationError } from '../../src'
import {

View File

@@ -1,64 +0,0 @@
import { assert } from 'chai'
import {
calculateHookOn,
hexNamespace,
hexHookParameters,
TTS,
} from '../../src'
describe('test hook on', function () {
it('invalid', function () {
const invokeOn: Array<keyof TTS> = ['AccountSet1']
expect(() => {
calculateHookOn(invokeOn)
}).toThrow("invalid transaction type 'AccountSet1' in HookOn array")
})
it('all', function () {
const result = calculateHookOn([])
assert.equal(
result,
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFFF',
)
})
it('one', function () {
const invokeOn: Array<keyof TTS> = ['AccountSet']
const result = calculateHookOn(invokeOn)
assert.equal(
result,
'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFF7',
)
})
})
describe('test hook namespace', function () {
it('basic', async function () {
const result = await hexNamespace('starter')
assert.equal(
result,
'4FF9961269BF7630D32E15276569C94470174A5DA79FA567C0F62251AA9A36B9',
)
})
})
describe('test hook parameters', function () {
it('basic', async function () {
const parameters = [
{
HookParameter: {
HookParameterName: 'name1',
HookParameterValue: 'value1',
},
},
]
const result = hexHookParameters(parameters)
assert.deepEqual(result, [
{
HookParameter: {
HookParameterName: '6E616D6531',
HookParameterValue: '76616C756531',
},
},
])
})
})

View File

@@ -1,5 +1,5 @@
import { assert } from 'chai'
import { decode } from '@transia/ripple-binary-codec'
import { decode } from 'ripple-binary-codec'
import { NFTokenMint, Payment, Transaction } from '../../src'
import ECDSA from '../../src/ECDSA'

View File

@@ -1,5 +1,5 @@
import { assert } from 'chai'
import { decode, encode } from '@transia/ripple-binary-codec'
import { decode, encode } from 'ripple-binary-codec'
import { Transaction, ValidationError } from '../../src'
import Wallet from '../../src/Wallet'