Compare commits

...

7 Commits

Author SHA1 Message Date
dependabot[bot]
4066715801 build(deps-dev): bump eslint-plugin-jsdoc from 37.1.0 to 39.3.3
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 37.1.0 to 39.3.3.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v37.1.0...v39.3.3)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-12 21:05:42 +00:00
dependabot[bot]
14ffaae960 build(deps): bump parse-url from 6.0.0 to 6.0.2 (#2035)
Bumps [parse-url](https://github.com/IonicaBizau/parse-url) from 6.0.0 to 6.0.2.
- [Release notes](https://github.com/IonicaBizau/parse-url/releases)
- [Commits](https://github.com/IonicaBizau/parse-url/commits)

---
updated-dependencies:
- dependency-name: parse-url
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-12 17:04:26 -04:00
Mayukha Vadari
8eab8b3c04 ci: cache npm dependencies (#2038)
* attempt to cache

* dummy commit

* change action strategy

* simplify
2022-07-12 10:04:25 -04:00
Omar Khan
aff6988f09 Release xrpl packages (#2028)
* update package and package-lock json

* update HISTORY files
2022-06-27 21:11:07 -04:00
Elliot Lee
9ff9fc7767 fix: link to XRPL Rosetta (ThreeXRP.dev) (#2027) 2022-06-20 06:18:31 -07:00
Jackson Mills
89240eae62 Handle edge cases for standard currency code signing (#2009)
* Allow decoding symbols + lowercase standard codes
* Standardize the treatment of standard codes and hex codes for verifying transaction equivalence
2022-06-17 14:27:47 -07:00
Jackson Mills
7732f22858 Add NFT Devnet as an inferable faucet (#2024)
* Add NFT Devnet to implicit fundWallet
2022-06-15 11:12:37 -07:00
15 changed files with 320 additions and 121 deletions

View File

@@ -18,11 +18,12 @@ jobs:
node-version: [14.x]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm install -g npm@7
- run: npm ci
- run: npm run build
@@ -37,11 +38,13 @@ jobs:
node-version: [12.x, 14.x, 16.x]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
- run: npm install -g npm@7
- run: npm ci
- run: npm run build
@@ -63,11 +66,13 @@ jobs:
--health-cmd="wget localhost:6006 || exit 1" --health-interval=5s --health-retries=10 --health-timeout=2s
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
- run: npm install -g npm@7
- run: npm ci
- run: npm run build
@@ -97,6 +102,8 @@ jobs:
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
- run: npm install -g npm@7
- run: npm ci
- run: npm run build

View File

@@ -68,7 +68,7 @@ Warning: Use at your own risk.
Attempts to detect RippleNet on-demand liquidity (ODL) transactions through known fiat corridors and report these transactions in real time.
- **[XRPL Rosetta](https://xrpl-rosetta-oepox.ondigitalocean.app)**
- **[XRPL Rosetta](https://threexrp.dev/)**
3D Globe written in three.js connected to a Node.js websocket server that is listening to exchanges and the XRPL. The visualization aims to show trading, ODL, and liquidity at exchanges, intra-exchange volume, and flows.

180
package-lock.json generated
View File

@@ -36,7 +36,7 @@
"eslint-plugin-consistent-default-export-name": "^0.0.14",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-import": "^2.24.1",
"eslint-plugin-jsdoc": "^37.1.0",
"eslint-plugin-jsdoc": "^39.3.3",
"eslint-plugin-mocha": "^10.0.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
@@ -719,26 +719,17 @@
}
},
"node_modules/@es-joy/jsdoccomment": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.12.0.tgz",
"integrity": "sha512-Gw4/j9v36IKY8ET+W0GoOzrRw17xjf21EIFFRL3zx21fF5MnqmeNpNi+PU/LKjqLpPb2Pw2XdlJbYM31VVo/PQ==",
"version": "0.31.0",
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.31.0.tgz",
"integrity": "sha512-tc1/iuQcnaiSIUVad72PBierDFpsxdUHtEF/OrfqvM1CBAsIoMP51j52jTMb3dXriwhieTo289InzZj72jL3EQ==",
"dev": true,
"dependencies": {
"comment-parser": "1.2.4",
"comment-parser": "1.3.1",
"esquery": "^1.4.0",
"jsdoc-type-pratt-parser": "2.0.0"
"jsdoc-type-pratt-parser": "~3.1.0"
},
"engines": {
"node": "^12 || ^14 || ^16 || ^17"
}
},
"node_modules/@es-joy/jsdoccomment/node_modules/comment-parser": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz",
"integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==",
"dev": true,
"engines": {
"node": ">= 12.0.0"
"node": "^14 || ^16 || ^17 || ^18"
}
},
"node_modules/@eslint/eslintrc": {
@@ -4908,9 +4899,9 @@
"dev": true
},
"node_modules/comment-parser": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.0.tgz",
"integrity": "sha512-hRpmWIKgzd81vn0ydoWoyPoALEOnF4wt8yKD35Ib1D6XC2siLiYaiqfGkYrunuKdsXGwpBpHU3+9r+RVw2NZfA==",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz",
"integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==",
"dev": true,
"engines": {
"node": ">= 12.0.0"
@@ -6178,23 +6169,21 @@
"dev": true
},
"node_modules/eslint-plugin-jsdoc": {
"version": "37.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.1.0.tgz",
"integrity": "sha512-DpkFzX5Sqkqzy4MCgowhDXmusWcF1Gn7wYnphdGfWmIkoQr6SwL0jEtltGAVyF5Rj6ACi6ydw0oCCI5hF3yz6w==",
"version": "39.3.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.3.tgz",
"integrity": "sha512-K/DAjKRUNaUTf0KQhI9PvsF+Y3mGDx/j0pofXsJCQe/tmRsRweBIXR353c8nAro0lytZYEf7l0PluBpzKDiHxw==",
"dev": true,
"dependencies": {
"@es-joy/jsdoccomment": "0.12.0",
"comment-parser": "1.3.0",
"debug": "^4.3.3",
"@es-joy/jsdoccomment": "~0.31.0",
"comment-parser": "1.3.1",
"debug": "^4.3.4",
"escape-string-regexp": "^4.0.0",
"esquery": "^1.4.0",
"jsdoc-type-pratt-parser": "^2.0.0",
"regextras": "^0.8.0",
"semver": "^7.3.5",
"semver": "^7.3.7",
"spdx-expression-parse": "^3.0.1"
},
"engines": {
"node": "^12 || ^14 || ^16 || ^17"
"node": "^14 || ^16 || ^17 || ^18"
},
"peerDependencies": {
"eslint": "^7.0.0 || ^8.0.0"
@@ -6998,7 +6987,8 @@
},
"node_modules/filter-obj": {
"version": "1.1.0",
"integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=",
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
"integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
"dev": true,
"engines": {
"node": ">=0.10.0"
@@ -9798,9 +9788,9 @@
"dev": true
},
"node_modules/jsdoc-type-pratt-parser": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.0.0.tgz",
"integrity": "sha512-sUuj2j48wxrEpbFjDp1sAesAxPiLT+z0SWVmMafyIINs6Lj5gIPKh3VrkBZu4E/Dv+wHpOot0m6H8zlHQjwqeQ==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz",
"integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==",
"dev": true,
"engines": {
"node": ">=12.0.0"
@@ -12616,8 +12606,9 @@
}
},
"node_modules/parse-path": {
"version": "4.0.3",
"integrity": "sha512-9Cepbp2asKnWTJ9x2kpw6Fe8y9JDbqwahGCTvklzd/cEq5C5JC59x2Xb0Kx+x0QZ8bvNquGO8/BWP0cwBHzSAA==",
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.4.tgz",
"integrity": "sha512-Z2lWUis7jlmXC1jeOG9giRO2+FsuyNipeQ43HAjqAZjwSe3SEf+q/84FGPHoso3kyntbxa4c4i77t3m6fGf8cw==",
"dev": true,
"dependencies": {
"is-ssh": "^1.3.0",
@@ -12627,13 +12618,14 @@
}
},
"node_modules/parse-url": {
"version": "6.0.0",
"integrity": "sha512-cYyojeX7yIIwuJzledIHeLUBVJ6COVLeT4eF+2P6aKVzwvgKQPndCBv3+yQ7pcWjqToYwaligxzSYNNmGoMAvw==",
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/parse-url/-/parse-url-6.0.2.tgz",
"integrity": "sha512-uCSjOvD3T+6B/sPWhR+QowAZcU/o4bjPrVBQBGFxcDF6J6FraCGIaDBsdoQawiaaAVdHvtqBe3w3vKlfBKySOQ==",
"dev": true,
"dependencies": {
"is-ssh": "^1.3.0",
"normalize-url": "^6.1.0",
"parse-path": "^4.0.0",
"parse-path": "^4.0.4",
"protocols": "^1.4.0"
}
},
@@ -13105,8 +13097,9 @@
}
},
"node_modules/qs": {
"version": "6.10.1",
"integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
"dev": true,
"dependencies": {
"side-channel": "^1.0.4"
@@ -13120,6 +13113,7 @@
},
"node_modules/query-string": {
"version": "6.14.1",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz",
"integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==",
"dev": true,
"dependencies": {
@@ -13424,14 +13418,6 @@
"url": "https://github.com/sponsors/mysticatea"
}
},
"node_modules/regextras": {
"version": "0.8.0",
"integrity": "sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==",
"dev": true,
"engines": {
"node": ">=0.1.14"
}
},
"node_modules/release-zalgo": {
"version": "1.0.0",
"integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=",
@@ -14030,8 +14016,9 @@
}
},
"node_modules/semver": {
"version": "7.3.5",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"version": "7.3.7",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -14590,6 +14577,7 @@
},
"node_modules/split-on-first": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
"dev": true,
"engines": {
@@ -14784,7 +14772,8 @@
},
"node_modules/strict-uri-encode": {
"version": "2.0.0",
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
"integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==",
"dev": true,
"engines": {
"node": ">=4"
@@ -16704,7 +16693,7 @@
}
},
"packages/ripple-binary-codec": {
"version": "1.4.1",
"version": "1.4.2",
"integrity": "sha512-XMRCbFXyG+dGp3x7tMs9IwA+FVWPPaGjdHYW2+g4Q/WQJqFp5MRED+jjOBOUafmrW4TUsOn1PEEdbB4ozWbDBw==",
"license": "ISC",
"dependencies": {
@@ -16743,7 +16732,7 @@
}
},
"packages/xrpl": {
"version": "2.3.0",
"version": "2.3.1",
"integrity": "sha512-NmrSYpXym7NzGABeXU1H8g4ZtCxRhr/3wu0lguxzcIYpcKPgWLYimg+s9NLLNbPWTZdxXu9SeSWu5zh4gyqAeA==",
"license": "ISC",
"dependencies": {
@@ -16753,7 +16742,7 @@
"https-proxy-agent": "^5.0.0",
"lodash": "^4.17.4",
"ripple-address-codec": "^4.2.4",
"ripple-binary-codec": "^1.4.1",
"ripple-binary-codec": "^1.4.2",
"ripple-keypairs": "^1.1.4",
"ws": "^8.2.2"
},
@@ -17271,22 +17260,14 @@
"dev": true
},
"@es-joy/jsdoccomment": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.12.0.tgz",
"integrity": "sha512-Gw4/j9v36IKY8ET+W0GoOzrRw17xjf21EIFFRL3zx21fF5MnqmeNpNi+PU/LKjqLpPb2Pw2XdlJbYM31VVo/PQ==",
"version": "0.31.0",
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.31.0.tgz",
"integrity": "sha512-tc1/iuQcnaiSIUVad72PBierDFpsxdUHtEF/OrfqvM1CBAsIoMP51j52jTMb3dXriwhieTo289InzZj72jL3EQ==",
"dev": true,
"requires": {
"comment-parser": "1.2.4",
"comment-parser": "1.3.1",
"esquery": "^1.4.0",
"jsdoc-type-pratt-parser": "2.0.0"
},
"dependencies": {
"comment-parser": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.2.4.tgz",
"integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==",
"dev": true
}
"jsdoc-type-pratt-parser": "~3.1.0"
}
},
"@eslint/eslintrc": {
@@ -20576,9 +20557,9 @@
"dev": true
},
"comment-parser": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.0.tgz",
"integrity": "sha512-hRpmWIKgzd81vn0ydoWoyPoALEOnF4wt8yKD35Ib1D6XC2siLiYaiqfGkYrunuKdsXGwpBpHU3+9r+RVw2NZfA==",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz",
"integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==",
"dev": true
},
"commondir": {
@@ -21597,19 +21578,17 @@
}
},
"eslint-plugin-jsdoc": {
"version": "37.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.1.0.tgz",
"integrity": "sha512-DpkFzX5Sqkqzy4MCgowhDXmusWcF1Gn7wYnphdGfWmIkoQr6SwL0jEtltGAVyF5Rj6ACi6ydw0oCCI5hF3yz6w==",
"version": "39.3.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.3.tgz",
"integrity": "sha512-K/DAjKRUNaUTf0KQhI9PvsF+Y3mGDx/j0pofXsJCQe/tmRsRweBIXR353c8nAro0lytZYEf7l0PluBpzKDiHxw==",
"dev": true,
"requires": {
"@es-joy/jsdoccomment": "0.12.0",
"comment-parser": "1.3.0",
"debug": "^4.3.3",
"@es-joy/jsdoccomment": "~0.31.0",
"comment-parser": "1.3.1",
"debug": "^4.3.4",
"escape-string-regexp": "^4.0.0",
"esquery": "^1.4.0",
"jsdoc-type-pratt-parser": "^2.0.0",
"regextras": "^0.8.0",
"semver": "^7.3.5",
"semver": "^7.3.7",
"spdx-expression-parse": "^3.0.1"
}
},
@@ -22214,7 +22193,8 @@
},
"filter-obj": {
"version": "1.1.0",
"integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=",
"resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
"integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
"dev": true
},
"find-cache-dir": {
@@ -24272,9 +24252,9 @@
"dev": true
},
"jsdoc-type-pratt-parser": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.0.0.tgz",
"integrity": "sha512-sUuj2j48wxrEpbFjDp1sAesAxPiLT+z0SWVmMafyIINs6Lj5gIPKh3VrkBZu4E/Dv+wHpOot0m6H8zlHQjwqeQ==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz",
"integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==",
"dev": true
},
"jsdom": {
@@ -26428,8 +26408,9 @@
}
},
"parse-path": {
"version": "4.0.3",
"integrity": "sha512-9Cepbp2asKnWTJ9x2kpw6Fe8y9JDbqwahGCTvklzd/cEq5C5JC59x2Xb0Kx+x0QZ8bvNquGO8/BWP0cwBHzSAA==",
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.4.tgz",
"integrity": "sha512-Z2lWUis7jlmXC1jeOG9giRO2+FsuyNipeQ43HAjqAZjwSe3SEf+q/84FGPHoso3kyntbxa4c4i77t3m6fGf8cw==",
"dev": true,
"requires": {
"is-ssh": "^1.3.0",
@@ -26439,13 +26420,14 @@
}
},
"parse-url": {
"version": "6.0.0",
"integrity": "sha512-cYyojeX7yIIwuJzledIHeLUBVJ6COVLeT4eF+2P6aKVzwvgKQPndCBv3+yQ7pcWjqToYwaligxzSYNNmGoMAvw==",
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/parse-url/-/parse-url-6.0.2.tgz",
"integrity": "sha512-uCSjOvD3T+6B/sPWhR+QowAZcU/o4bjPrVBQBGFxcDF6J6FraCGIaDBsdoQawiaaAVdHvtqBe3w3vKlfBKySOQ==",
"dev": true,
"requires": {
"is-ssh": "^1.3.0",
"normalize-url": "^6.1.0",
"parse-path": "^4.0.0",
"parse-path": "^4.0.4",
"protocols": "^1.4.0"
}
},
@@ -26799,8 +26781,9 @@
"dev": true
},
"qs": {
"version": "6.10.1",
"integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
"dev": true,
"requires": {
"side-channel": "^1.0.4"
@@ -26808,6 +26791,7 @@
},
"query-string": {
"version": "6.14.1",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz",
"integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==",
"dev": true,
"requires": {
@@ -27040,11 +27024,6 @@
"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
"dev": true
},
"regextras": {
"version": "0.8.0",
"integrity": "sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==",
"dev": true
},
"release-zalgo": {
"version": "1.0.0",
"integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=",
@@ -27509,8 +27488,9 @@
}
},
"semver": {
"version": "7.3.5",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"version": "7.3.7",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -27950,6 +27930,7 @@
},
"split-on-first": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
"dev": true
},
@@ -28105,7 +28086,8 @@
},
"strict-uri-encode": {
"version": "2.0.0",
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
"integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==",
"dev": true
},
"string_decoder": {
@@ -29425,7 +29407,7 @@
"https-proxy-agent": "^5.0.0",
"lodash": "^4.17.4",
"ripple-address-codec": "^4.2.4",
"ripple-binary-codec": "^1.4.1",
"ripple-binary-codec": "^1.4.2",
"ripple-keypairs": "^1.1.4",
"ws": "^8.2.2",
"xrpl-local": "file:src"

View File

@@ -38,7 +38,7 @@
"eslint-plugin-consistent-default-export-name": "^0.0.14",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-import": "^2.24.1",
"eslint-plugin-jsdoc": "^37.1.0",
"eslint-plugin-jsdoc": "^39.3.3",
"eslint-plugin-mocha": "^10.0.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",

View File

@@ -2,6 +2,9 @@
## Unreleased
## 1.4.2 (2022-06-27)
- Fixed standard currency codes with lowercase and allowed symbols not decoding into standard codes.
## 1.4.1 (2022-06-02)
- Added a clearer error message for trying to encode an invalid transaction. (Ex. With an incorrect TransactionType)

View File

@@ -1,6 +1,6 @@
{
"name": "ripple-binary-codec",
"version": "1.4.1",
"version": "1.4.2",
"description": "XRP Ledger binary codec",
"files": [
"dist/*",

View File

@@ -2,7 +2,7 @@ import { Hash160 } from './hash-160'
import { Buffer } from 'buffer/'
const XRP_HEX_REGEX = /^0{40}$/
const ISO_REGEX = /^[A-Z0-9]{3}$/
const ISO_REGEX = /^[A-Z0-9a-z?!@#$%^&*(){}[\]|]{3}$/
const HEX_REGEX = /^[A-F0-9]{40}$/
// eslint-disable-next-line no-control-regex
const STANDARD_FORMAT_HEX_REGEX = /^0{24}[\x00-\x7F]{6}0{10}$/

View File

@@ -54,15 +54,19 @@ describe('Currency', function () {
const currencyCode = '0000000000000000000000005852500000000000'
expect(Currency.from(currencyCode).toJSON()).toBe(currencyCode)
})
test('Currency with lowercase letters decode to hex', () => {
expect(Currency.from('xRp').toJSON()).toBe(
'0000000000000000000000007852700000000000',
test('Currency code with lowercase letters decodes to ISO code', () => {
expect(Currency.from('xRp').toJSON()).toBe('xRp')
})
test('Currency codes with symbols decodes to ISO code', () => {
expect(Currency.from('x|p').toJSON()).toBe('x|p')
})
test('Currency code with non-standard symbols decodes to hex', () => {
expect(Currency.from(':::').toJSON()).toBe(
'0000000000000000000000003A3A3A0000000000',
)
})
test('Currency codes with symbols decode to hex', () => {
expect(Currency.from('x|p').toJSON()).toBe(
'000000000000000000000000787C700000000000',
)
test('Currency codes can be exclusively standard symbols', () => {
expect(Currency.from('![]').toJSON()).toBe('![]')
})
test('Currency codes with uppercase and 0-9 decode to ISO codes', () => {
expect(Currency.from('X8P').toJSON()).toBe('X8P')

View File

@@ -4,6 +4,13 @@ Subscribe to [the **xrpl-announce** mailing list](https://groups.google.com/g/xr
## Unreleased
## 2.3.1 (2022-06-27)
### Fixed
* Signing tx with standard currency codes with lowercase and allowed symbols causing an error on decode.
### Added
* When connected to nft-devnet, Client.fundWallet now defaults to using the nft-devnet faucet instead of requiring specification.
## 2.3.0 (2022-06-02)
### Added
* Sourcemap generation for browser bundle

View File

@@ -1,6 +1,6 @@
{
"name": "xrpl",
"version": "2.3.0",
"version": "2.3.1",
"lockfileVersion": 2,
"requires": true,
"packages": {

View File

@@ -1,6 +1,6 @@
{
"name": "xrpl",
"version": "2.3.0",
"version": "2.3.1",
"license": "ISC",
"description": "A TypeScript/JavaScript API for interacting with the XRP Ledger in Node.js and the browser",
"files": [
@@ -27,7 +27,7 @@
"https-proxy-agent": "^5.0.0",
"lodash": "^4.17.4",
"ripple-address-codec": "^4.2.4",
"ripple-binary-codec": "^1.4.1",
"ripple-binary-codec": "^1.4.2",
"ripple-keypairs": "^1.1.4",
"ws": "^8.2.2"
},

View File

@@ -21,6 +21,7 @@ interface FaucetWallet {
enum FaucetNetwork {
Testnet = 'faucet.altnet.rippletest.net',
Devnet = 'faucet.devnet.rippletest.net',
NFTDevnet = 'faucet-nft.ripple.com',
}
// Interval to check an account balance
@@ -312,6 +313,10 @@ function getFaucetHost(client: Client): FaucetNetwork | undefined {
return FaucetNetwork.Devnet
}
if (connectionUrl.includes('xls20-sandbox')) {
return FaucetNetwork.NFTDevnet
}
throw new XRPLFaucetError('Faucet URL is not defined or inferrable.')
}

View File

@@ -24,8 +24,10 @@ import {
} from 'ripple-keypairs'
import ECDSA from '../ECDSA'
import { ValidationError } from '../errors'
import { ValidationError, XrplError } from '../errors'
import { IssuedCurrencyAmount } from '../models/common'
import { Transaction } from '../models/transactions'
import { isIssuedCurrency } from '../models/transactions/common'
import { isHex } from '../models/utils'
import { ensureClassicAddress } from '../sugar/utils'
import { hashSignedTx } from '../utils/hashes/hashLedger'
@@ -303,6 +305,7 @@ class Wallet {
* @param multisign - Specify true/false to use multisign or actual address (classic/x-address) to make multisign tx request.
* @returns A signed transaction.
* @throws ValidationError if the transaction is already signed or does not encode/decode to same result.
* @throws XrplError if the issued currency being signed is XRP ignoring case.
*/
// eslint-disable-next-line max-lines-per-function -- introduced more checks to support both string and boolean inputs.
public sign(
@@ -351,6 +354,7 @@ class Wallet {
this.privateKey,
)
}
const serialized = encode(txToSignAndEncode)
this.checkTxSerialization(serialized, tx)
return {
@@ -392,6 +396,7 @@ class Wallet {
* @param tx - The transaction prior to signing.
* @throws A ValidationError if the transaction does not have a TxnSignature/Signers property, or if
* the serialized Transaction desn't match the original transaction.
* @throws XrplError if the transaction includes an issued currency which is equivalent to XRP ignoring case.
*/
// eslint-disable-next-line class-methods-use-this, max-lines-per-function -- Helper for organization purposes
private checkTxSerialization(serialized: string, tx: Transaction): void {
@@ -449,6 +454,38 @@ class Wallet {
txCopy.URI = txCopy.URI.toUpperCase()
}
/* eslint-disable @typescript-eslint/consistent-type-assertions -- We check at runtime that this is safe */
Object.keys(txCopy).forEach((key) => {
const standard_currency_code_len = 3
if (txCopy[key] && isIssuedCurrency(txCopy[key])) {
const decodedAmount = decoded[key] as unknown as IssuedCurrencyAmount
const decodedCurrency = decodedAmount.currency
const txCurrency = (txCopy[key] as IssuedCurrencyAmount).currency
if (
txCurrency.length === standard_currency_code_len &&
txCurrency.toUpperCase() === 'XRP'
) {
throw new XrplError(
`Trying to sign an issued currency with a similar standard code to XRP (received '${txCurrency}'). XRP is not an issued currency.`,
)
}
// Standardize the format of currency codes to the 40 byte hex string for comparison
const amount = txCopy[key] as IssuedCurrencyAmount
if (amount.currency.length !== decodedCurrency.length) {
/* eslint-disable-next-line max-depth -- Easier to read with two if-statements */
if (decodedCurrency.length === standard_currency_code_len) {
decodedAmount.currency = isoToHex(decodedCurrency)
} else {
/* eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- We need to update txCopy directly */
txCopy[key].currency = isoToHex(txCopy[key].currency)
}
}
}
})
/* eslint-enable @typescript-eslint/consistent-type-assertions -- Done with dynamic checking */
if (!_.isEqual(decoded, txCopy)) {
const data = {
decoded,
@@ -509,4 +546,20 @@ function removeTrailingZeros(tx: Transaction): void {
}
}
/**
* Convert an ISO code to a hex string representation
*
* @param iso - A 3 letter standard currency code
*/
/* 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 !== 'XRP') {
const isoBytes = iso.split('').map((chr) => chr.charCodeAt(0))
bytes.set(isoBytes, 12)
}
return bytes.toString('hex').toUpperCase()
}
/* eslint-enable @typescript-eslint/no-magic-numbers -- Only needed in this function */
export default Wallet

View File

@@ -69,6 +69,35 @@ describe('fundWallet', function () {
await api.disconnect()
})
it('can generate and fund wallets on nft-devnet', async function () {
const api = new Client('ws://xls20-sandbox.rippletest.net:51233')
await api.connect()
const { wallet, balance } = await api.fundWallet()
assert.notEqual(wallet, undefined)
assert(isValidClassicAddress(wallet.classicAddress))
assert(isValidXAddress(wallet.getXAddress()))
const info = await api.request({
command: 'account_info',
account: wallet.classicAddress,
})
assert.equal(dropsToXrp(info.result.account_data.Balance), balance)
const { balance: newBalance } = await api.fundWallet(wallet, {
faucetHost: 'faucet-nft.ripple.com',
})
const afterSent = await api.request({
command: 'account_info',
account: wallet.classicAddress,
})
assert.equal(dropsToXrp(afterSent.result.account_data.Balance), newBalance)
await api.disconnect()
})
it('can generate and fund wallets using a custom host', async function () {
const api = new Client('ws://xls20-sandbox.rippletest.net:51233')

View File

@@ -1,6 +1,6 @@
import { assert } from 'chai'
import { decode } from 'ripple-binary-codec/dist'
import { NFTokenMint, Transaction } from 'xrpl-local'
import { NFTokenMint, Payment, Transaction } from 'xrpl-local'
import ECDSA from 'xrpl-local/ECDSA'
import Wallet from 'xrpl-local/Wallet'
@@ -301,6 +301,7 @@ describe('Wallet', function () {
})
})
// eslint-disable-next-line max-statements -- Required for test coverage.
describe('sign', function () {
let wallet: Wallet
@@ -590,6 +591,114 @@ describe('Wallet', function () {
}, /^1.1234567 is an illegal amount/u)
})
const issuedCurrencyPayment: Transaction = {
TransactionType: 'Payment',
Account: 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59',
Destination: 'rQ3PTWGLCbPz8ZCicV5tCX3xuymojTng5r',
Amount: {
currency: 'foo',
issuer: 'rnURbz5HLbvqEq69b1B4TX6cUTNMmcrBqi',
value: '123.40',
},
Flags: 2147483648,
Sequence: 23,
LastLedgerSequence: 8819954,
Fee: '12',
}
it('lowercase standard currency code signs successfully', async function () {
const payment: Payment = { ...issuedCurrencyPayment }
payment.Amount = {
currency: 'foo',
issuer: 'rnURbz5HLbvqEq69b1B4TX6cUTNMmcrBqi',
value: '123.40',
}
assert.deepEqual(wallet.sign(payment), {
tx_blob:
'12000022800000002400000017201B008694F261D504625103A72000000000000000000000000000666F6F00000000002E099DD75FDD96EB4A603037844F964832FED86B68400000000000000C732102A8A44DB3D4C73EEEE11DFE54D2029103B776AA8A8D293A91D645977C9DF5F54474473045022100D32EBD44F86FB6D0BE239A410B62A73A8B0C26CE3767321913D6FB7BE6FAC2410220430C011C25091DA9CD75E7C99BE406572FBB57B92132E39B4BF873863E744E2E81145E7B112523F68D2F5E879DB4EAC51C6698A693048314FDB08D07AAA0EB711793A3027304D688E10C3648',
hash: 'F822EA1D7B2A3026E4654A9152896652C3843B5690F8A56C4217CB4690C5C95A',
})
})
it('issued currency in standard or hex format signs to the same transaction', async function () {
const payment: Payment = { ...issuedCurrencyPayment }
payment.Amount = {
currency: '***',
issuer: 'rnURbz5HLbvqEq69b1B4TX6cUTNMmcrBqi',
value: '123.40',
}
const payment2: Payment = { ...issuedCurrencyPayment }
payment2.Amount = {
currency: '0000000000000000000000002A2A2A0000000000',
issuer: 'rnURbz5HLbvqEq69b1B4TX6cUTNMmcrBqi',
value: '123.40',
}
assert.deepEqual(wallet.sign(payment), wallet.sign(payment2))
})
it('sign throws when a payment contains an issued currency like XRP', async function () {
const payment: Payment = { ...issuedCurrencyPayment }
payment.Amount = {
currency: 'xrp',
issuer: 'rnURbz5HLbvqEq69b1B4TX6cUTNMmcrBqi',
value: '123.40',
}
assert.throws(() => {
wallet.sign(payment)
}, /^Trying to sign an issued currency with a similar standard code to XRP \(received 'xrp'\)\. XRP is not an issued currency\./u)
})
it('sign does NOT throw when a payment contains an issued currency like xrp in hex string format', async function () {
const payment: Payment = { ...issuedCurrencyPayment }
payment.Amount = {
currency: '0000000000000000000000007872700000000000',
issuer: 'rnURbz5HLbvqEq69b1B4TX6cUTNMmcrBqi',
value: '123.40',
}
assert.deepEqual(wallet.sign(payment), {
tx_blob:
'12000022800000002400000017201B008694F261D504625103A7200000000000000000000000000078727000000000002E099DD75FDD96EB4A603037844F964832FED86B68400000000000000C732102A8A44DB3D4C73EEEE11DFE54D2029103B776AA8A8D293A91D645977C9DF5F5447446304402202CD2BE27480860765B1B8DB6C499D299734C533F4FFA66317E46D1ADE5181EB7022066D2C65B975A6A9FEE56AB55211D5F2F65D6F988C8280019211874D11771A05D81145E7B112523F68D2F5E879DB4EAC51C6698A693048314FDB08D07AAA0EB711793A3027304D688E10C3648',
hash: '1FEAA7894E507E36D73F60DED89852CE28994366879BC7D3D806E4C50D10B1EE',
})
})
it('sign succeeds with standard currency code with symbols', async function () {
const payment: Payment = { ...issuedCurrencyPayment }
payment.Amount = {
currency: '***',
issuer: 'rnURbz5HLbvqEq69b1B4TX6cUTNMmcrBqi',
value: '123.40',
}
const result = wallet.sign(payment)
const expectedResult = {
tx_blob:
'12000022800000002400000017201B008694F261D504625103A720000000000000000000000000002A2A2A00000000002E099DD75FDD96EB4A603037844F964832FED86B68400000000000000C732102A8A44DB3D4C73EEEE11DFE54D2029103B776AA8A8D293A91D645977C9DF5F54474463044022073E71588750C3D47D7D9A541F00FB897823DA67ED198D0A74404B6FE6D5E4AB5022021BE798D4159F375EBE13D0545F50EE864DF834D5A9F9A31504212156A57934C81145E7B112523F68D2F5E879DB4EAC51C6698A693048314FDB08D07AAA0EB711793A3027304D688E10C3648',
hash: '95BF9931C1EA164960FE13A504D5FBAEB1E072C1D291D75B85BA3F22A50346DF',
}
assert.deepEqual(result, expectedResult)
})
it('sign succeeds with non-standard 3 digit currency code', async function () {
const payment: Payment = { ...issuedCurrencyPayment }
payment.Amount = {
currency: ':::',
issuer: 'rnURbz5HLbvqEq69b1B4TX6cUTNMmcrBqi',
value: '123.40',
}
const result = wallet.sign(payment)
const expectedResult = {
tx_blob:
'12000022800000002400000017201B008694F261D504625103A720000000000000000000000000003A3A3A00000000002E099DD75FDD96EB4A603037844F964832FED86B68400000000000000C732102A8A44DB3D4C73EEEE11DFE54D2029103B776AA8A8D293A91D645977C9DF5F5447446304402205952993DB235D3A6398E2CB5F91D7F0AD9067F02CB8E62FD335C516B64130F4702206777746CC516F95F39ADDD62CD395AF2F6BAFCCA355B5D23B9B4D9358474A11281145E7B112523F68D2F5E879DB4EAC51C6698A693048314FDB08D07AAA0EB711793A3027304D688E10C3648',
hash: 'CE80072E6D70932BC7AA698B931BCF97B6CC3DD3984E08DF284B74E8CB4E543A',
}
assert.deepEqual(result, expectedResult)
})
it('sign handles non-XRP amount with a trailing zero', async function () {
const payment: Transaction = {
TransactionType: 'Payment',