Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Lint

on:
push:
branches: [master]
pull_request:
workflow_dispatch:

jobs:
prettier:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "24"

- name: Install dependencies
run: npm install -g prettier

- name: Run Prettier
run: npx prettier --check .
14 changes: 14 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: mixed-line-ending
- id: check-merge-conflict
args: [--assume-in-merge]

- repo: https://github.com/rbubley/mirrors-prettier
rev: 5ba47274f9b181bce26a5150a725577f3c336011 # frozen: v3.6.2
hooks:
- id: prettier
12 changes: 7 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# CONTRIBUTING

The work of the [XRP Ledger](https://xrpl.org) community is open, collaborative, and welcoming of all contributors participating in good faith. Part of that effort involves standardization, and this document outlines how anyone can contribute to that process.
The work of the [XRP Ledger](https://xrpl.org) community is open, collaborative, and welcoming of all contributors participating in good faith. Part of that effort involves standardization, and this document outlines how anyone can contribute to that process.

## Licensing
Any XRPL Standards document can be referred to interchangeably as an "XLS", "XRPL Standard", or "document". Copyright on all content is subject to the terms of this [license](LICENSE), and all contributors grant everyone a royalty-free license to use their contributions, including the following grants:

Any XRPL Standards document can be referred to interchangeably as an "XLS", "XRPL Standard", or "document". Copyright on all content is subject to the terms of this [license](LICENSE), and all contributors grant everyone a royalty-free license to use their contributions, including the following grants:

- Copyright: a royalty-free license to anyone to use any contributions submitted to this repository.
- Patent: a commitment to license on a royalty-free basis any essential patent claims relating to any contributions in this repository.
Expand All @@ -15,14 +16,16 @@ Any XRPL Standards document can be referred to interchangeably as an "XLS", "XRP
Before opening a PR with any kind of formal proposal, please first gather community input by starting a [Discussion](https://github.com/XRPLF/XRPL-Standards/discussions). Discussions are suitable for early work-in-progress: ask, suggest, add, and make sweeping changes. Collecting such feedback helps to refine your concept, and is required in order to move forward in the specification process.

#### Discussion Title

When creating a new discussion for your idea, the discussion title should follow the naming convention `XLS-{0000}d {Title}`, where `{0000}` is a unique number for the XLS, `d` indicates that the document is a Draft (i.e., work in progress), and `{Title}` is a descriptive title for the proposed document.

#### Specification Number

Use the next number that has not yet been used. If a conflict occurs, it will be fixed by a maintainer or editor. Maintainers or editors also reserve the right to remove or re-number proposals as necessary. The number is important, as it will be used to reference features and ideas throughout the community.

### 2. Closing a Discussion

When a discussion has produced a well-refined standard, authors should post a comment to the discussion noting that the discussion will be closed in a few days. This allows time (for those engaged with the discussion) to submit final commentary.
When a discussion has produced a well-refined standard, authors should post a comment to the discussion noting that the discussion will be closed in a few days. This allows time (for those engaged with the discussion) to submit final commentary.

Once this waiting period has elapsed, the standard's author may close the discussion from further comment, and then move the discussion to a [**specification pull request**](#3-specification-pull-requests) to add the standard into the repository as a markdown file (see below for specification formats).

Expand All @@ -32,7 +35,7 @@ The intention of this workflow is that the discussion be closed from further com

### 3. Specification Pull Requests

When opening a specification PR, there are two document types: *Drafts* and *Candidate Specifications*. The type and status of any particular document has no bearing on the priority of that document. Typically, the further along in the process, the more likely it is that any particular XLS will be implemented or adopted.
When opening a specification PR, there are two document types: _Drafts_ and _Candidate Specifications_. The type and status of any particular document has no bearing on the priority of that document. Typically, the further along in the process, the more likely it is that any particular XLS will be implemented or adopted.

#### Drafts

Expand Down Expand Up @@ -66,7 +69,6 @@ Refinements in detail are still allowed and recommended. For example, you can cl

When a Draft is considered stable, there is a call for review from the community to publish the document as a Candidate Specification by making a PR to remove the `d` from the document folder name and update the `type` to `candidate-specification`.


Once published as a Candidate Specification, no further substantive changes are allowed under the same XLS number.

For Specifications that require changes or implementation in the XRP Ledger server software and protocol, the Candidate Specification cannot be published until the relevant change has been merged into [the software's `master` branch](https://github.com/XRPLF/rippled/tree/master).
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

XRP Ledger Standards (XLSs) describe standards and specifications relating to the XRP Ledger ecosystem that help achieve the following goals:

* Ensure interoperability and compatibility between XRP Ledger core protocol, ecosystem applications, tools, and platforms.
* Maintain a continued, excellent user experience around every application or system.
* Drive alignment and agreement in the XRPL community (i.e., developers, users, operators, etc).
- Ensure interoperability and compatibility between XRP Ledger core protocol, ecosystem applications, tools, and platforms.
- Maintain a continued, excellent user experience around every application or system.
- Drive alignment and agreement in the XRPL community (i.e., developers, users, operators, etc).

# [Contributing](./CONTRIBUTING.md)

The exact process for organizing and contributing to this repository is defined in [CONTRIBUTING.md](./CONTRIBUTING.md). If you would like to contribute, please read more there.
The exact process for organizing and contributing to this repository is defined in [CONTRIBUTING.md](./CONTRIBUTING.md). If you would like to contribute, please read more there.
4 changes: 2 additions & 2 deletions XLS-0002-destination-information/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ Where params may _all_ be optional except for the account address:
- `to` (account address, rXXXX..)
- `dt` (destination tag, uint32)
- `amount` (float, default currency: XRP (1000000 drops))
- ...
- ...

So App 1 may use:
https://someapp.com/sendXrp?to=...

... While App 2 uses:
https://anotherapp.net/deposit-xrp?to=...&dt=1234&amount=10
https://anotherapp.net/deposit-xrp?to=...&dt=1234&amount=10
133 changes: 71 additions & 62 deletions XLS-0002-destination-information/reference.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,84 @@
function xls2d(uri) {
const cleaned_uri = uri
.replace(/^(.*:.*)?\?/gm, "")
.replace(/\?/gim, "&")
.replace(/^.*?:\/\//, "")
.replace(/^ripple:/gim, "");

const cleaned_uri = uri.replace(/^(.*:.*)?\?/mg, "").replace(/\?/img, "&").replace(/^.*?:\/\//, '').replace(/^ripple:/img, "")
function clean() {
return cleaned_uri;
}

function clean() {
return cleaned_uri
}
function to() {
//NB: this regex is case sensitive to assist in correctly matching XRP ledger addresses
var match =
/(?:(?:^|&)(?:to|TO|tO|To)=|^)([rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz]{25,55})/gm.exec(
cleaned_uri,
);
return match == null ? false : match[1];
}

function to() {
//NB: this regex is case sensitive to assist in correctly matching XRP ledger addresses
var match = /(?:(?:^|&)(?:to|TO|tO|To)=|^)([rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz]{25,55})/mg.exec(cleaned_uri)
return (match == null ? false : match[1])
}
function dt() {
var match = /(?:^|&)dt=([0-9]+)|:([0-9]+)$/gim.exec(cleaned_uri);
if (match != null) return match[1] ? match[1] : match[2];
return false;
}

function dt() {
var match = /(?:^|&)dt=([0-9]+)|:([0-9]+)$/img.exec(cleaned_uri)
if (match != null) return (match[1] ? match[1] : match[2])
return false
}
function amount() {
var match = /(?:^|&)am(?:oun)?t=([0-9\.]+)/gim.exec(cleaned_uri);
return match == null ? false : match[1];
}

function amount() {
var match = /(?:^|&)am(?:oun)?t=([0-9\.]+)/img.exec(cleaned_uri)
return (match == null ? false : match[1])
}
function currency() {
var match =
/(?:^|&)cur(?:rency)?=(?:([rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz]{25,55}):)?([A-Z]{3}|[A-Fa-f]{40})/gim.exec(
cleaned_uri,
);
return match == null
? false
: { issuer: match[1] ? match[1] : false, currency: match[2] };
}

function currency() {
var match = /(?:^|&)cur(?:rency)?=(?:([rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz]{25,55}):)?([A-Z]{3}|[A-Fa-f]{40})/img.exec(cleaned_uri)
return (match == null ? false : { issuer: ( match[1] ? match[1] : false ), currency: match[2] } )
}
function invoiceid() {
var match = /(?:^|&)inv(?:oice)?(?:id)?=([a-f]{64})/gim.exec(cleaned_uri);
return match == null ? false : match[1];
}


function invoiceid() {
var match = /(?:^|&)inv(?:oice)?(?:id)?=([a-f]{64})/img.exec(cleaned_uri)
return (match == null ? false : match[1])
}


return {
uri: uri,
clean: clean(),
to: to(),
dt: dt(),
amount: amount(),
currency: currency(),
invoiceid: invoiceid()
}
return {
uri: uri,
clean: clean(),
to: to(),
dt: dt(),
amount: amount(),
currency: currency(),
invoiceid: invoiceid(),
};
}

var examples = [
"rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY?dt=123",
"rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY:123",
"https://ripple.com//send?to=rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY&amount=30&dt=123",
"https://sub.domain.site.edu.au//send?to=rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY&amount=30&dt=123",
"https://someapp.com/sendXrp?to=rRippleBlah&dt=4&invoiceid=abcdef",
"deposit-xrp?to=blah",
"?rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY:123",
"rAhDr1qUEG4gHXt6m6zyRE4oogDDWmYvcgotCqyyEpArk8",
"to=rAhDr1qUEG4gHXt6m6zyRE4oogDDWmXFdzQdZdH9SJzcNJ",
"to=rAhDr1qUEG4gHXt6m6zyRE4oogDDWmXFdzQdZdH9SJzcNJ&currency=rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B:USD",
"to=rAhDr1qUEG4gHXt6m6zyRE4oogDDWmXFdzQdZdH9SJzcNJ&currency=USD",
"to=rAhDr1qUEG4gHXt6m6zyRE4oogDDWmXFdzQdZdH9SJzcNJ&currency=rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B:USD&invid=DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF",
"scheme://uri/folders?rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY:123",
"scheme://uri/folders?rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY&amount=4:123", // this one a bit iffy
"XVLhHMPHU98es4dbozjVtdWzVrDjtV8xvjGQTYPiAx6gwDC",
"to=XVLhHMPHU98es4dbozjVtdWzVrDjtV8xvjGQTYPiAx6gwDC",
"ripple:XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u",
"ripple:XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u:58321",
"ripple:XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u:58321&currency=rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B:USD",
"ripple:XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u:58321&currency=XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u:ABC",
"xrpl://XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u",
"xrp://XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u",
"f3w54ygsdfgfserga"
]
"rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY?dt=123",
"rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY:123",
"https://ripple.com//send?to=rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY&amount=30&dt=123",
"https://sub.domain.site.edu.au//send?to=rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY&amount=30&dt=123",
"https://someapp.com/sendXrp?to=rRippleBlah&dt=4&invoiceid=abcdef",
"deposit-xrp?to=blah",
"?rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY:123",
"rAhDr1qUEG4gHXt6m6zyRE4oogDDWmYvcgotCqyyEpArk8",
"to=rAhDr1qUEG4gHXt6m6zyRE4oogDDWmXFdzQdZdH9SJzcNJ",
"to=rAhDr1qUEG4gHXt6m6zyRE4oogDDWmXFdzQdZdH9SJzcNJ&currency=rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B:USD",
"to=rAhDr1qUEG4gHXt6m6zyRE4oogDDWmXFdzQdZdH9SJzcNJ&currency=USD",
"to=rAhDr1qUEG4gHXt6m6zyRE4oogDDWmXFdzQdZdH9SJzcNJ&currency=rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B:USD&invid=DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF",
"scheme://uri/folders?rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY:123",
"scheme://uri/folders?rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY&amount=4:123", // this one a bit iffy
"XVLhHMPHU98es4dbozjVtdWzVrDjtV8xvjGQTYPiAx6gwDC",
"to=XVLhHMPHU98es4dbozjVtdWzVrDjtV8xvjGQTYPiAx6gwDC",
"ripple:XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u",
"ripple:XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u:58321",
"ripple:XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u:58321&currency=rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B:USD",
"ripple:XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u:58321&currency=XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u:ABC",
"xrpl://XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u",
"xrp://XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u",
"f3w54ygsdfgfserga",
];

for (var i in examples) console.log(xls2d(examples[i]));
2 changes: 1 addition & 1 deletion XLS-0003-deeplink-signed-transactions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ MSIE limits URL parsing to 2,083 chars. Safari 65k chars. Todo: need to test thi
P.S. Another option (proposal) would be to use a specific syntax (prefix) instead of fixed (one) folder; eg.
`https://xrpl-labs.com/xrpl:signed-transaction:<SIGNEDBLOB>`

... Where the fixed prefix in this case is `xrpl:signed-transaction:`.
... Where the fixed prefix in this case is `xrpl:signed-transaction:`.
2 changes: 1 addition & 1 deletion XLS-0004-trustline-uri/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ So for example

`anything://any.domain/url/?action=trustline&limit=10000&currency=rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B:USD&rippling=false`

I realise compounding the currency and issuer information is a little tacky here but we did it in the previous standard
I realise compounding the currency and issuer information is a little tacky here but we did it in the previous standard
Loading
Loading