WIP revised tutorials IA

This commit is contained in:
amarantha-k
2025-08-18 13:38:57 -07:00
parent 94686086ee
commit 9c01d13067
29 changed files with 72 additions and 118 deletions

View File

@@ -1,210 +0,0 @@
---
html: build-a-browser-wallet-in-javascript.html
parent: javascript.html
targets:
- en
- ja # TODO: translate this page
seo:
description: Build a graphical browser wallet for the XRPL using Javascript.
---
# Build a Browser Wallet in JavaScript
<!-- STYLE_OVERRIDE: wallet -->
This tutorial demonstrates how to build a browser wallet for the XRP Ledger using the Javascript programming language and various libraries. This application can be used as a starting point for building a more complete and powerful application, as a reference point for building comparable apps, or as a learning experience to better understand how to integrate XRP Ledger functionality into a larger project.
## Prerequisites
To complete this tutorial, you should meet the following guidelines:
1. You have [Node.js](https://nodejs.org/en/download/) v14 or higher installed.
2. You have [Yarn](https://yarnpkg.com/en/docs/install) (v1.17.3 or higher) installed.
3. You are somewhat familiar with coding with JavaScript and have completed the [Get Started Using JavaScript](./get-started.md) tutorial.
## Source Code
You can find the complete source code for all of this tutorial's examples in the {% repo-link path="_code-samples/build-a-browser-wallet/js/" %}code samples section of this website's repository{% /repo-link %}.
## Goals
At the end of this tutorial, you should be able to build a simple XRP wallet displayed below.
![Home Page Screenshot](/docs/img/js-wallet-home.png)
This application can:
- Show updates to the XRP Ledger in real-time.
- View any XRP Ledger account's activity, including showing how much XRP was delivered by each transaction.
- Show how much XRP is set aside for the account's [reserve requirement](../../../concepts/accounts/reserves.md).
- Send [direct XRP payments](../../../concepts/payment-types/direct-xrp-payments.md), and provide feedback about the intended destination address, including:
- Displaying your account's available balance
- Verifying that the destination address is valid
- Validating the account has enough XRP to send
- Allowing you to specify a destination tag
## Steps
Before you begin, make sure you have the prerequisites installed. Check your node version by running `node -v`. If necessary, [download Node.js](https://nodejs.org/en/download/).
{% admonition type="success" name="Tip" %}If you get stuck while doing this tutorial, or working on another project, feel free to ask for help in the XRPL's [Developer Discord](https://discord.com/invite/KTNmhJDXqa).{% /admonition %}
### 1. Set up the project
1. Navigate to the directory that you want to create the project in.
2. Create a new Vite project:
```bash
yarn create vite simple-xrpl-wallet --template vanilla
```
3. Create or modify the file `package.json` to have the following contents:
{% code-snippet file="/_code-samples/build-a-browser-wallet/js/package.json" language="js" /%}
- Alternatively you can also do `yarn add <package-name>` for each individual package to add them to your `package.json` file.
4. Install dependencies:
```bash
yarn
```
5. Create a new file `.env` in the root directory of the project and add the following variables:
```bash
CLIENT="wss://s.altnet.rippletest.net:51233/"
EXPLORER_NETWORK="testnet"
SEED="s████████████████████████████"
```
6. Change the seed to your own seed. You can get credentials from [the Testnet faucet](/resources/dev-tools/xrp-faucets).
7. Set up a Vite bundler. Create a file named `vite.config.js` in the root directory of the project and fill it with the following code:
{% code-snippet file="/_code-samples/build-a-browser-wallet/js/vite.config.js" language="js" /%}
8. Add script to `package.json`
In your `package.json` file, add the following section if it's not there already:
```json
"scripts": {
"dev": "vite"
}
```
### 2. Create the Home Page (Displaying Account & Ledger Details)
In this step, we create a home page that displays account and ledger details.
![Home Page Screenshot](/docs/img/js-wallet-home.png)
1. If not already present, create new files in the root folder named `index.html`, `index.js` and `index.css`.
2. Make a new folder named `src` in the root directory of the project.
3. Copy the contents of {% repo-link path="_code-samples/build-a-browser-wallet/js/index.html" %}index.html{% /repo-link %} in your code.
4. Add styling to your {% repo-link path="_code-samples/build-a-browser-wallet/js/index.css" %}index.css{% /repo-link %} file by following the link.
This basic setup creates a homepage and applies some visual styles. The goal is for the homepage to:
- Display our account info
- Show what's happening on the ledger
- And add a little logo for fun
To make that happen, we need to connect to the XRP Ledger and look up the account and the latest validated ledger.
5. In the `src/` directory, make a new folder named `helpers`. Create a new file there named `get-wallet-details.js` and define a function named `getWalletDetails` there. This function uses the [account_info method](../../../references/http-websocket-apis/public-api-methods/account-methods/account_info.md) to fetch account details and the [server_info method](../../../references/http-websocket-apis/public-api-methods/server-info-methods/server_info.md) to calculate the current [reserves](../../../concepts/accounts/reserves.md). The code to do all this is as follows:
{% code-snippet file="/_code-samples/build-a-browser-wallet/js/src/helpers/get-wallet-details.js" language="js" /%}
6. Now, let's add the code to `index.js` file to fetch the account and ledger details and display them on the home page. Copy the code written below to the `index.js` file. Here we render the wallet details using the function we defined in `get-wallet-details.js`. In order to make sure we have up to date ledger data, we are using the [ledger stream](../../../references/http-websocket-apis/public-api-methods/subscription-methods/subscribe.md#ledger-stream) to listen for ledger close events.
{% code-snippet file="/_code-samples/build-a-browser-wallet/js/index.js" language="js" /%}
7. In the `helpers` folder, add {% repo-link path="_code-samples/build-a-browser-wallet/js/src/helpers/render-xrpl-logo.js" %}render-xrpl-logo.js{% /repo-link %} to handle displaying a logo.
8. Finally create a new folder named `assets` in the `src/` directory and add the file {% repo-link path="_code-samples/build-a-browser-wallet/js/src/assets/xrpl.svg" %}`xrpl.svg`{% /repo-link %} there.
These files are used to render the XRPL logo for aesthetic purposes.
The one other thing we do here is add events to two buttons - one to send XRP and one to view transaction history. They won't work just yet — we'll implement them in the next steps.
Now the application is ready to run. You can start it in dev mode using the following command:
```bash
yarn dev
```
Your terminal should output a URL which you can use to open your app in a browser. This dev site automatically updates to reflect any changes you make to the code.
### 3. Create the Send XRP Page
Now that we've created the home page, we can move on to the "Send XRP" page. This is what allows this wallet to manage your account's funds.
![Send XRP Page Screenshot](/docs/img/js-wallet-send-xrp.png)
1. Create a folder named `send-xrp` in the `src` directory.
2. Inside the `send-xrp` folder, create two files named `send-xrp.js` and `send-xrp.html`.
3. Copy the contents of the {% repo-link path="_code-samples/build-a-browser-wallet/js/src/send-xrp/send-xrp.html" %}send-xrp.html{% /repo-link %} file to your `send-xrp.html` file. The provided HTML code includes three input fields for the destination address, amount, and destination tag, each with their corresponding labels.
4. Now that we have the HTML code, let's add the JavaScript code. In the `helpers` folder, create a new file named `submit-transaction.js` and copy the code written below to the file. In this file, we are using the [submit](../../../references/http-websocket-apis/public-api-methods/transaction-methods/submit.md) method to submit the transaction to the XRPL. Before submitting every transaction needs to be signed by a wallet, learn more about [signing](../../../references/http-websocket-apis/admin-api-methods/signing-methods/sign.md) a transaction.
{% code-snippet file="/_code-samples/build-a-browser-wallet/js/src/helpers/submit-transaction.js" language="js" /%}
5. Now back to the `send-xrp.js` file, copy the code written below to the file. In this piece of code we are first getting all the DOM elements from HTML and adding event listners to update & validate the fields based on the user input. Using `renderAvailableBalance` method we display the current available balance of the wallet. `validateAddress` function validates the user address, and the amount is validated using a regular expression. When all the fields are filled with correct inputs, we call the `submitTransaction` function to submit the transaction to the ledger.
{% code-snippet file="/_code-samples/build-a-browser-wallet/js/src/send-xrp/send-xrp.js" language="js" /%}
You can now click 'Send XRP' to try creating your own transaction! You can use this example to send XRP to the testnet faucet to try it out.
Testnet faucet account: `rHbZCHJSGLWVMt8D6AsidnbuULHffBFvEN`
Amount: 9
Destination Tag: (Not usually necessary unless you're paying an account tied to an exchange)
![Send XRP Transaction Screenshot](/docs/img/js-wallet-send-xrp-transaction-details.png)
### 4. Create the Transactions Page
Now that we have created the home page and the send XRP page, let's create the transactions page that will display the transaction history of the account. In order to see what's happening on the ledger, we're going to display the following fields:
- Account: The account that sent the transaction.
- Destination: The account that received the transaction.
- Transaction Type: The type of transaction.
- Result: The result of the transaction.
- Delivered amount: The amount of XRP or tokens delivered by the transaction, if applicable.
- Link: A link to the transaction on the XRP Ledger Explorer.
{% admonition type="warning" name="Caution" %}When displaying how much money a transaction delivered, always use the `delivered_amount` field from the metadata, not the `Amount` field from the transaction instructions. [Partial Payments](../../../concepts/payment-types/partial-payments.md) can deliver much less than the stated `Amount` and still be successful.{% /admonition %}
![Transactions Page Screenshot](/docs/img/js-wallet-transaction.png)
1. Create a folder named `transaction-history` in the src directory.
2. Create a file named `transaction-history.js` and copy the code written below.
{% code-snippet file="/_code-samples/build-a-browser-wallet/js/src/transaction-history/transaction-history.js" language="js" /%}
This code uses [account_tx](../../../references/http-websocket-apis/public-api-methods/account-methods/account_tx.md) to fetch transactions we've sent to and from this account. In order to get all the results, we're using the `marker` parameter to paginate through the incomplete list of transactions until we reach the end.
3. Create a file named `transaction-history.html` and copy the code from {% repo-link path="_code-samples/build-a-browser-wallet/js/src/transaction-history/transaction-history.html" %}transaction-history.html{% /repo-link %} into it.
`transaction-history.html` defines a table which displays the fields mentioned above.
You can use this code as a starting point for displaying your account's transaction history. If you want an additional challenge, try expanding it to support different transaction types (e.g. [TrustSet](../../../references/protocol/transactions/types/trustset.md)). If you want inspiration for how to handle this, you can check out the [XRP Ledger Explorer](https://livenet.xrpl.org/) to see how the transaction details are displayed.
## Next Steps
Now that you have a functional wallet, you can take it in several new directions. The following are a few ideas:
- You could support more of the XRP Ledger's [transaction types](../../../references/protocol/transactions/types/index.md) including [tokens](../../../concepts/tokens/index.md) and [cross-currency payments](../../../concepts/payment-types/cross-currency-payments.md)
- You could add support for displaying multiple tokens, beyond just XRP
- You could support creating [offers](../../../concepts/tokens/decentralized-exchange/offers.md) in the [decentralized exchange](../../../concepts/tokens/decentralized-exchange/index.md)
- You could add new ways to request payments, such as with QR codes or URIs that open in your wallet.
- You could support better account security including allowing users to set [regular key pairs](../../../concepts/accounts/cryptographic-keys.md#regular-key-pair) or handle [multi-signing](../../../concepts/accounts/multi-signing.md).
- Or you could take your code to production by following the [Building for Production with Vite](https://vitejs.dev/guide/build.html#public-base-path) guide.
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -1,366 +0,0 @@
---
seo:
description: Build a credential issuing microservice with Javascript and Node.js.
---
# Build a Credential Issuing Service
_(Requires the Credentials amendment. {% not-enabled /%})_
This tutorial demonstrates how to build and use a microservice that issues [Credentials](../../../concepts/decentralized-storage/credentials.md) on the XRP Ledger, in the form of a RESTlike API, using the [Express](https://expressjs.com/) framework for Node.js.
## Prerequisites
To complete this tutorial, you should meet the following guidelines:
- You have [Node.js](https://nodejs.org/en/download/) v18 or higher installed.
- You are somewhat familiar with modern JavaScript programming and have completed the [Get Started Using JavaScript tutorial](./get-started.md).
- You have some understanding of the XRP Ledger, its capabilities, and of cryptocurrency in general. Ideally you have completed the [Basic XRPL guide](https://learn.xrpl.org/).
## Setup
First, download the complete sample code for this tutorial from GitHub:
- {% repo-link path="_code-samples/issue-credentials/js/" %}Credential Issuing Service sample code{% /repo-link %}
Then, in the appropriate directory, install the dependencies:
```sh
npm install
```
This should install appropriate versions of Express, xrpl.js and a few other dependencies. You can view all dependencies in the {% repo-link path="_code-samples/issue-credentials/js/package.json" %}`package.json`{% /repo-link %} file.
To use the API that this microservice provides, you also need an HTTP client such as [Postman](https://www.postman.com/downloads/), [RESTED](https://github.com/RESTEDClient/RESTED), or [cURL](https://curl.se/).
## Overview
The Credential Issuer microservice, mostly implemented in `issuer_service.js`, provides a RESTlike API with the following methods:
| Method | Description |
|---|----|
| `POST /credential` | Request that the issuer issue a specific credential to a specific account. |
| `GET /admin/credential` | List all credentials issued by the issuer's address, optionally filtering only for credentials that have or have not been accepted by their subject. |
| `DELETE /admin/credential` | Delete a specific credential from the XRP Ledger, which revokes it. |
{% admonition type="info" name="Note" %}Some of the methods have `/admin` in the path because they are intended to be used by the microservice's administrator. However, the sample code does not implement any authentication.{% /admonition %}
The sample code also contains a simple commmandline interface for a user account to accept a credential issued to it, as `accept_credential.js`.
The other files contain helper code that is used by one or both tools.
## Usage
### 1. Get Accounts
To use the credential issuing service, you need two accounts on the Devnet, where the Credentials amendment is already enabled. Go to the [XRP Faucets page](../../../../resources/dev-tools/xrp-faucets.page.tsx) and select **Devnet**. Then, click the button to Generate credentials, saving the key pair (address and secret), twice. You will use one of these accounts as a **credential issuer** and the other account as the **credential subject** (holder), so make a note of which is which.
### 2. Start Issuer Service
To start the issuer microservice, run the following command from the directory with the sample code:
```sh
node issuer_service.js
```
It should prompt you for your **issuer account** seed. Input the secret key you saved previously and press Enter.
The output should look like the following:
```txt
✔ Issuer account seed:
✅ Starting credential issuer with XRPL address rPLY4DWhB4VA7PPZ8nvZLhShXeVZqeKif3
🔐 Credential issuer service running on port: 3005
```
Double-check that the XRPL address displayed matches the address of the credential issuer keys you saved earlier.
### 3. Request Credential
To request a credential, make a request such as the following:
{% tabs %}
{% tab label="Summary" %}
* HTTP method: `POST`
* URL: `http://localhost:3005/credential`
* Headers:
* `Content-Type: application/json`
* Request Body:
```json
{
"subject": "rBqPPjAW6ubfFdmwERgajvgP5LtM4iQSQG",
"credential": "TestCredential",
"documents": {
"reason": "please"
}
}
```
{% /tab %}
{% tab label="cURL" %}
```sh
curl -H "Content-Type: application/json" -X POST -d '{"subject": "rBqPPjAW6ubfFdmwERgajvgP5LtM4iQSQG", "credential": "TestCredential", "documents": {"reason": "please"}}' http://localhost:3005/credential
```
{% /tab %}
{% /tabs %}
The parameters of the JSON request body should be as follows:
| Field | Type | Required? | Description |
|---|---|---|---|
| `subject` | String - Address | Yes | The XRPL classic address of the subject of the credential. Set this to the address that you generated at the start of this tutorial for the credential holder account. |
| `credential` | String | Yes | The type of credential to issue. The example microservice accepts any string consisting of alphanumeric characters as well as the special characters underscore (`_`), dash (`-`), and period (`.`), with a minimum length of 1 and a maximum length of 64 characters. |
| `documents` | Object | Yes | As a credential issuer, you typically need to verify some confidential information about someone before you issue them a credential. As a placeholder, the sample code checks for a nested field named `reason` that contains the string `please`. |
| `expiration` | String - ISO8601 Datetime | No | The time after which the credential expires, such as `2025-12-31T00:00:00Z`. |
| `uri` | String | No | Optional URI data to store with the credential. This data will become public on the XRP Ledger. If provided, this must be a string with minimum length 1 and max length 256, consisting of only characters that are valid in URIs, which are numbers, letters, and the following special characters: `-._~:/?#[]@!$&'()*+,;=%`. Conventionally, it should link to a Verifiable Credential document as defined by the W3C. |
This microservice immediately issues any credential that the user requests. A successful response from the API uses the HTTP status code `201 Created` and has a response body with the result of submitting the transaction to the XRP Ledger. You can use the `hash` value from the response to look up the transaction using an explorer such as [https://devnet.xrpl.org/](https://devnet.xrpl.org/).
{% admonition type="warning" name="Differences from Production" %}For a real credential issuer, you would probably check the credential type and only issue specific types of credentials, or maybe even just one type. <br><br> If checking the user's documents requires human intervention or takes longer than the amount of time an API request should wait to respond, you would need to store credential requests to some kind of storage, like a SQL database. You might also want to add a separate method for admins (or automated processes) to reject or issue the credential after checking the documents.{% /admonition %}
### 4. List Credentials
To show a list of credentials issued by the issuing account, make the following request:
{% tabs %}
{% tab label="Summary" %}
* HTTP method: `GET`
* URL: `http://localhost:3005/admin/credential`
* Query parameters (optional): Use `?accepted=yes` to filter results to only credentials that the subject has accepted, or `?accepted=no` for credentials the user has not accepted.
{% /tab %}
{% tab label="cURL" %}
```sh
curl http://localhost:3005/admin/credential
```
{% /tab %}
{% /tabs %}
A response could look like the following:
```json
{
"credentials": [
{
"subject": "rBqPPjAW6ubfFdmwERgajvgP5LtM4iQSQG",
"credential": "TstCredential",
"accepted": true
}
]
}
```
In the response, each entry in the `credentials` array represents a Credential issued by the issuer account and stored in the blockchain. The details should match the request from the previous step, except that the `documents` are omitted because they are not saved on the blockchain.
### 5. Accept Credential
For a credential to be valid, the subject of the credential has to accept it. You can use `accept_credential.js` to do this:
```sh
node accept_credential.js
```
It should prompt you for your **subject account** seed. Input the secret key you saved previously and press Enter.
The script displays a list of Credentials that have been issued to your account and have not been accepted yet. Use the arrrow keys to scroll through the choices in the prompt and select the credential you want to accept, then press Enter. For example:
```text
✔ Subject account seed:
? Accept a credential?
0) No, quit.
1) 'TstzzzCredential' issued by rPLY4DWhB4VA7PPZ8nvZLhShXeVZqeKif3
2) 'Tst9Credential' issued by rPLY4DWhB4VA7PPZ8nvZLhShXeVZqeKif3
3) 'TCredential1' issued by rPLY4DWhB4VA7PPZ8nvZLhShXeVZqeKif3
4) 'Tst1Credential' issued by rPLY4DWhB4VA7PPZ8nvZLhShXeVZqeKif3
5) 'Tst0Credential' issued by rPLY4DWhB4VA7PPZ8nvZLhShXeVZqeKif3
6) 'Tst6Credential' issued by rPLY4DWhB4VA7PPZ8nvZLhShXeVZqeKif3
```
### 6. Revoke Credential
To revoke an issued credential, make a request such as the following:
{% tabs %}
{% tab label="Summary" %}
* HTTP method: `DELETE`
* URL: `http://localhost:3005/admin/credential`
* Headers:
* `Content-Type: application/json`
* Request Body:
```json
{
"subject": "rBqPPjAW6ubfFdmwERgajvgP5LtM4iQSQG",
"credential": "TestCredential"
}
```
{% /tab %}
{% tab label="cURL" %}
```sh
curl -H "Content-Type: application/json" -X DELETE -d '{"subject": "rBqPPjAW6ubfFdmwERgajvgP5LtM4iQSQG", "credential": "TestCredential"}' http://localhost:3005/admin/credential
```
{% /tab %}
{% /tabs %}
The parameters of the JSON request body should be as follows:
| Field | Type | Required? | Description |
|---|---|---|---|
| `subject` | String - Address | Yes | The XRPL classic address of the subject of the credential to revoke. |
| `credential` | String | Yes | The type of credential to revoke. This must match a credential type previously issued. |
A successful response from the API uses the HTTP status code `200 OK` and has a response body with the result of submitting the transaction to the XRP Ledger. You can use the `hash` value from the response to look up the transaction using an explorer.
## Code Walkthrough
The code for this tutorial is divided among the following files:
| File | Purpose |
|---|---|
| `accept_credential.js` | Commandline interface for a credential subject to look up and accept Credentials. |
| `credential.js` | Provides functions that validate credential input, verify supporting documents, and convert between the microservices simplified Credential format and the full XRPL representation of Credentials. |
| `errors.js` | Custom error classes that standardize how the server reports validation errors and XRPL transaction failures. |
| `issuer_service.js` | Defines the microservice as an Express app, including API methods and error handling. |
| `look_up_credentials.js` | A helper function for looking up Credentials tied to an account, including pagination and filtering, used by both the credential issuer and holder. |
### accept_credential.js
This file is meant to be run as a commandline tool so it starts with a [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)), followed by dependencies grouped by type: external packages (Node.js modules) first, and local modules last.
{% code-snippet file="/_code-samples/issue-credentials/js/accept_credential.js" language="js" before="const XRPL_SERVER =" /%}
It returns a `Wallet` instance in the `initWallet()` function, with the subject account's key pair, using a seed either passed as an environment variable, or input as a password:
{% code-snippet file="/_code-samples/issue-credentials/js/accept_credential.js" language="js" from="const XRPL_SERVER" before="async function main()" /%}
The `main()` function contains the core logic for the script. At the begining of the function it sets up the XRPL client, and calls `initWallet()` to instantiate a `Wallet` object:
{% code-snippet file="/_code-samples/issue-credentials/js/accept_credential.js" language="js" from="async function main()" before="const pendingCredentials =" /%}
It then looks up pending credentials using the `lookUpCredentials(...)` function imported from `look_up_credentials.js`:
{% code-snippet file="/_code-samples/issue-credentials/js/accept_credential.js" language="js" from="const pendingCredentials = " before="const choices" /%}
Next is a text menu that displays each of the unaccepted credentials returned by the lookup, as well as the option to quit:
{% code-snippet file="/_code-samples/issue-credentials/js/accept_credential.js" language="js" from="choices = " before="const chosenCred = " /%}
If the user picked a credential, the code constructs a [CredentialAccept transaction][], signs and submits it, and waits for it to be validated by consensus before displaying the result.
{% code-snippet file="/_code-samples/issue-credentials/js/accept_credential.js" language="js" from="const chosenCred = " before="main().catch" /%}
Finally, the code runs the `main()` function:
{% code-snippet file="/_code-samples/issue-credentials/js/accept_credential.js" language="js" from="main().catch" /%}
### issuer_service.js
This file defines the Express app of the issuer microservice. It opens by importing dependencies, grouped into external packages and local files:
{% code-snippet file="/_code-samples/issue-credentials/js/issuer_service.js" language="js" before="dotenv.config()" /%}
It returns a `Wallet` instance in the `initWallet()` function, with the subject account's key pair, using a seed either passed as an environment variable, or input as a password:
{% code-snippet file="/_code-samples/issue-credentials/js/issuer_service.js" language="js" from="dotenv.config()" before="// Error handling" /%}
A function called `handleAppError(...)` is defined to handle errors thrown by the microservice.
{% code-snippet file="/_code-samples/issue-credentials/js/issuer_service.js" language="js" from="// Error handling" before="async function main()" /%}
The `main()` function contains the core logic for the script. At the begining of the function it sets up the XRPL client, and calls `initWallet()` to instantiate a `Wallet` object:
{% code-snippet file="/_code-samples/issue-credentials/js/issuer_service.js" language="js" from="async function main()" before="// Define Express app" /%}
Next, it creates the Express app:
{% code-snippet file="/_code-samples/issue-credentials/js/issuer_service.js" language="js" from="// Define Express app" before="// POST /credential" /%}
After that come the definitions for the three API methods, starting with `POST /credential`. Users call this method to request a credential from the service. This method parses the request body as JSON and validates it. If this succeeds, it uses the data to fill out a `CredentialCreate` transaction. Finally, it checks the transaction's [result](../../../references/protocol/transactions/transaction-results/index.md) to decide which HTTP response code to use:
{% code-snippet file="/_code-samples/issue-credentials/js/issuer_service.js" language="js" from="// POST /credential" before="// GET /admin/credential" /%}
The next API method is `GET /admin/credential`, which looks up credentials issued by the service. It uses the `lookUpCredentials(...)` method defined in `look_up_credentials.js` to get a list of credentials. Then it calls the `serializeCredential(...)` and `parseCredentialFromXrpl(...)` functions, imported from `credential.js`, to transform each ledger entry from the XRP Ledger format to the simplified representation the microservice uses.
{% code-snippet file="/_code-samples/issue-credentials/js/issuer_service.js" language="js" from="// GET /admin/credential" before="// DELETE /admin/credential" /%}
The final API method, `DELETE /admin/credential`, deletes a Credential from the ledger, revoking it. This again uses functions from `credential.js` to validate user inputs and translate them into XRPL format where necessary. After that, it attempts to look up the Credential in the ledger and returns an error if it doesn't exist. This way, the issuer doesn't have to pay the cost of sending a transaction that would fail. Finally, the method checks the transaction result and sets the HTTP response code accordingly.
{% code-snippet file="/_code-samples/issue-credentials/js/issuer_service.js" language="js" from="// DELETE /admin/credential" before="const PORT = process.env.PORT" /%}
The port for the microservice is set to either an environment variable called `PORT` or to `3000`, and the application listens for connections at the assigned port:
{% code-snippet file="/_code-samples/issue-credentials/js/issuer_service.js" language="js" from="const PORT = process.env.PORT" before="// Start the server" /%}
Finally, the code runs the `main()` function:
{% code-snippet file="/_code-samples/issue-credentials/js/issuer_service.js" language="js" from="// Start the server" before="/**" /%}
### look_up_credentials.js
This file implements lookup of Credentials. Both the issuer code and the subject code use this function to look up their own credentials.
This code performs [pagination using markers](../../../references/http-websocket-apis/api-conventions/markers-and-pagination.md) to get all the results from the ledger. It also filters results based on the issuer/subject account, so that lookup by issuer, for example, doesn't include credentials that someone else issued _to_ the issuer account. Finally, it can optionally check the accepted status of the Credentials and only include ones that are or aren't accepted.
{% code-snippet file="/_code-samples/issue-credentials/js/look_up_credentials.js" language="js" /%}
### credential.js
This file defines a set of helper functions that validate credential related input, verify request data, and convert between the issuer microservice's simplified Credential format and the XRP Ledger object representation. It throws typed errors on invalid input.
The file starts with importing dependencies, grouped into external packages and local files:
{% code-snippet file="/_code-samples/issue-credentials/js/credential.js" before="// Regex constants" language="js" /%}
It then defines regular expression constants that are used further on in the code to validate the credential and uri:
{% code-snippet file="/_code-samples/issue-credentials/js/credential.js" from="// Regex constants" before="/**" language="js" /%}
The function `validateCredentialRequest(...)` checks that the user input meets various requirements. It also parses the user-provided timestamp from a string to a native Javascript Date object if necessary.
{% code-snippet file="/_code-samples/issue-credentials/js/credential.js" from="/**" before="// Convert " language="js" /%}
The `credentialFromXrpl(...)` function converts an XRPL ledger entry into a usable credential object (for example, converting the credential field from hexadecimal to a native string). The API methods that read data from the XRP Ledger use this function so that their output is formatted the same way as user input in the other API methods.
{% code-snippet file="/_code-samples/issue-credentials/js/credential.js" from="// Convert an XRPL ledger" before="// Convert to an object" language="js" /%}
The `credentialToXrpl(...)` function returns an object which is formatted for submitting to the XRP Ledger:
{% code-snippet file="/_code-samples/issue-credentials/js/credential.js" from="Convert to an object" before="export function verifyDocuments" language="js" /%}
Finally, the `verifyDocuments(...)` function checks for an additional field, `documents`. For a realistic credential issuer, you might require the user to provide specific documents in the request body, like a photo of their government-issued ID or a cryptographically signed message from another business, which your code would check. For this tutorial, the check is only a placeholder:
{% code-snippet file="/_code-samples/issue-credentials/js/credential.js" from="export function verifyDocuments" language="js" /%}
### errors.js
This file defines custom error classes used by the credential issuer service to provide consistent error handling and help distinguish between different kinds of failures:
{% code-snippet file="/_code-samples/issue-credentials/js/errors.js" language="js" /%}
## Next Steps
Using this service as a base, you can extend the service with more features, such as:
- Security/authentication to protect API methods from unauthorized use.
- Actually checking user documents to decide if you should issue a credential.
Alternatively, you can use credentials to for various purposes, such as:
- Define a [Permissioned Domain](/docs/concepts/tokens/decentralized-exchange/permissioned-domains) that uses your credentials to grant access to features on the XRP Ledger.
- [Verify credentials](../compliance/verify-credential.md) manually to grant access to services that exist off-ledger.
## See Also
- [Python: Build a Credential Issuing Service](../../python/build-apps/credential-issuing-service.md)
{% raw-partial file="/docs/_snippets/common-links.md" /%}

View File

@@ -1,173 +0,0 @@
---
html: get-started-using-javascript-library.html
parent: javascript.html
seo:
description: Build an entry-level JavaScript application for querying the XRP Ledger.
top_nav_name: JavaScript
top_nav_grouping: Get Started
labels:
- Development
showcase_icon: assets/img/logos/javascript.svg
---
# Get Started Using JavaScript Library
This tutorial guides you through the basics of building an XRP Ledger-connected application in JavaScript or TypeScript using the [`xrpl.js`](https://github.com/XRPLF/xrpl.js/) client library in either Node.js or web browsers.
The scripts and config files used in this guide are {% repo-link path="_code-samples/get-started/js/" %}available in this website's GitHub Repository{% /repo-link %}.
## Learning Goals
In this tutorial, you'll learn:
* The basic building blocks of XRP Ledger-based applications.
* How to connect to the XRP Ledger using `xrpl.js`.
* How to get an account on the [Testnet](/resources/dev-tools/xrp-faucets) using `xrpl.js`.
* How to use the `xrpl.js` library to look up information about an account on the XRP Ledger.
* How to put these steps together to create a JavaScript app or web-app.
## Requirements
To follow this tutorial, you should have some familiarity with writing code in JavaScript and managing small JavaScript projects. In browsers, any modern web browser with JavaScript support should work fine. In Node.js, **version 14** is recommended. Node.js versions 12 and 16 are also regularly tested.
## Install with npm
Start a new project by creating an empty folder, then move into that folder and use [NPM](https://www.npmjs.com/) to install the latest version of xrpl.js:
```sh
npm install xrpl
```
## Start Building
When you're working with the XRP Ledger, there are a few things you'll need to manage, whether you're adding XRP to your [account](../../../concepts/accounts/index.md), integrating with the [decentralized exchange](../../../concepts/tokens/decentralized-exchange/index.md), or [issuing tokens](../../../concepts/tokens/index.md). This tutorial walks you through basic patterns common to getting started with all of these use cases and provides sample code for implementing them.
Here are some steps you use in many XRP Ledger projects:
1. [Import the library.](#1-import-the-library)
1. [Connect to the XRP Ledger.](#2-connect-to-the-xrp-ledger)
1. [Get an account.](#3-get-account)
1. [Query the XRP Ledger.](#4-query-the-xrp-ledger)
1. [Listen for Events.](#5-listen-for-events)
### 1. Import the Library
How you load `xrpl.js` into your project depends on your development environment:
#### Web Browsers
Add a `<script>` tag such as the following to your HTML:
```html
<script src="https://unpkg.com/xrpl/build/xrpl-latest-min.js"></script>
```
You can load the library from a CDN as in the above example, or download a release and host it on your own website.
This loads the module into the top level as `xrpl`.
#### Node.js
Add the library using [npm](https://www.npmjs.com/). This updates your `package.json` file, or creates a new one if it didn't already exist:
```sh
npm install xrpl
```
Then import the library:
```js
const xrpl = require("xrpl")
```
### 2. Connect to the XRP Ledger
To make queries and submit transactions, you need to connect to the XRP Ledger. To do this with `xrpl.js`, you create an instance of the `Client` class and use the `connect()` method.
{% admonition type="success" name="Tip" %}Many network functions in `xrpl.js` use [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) to return values asynchronously. The code samples here use the [`async/await` pattern](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await) to wait for the actual result of the Promises.{% /admonition %}
{% code-snippet file="/_code-samples/get-started/js/base.js" language="js" /%}
#### Connect to the XRP Ledger Mainnet
The sample code in the previous section shows you how to connect to the Testnet, which is one of the available [parallel networks](../../../concepts/networks-and-servers/parallel-networks.md). When you're ready to move to production, you'll need to connect to the XRP Ledger Mainnet. You can do that in two ways:
* By [installing the core server](../../../infrastructure/installation/index.md) (`rippled`) and running a node yourself. The core server connects to the Mainnet by default, but you can [change the configuration to use Testnet or Devnet](../../../infrastructure/configuration/connect-your-rippled-to-the-xrp-test-net.md). [There are good reasons to run your own core server](../../../concepts/networks-and-servers/index.md#reasons-to-run-your-own-server). If you run your own server, you can connect to it like so:
```
const MY_SERVER = "ws://localhost:6006/"
const client = new xrpl.Client(MY_SERVER)
await client.connect()
```
See the example [core server config file](https://github.com/XRPLF/rippled/blob/c0a0b79d2d483b318ce1d82e526bd53df83a4a2c/cfg/rippled-example.cfg#L1562) for more information about default values.
* By using one of the available [public servers][]:
```
const PUBLIC_SERVER = "wss://xrplcluster.com/"
const client = new xrpl.Client(PUBLIC_SERVER)
await client.connect()
```
### 3. Get Account
The `xrpl.js` library has a `Wallet` class for handling the keys and address of an XRP Ledger account. On Testnet, you can fund a new account like this:
{% code-snippet file="/_code-samples/get-started/js/get-acct-info.js" from="// Create a wallet" before="// Get info" language="js" /%}
If you only want to generate keys, you can create a new `Wallet` instance like this:
```js
const test_wallet = xrpl.Wallet.generate()
```
Or, if you already have a seed encoded in [base58][], you can make a `Wallet` instance from it like this:
```js
const test_wallet = xrpl.Wallet.fromSeed("sn3nxiW7v8KXzPzAqzyHXbSSKNuN9") // Test secret; don't use for real
```
### 4. Query the XRP Ledger
Use the Client's `request()` method to access the XRP Ledger's [WebSocket API](../../../references/http-websocket-apis/api-conventions/request-formatting.md). For example:
{% code-snippet file="/_code-samples/get-started/js/get-acct-info.js" from="// Get info" before="// Listen to ledger close events" language="js" /%}
### 5. Listen for Events
You can set up handlers for various types of events in `xrpl.js`, such as whenever the XRP Ledger's [consensus process](../../../concepts/consensus-protocol/index.md) produces a new [ledger version](../../../concepts/ledgers/index.md). To do that, first call the [subscribe method][] to get the type of events you want, then attach an event handler using the `on(eventType, callback)` method of the client.
{% code-snippet file="/_code-samples/get-started/js/get-acct-info.js" from="// Listen to ledger close events" before="// Disconnect when done" language="js" /%}
## Keep on Building
Now that you know how to use `xrpl.js` to connect to the XRP Ledger, get an account, and look up information about it, you can also:
* [Send XRP](../../how-tos/send-xrp.md).
* [Issue a Fungible Token](../../how-tos/use-tokens/issue-a-fungible-token.md)
* [Set up secure signing](../../../concepts/transactions/secure-signing.md) for your account.
## See Also
- **Concepts:**
- [XRP Ledger Overview](/about/)
- [Client Libraries](../../../references/client-libraries.md)
- **Tutorials:**
- [Send XRP](../../how-tos/send-xrp.md)
- **References:**
- [`xrpl.js` Reference](https://js.xrpl.org/)
- [Public API Methods](../../../references/http-websocket-apis/public-api-methods/index.md)
- [API Conventions](../../../references/http-websocket-apis/api-conventions/index.md)
- [base58 Encodings](../../../references/protocol/data-types/base58-encodings.md)
- [Transaction Formats](../../../references/protocol/transactions/index.md)
{% raw-partial file="/docs/_snippets/common-links.md" /%}