-
-
-
-
\ No newline at end of file
diff --git a/_code-samples/modular-tutorials/permissioned-domain-manager.js b/_code-samples/modular-tutorials/permissioned-domain-manager.js
deleted file mode 100644
index 71a2b9086d..0000000000
--- a/_code-samples/modular-tutorials/permissioned-domain-manager.js
+++ /dev/null
@@ -1,127 +0,0 @@
-/// Create permissioned domain
-async function createDomain() {
-
- let net = getNet()
- const client = new xrpl.Client(net)
- results = `\n\n===Creating Permissioned Domain===\n\nConnecting to ${getNet()} ...`
- updateResults()
- await client.connect()
- results = `\n\nConnected.`
- updateResults()
-
- // Gather transaction info
- try {
-
- // Get account wallet from seed
- const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
-
- // Get Domain ID
- const domainID = domainIDField.value
-
- // Get credential type - convert string to hex if needed
- let credentialType = credentialTypeField.value;
- if (!/^[0-9A-F]+$/i.test(credentialType)) {
- let hex = '';
- for (let i = 0; i < credentialType.length; i++) {
- const charCode = credentialType.charCodeAt(i);
- const hexCharCode = charCode.toString(16).padStart(2, '0');
- hex += hexCharCode;
- }
- credentialType = hex.toUpperCase();
- }
-
- // Prepare transaction
- const transaction = {
- "TransactionType": "PermissionedDomainSet",
- "Account": wallet.address,
- "AcceptedCredentials": [
- {
- "Credential": {
- "Issuer": wallet.address,
- "CredentialType": credentialType
- }
- }
- ]
- }
-
- if (domainID) {
- transaction.DomainID = domainID
- }
-
- results = `\n\n===Preparing and Sending Transaction===\n\n${JSON.stringify(transaction, null, 2)}`
- updateResults()
-
- // Submit transaction
- const tx = await client.submitAndWait(transaction, {autofill: true, wallet: wallet})
-
- if (tx.result.meta.TransactionResult == "tesSUCCESS") {
- // Parse for domain info
- if (domainID) {
- results = `\n\n===Create Permissioned Domain Result===\n\n${JSON.stringify(tx.result.tx_json, null, 2)}`
- } else {
- const parsedResponse = JSON.parse(JSON.stringify(tx.result.meta.AffectedNodes, null, 2))
- const domainInfo = parsedResponse.find( node => node.CreatedNode && node.CreatedNode.LedgerEntryType === "PermissionedDomain" )
- results = `\n\n===Create Permissioned Domain Result===\n\n${JSON.stringify(domainInfo.CreatedNode, null, 2)}`
- }
- } else {
- results = `\n\n===Error===\n\n${JSON.stringify(tx.result.meta.TransactionResult, null, 2)}: Check codes at https://xrpl.org/docs/references/protocol/transactions/types/permissioneddomainset#error-cases`
- }
- updateResults()
-
- } catch (error) {
- results = `\n\n===Error===\n\n${error}`
- updateResults()
- }
-
- client.disconnect()
-}
-// End create permissioned domain
-
-
-// Delete permissioned domain
-async function deleteDomain() {
-
- let net = getNet()
- const client = new xrpl.Client(net)
- results = `\n\n===Delete Permissioned Domain===\n\nConnecting to ${getNet()} ...`
- updateResults()
- await client.connect()
- results = `\n\nConnected.`
- updateResults()
-
- // Get delete domain transaction info
- try {
-
- // Get account wallet from seed
- const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
-
- // Get Domain ID
- const domainID = domainIDField.value
-
- // Prepare transaction
- const transaction = {
- "TransactionType": "PermissionedDomainDelete",
- "Account": wallet.address,
- "DomainID": domainID
- }
-
- results = `\n\n===Preparing and Sending Transaction===\n\n${JSON.stringify(transaction, null, 2)}`
- updateResults()
-
- // Submit delete domain transaction
- const tx = await client.submitAndWait(transaction, {autofill: true, wallet: wallet})
-
- if (tx.result.meta.TransactionResult == "tesSUCCESS") {
- results = `\n\n===Delete Permissioned Domain Result===\n\nSuccessfully deleted the permissioned domain.`
- } else {
- results = `\n\n===Error===\n\n${JSON.stringify(tx.result.meta.TransactionResult, null, 2)}: Check codes at https://xrpl.org/docs/references/protocol/transactions/types/permissioneddomaindelete#error-cases`
- }
- updateResults()
-
- } catch (error) {
- results = `\n\n===Error===\n\n${error}`
- updateResults()
- }
-
- client.disconnect()
-}
diff --git a/_code-samples/permissioned-domains/js/create-domain.js b/_code-samples/permissioned-domains/js/create-domain.js
new file mode 100644
index 0000000000..2df8e4ea7c
--- /dev/null
+++ b/_code-samples/permissioned-domains/js/create-domain.js
@@ -0,0 +1,73 @@
+import xrpl from 'xrpl'
+import { stringToHex } from '@xrplf/isomorphic/dist/utils/index.js'
+import fs from 'fs'
+
+// Get issuer wallet and define constants -------------------------------------
+const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233')
+await client.connect()
+console.log('Getting a new account from the faucet.')
+const { wallet } = await client.fundWallet()
+console.log(`Account funded:
+ Address: ${wallet.address}
+ Seed: ${wallet.seed}
+`)
+
+const issuerAddress = wallet.address // Can also use a third-party issuer
+const credentialType = stringToHex("my-credential")
+
+// Create a domain ------------------------------------------------------------
+const pDomainSet = {
+ TransactionType: "PermissionedDomainSet",
+ Account: wallet.address,
+ AcceptedCredentials: [
+ {
+ Credential: {
+ Issuer: issuerAddress,
+ CredentialType: credentialType
+ }
+ }
+ ]
+}
+
+console.log('Submitting transaction', JSON.stringify(pDomainSet, null, 2))
+const response = await client.submitAndWait(pDomainSet, { wallet, autofill: true})
+console.log(response)
+const resultCode = response.result.meta.TransactionResult
+if (resultCode !== 'tesSUCCESS') {
+ console.error(`PermissionedDomainSet failed with code ${resultCode}`)
+ client.disconnect()
+ process.exit(2)
+}
+
+console.log('Successfully created permissioned domain.')
+
+// Find Domain ID in metadata -------------------------------------------------
+let domainID
+for (const modifiedNode of response.result.meta.AffectedNodes) {
+ if (modifiedNode.CreatedNode?.LedgerEntryType === 'PermissionedDomain') {
+ domainID = modifiedNode.CreatedNode.LedgerIndex
+ break
+ }
+}
+if (!domainID) {
+ console.error("Couldn't find a created PermissionedDomain in transaction "+
+ "metadata. This is not typical.")
+ client.disconnect()
+ process.exit(3)
+}
+console.log('Domain ID of created domain:', domainID)
+
+client.disconnect()
+
+// Save config for other scripts ----------------------------------------------
+const configData = {
+ description: "This file is auto-generated by create-domain.js. "+
+ "It stores account and domain info for the other tutorial scripts.",
+ owner: {
+ address: wallet.address,
+ seed: wallet.seed
+ },
+ issuer_address: issuerAddress,
+ domain_id: domainID
+}
+fs.writeFileSync('setup.json', JSON.stringify(configData, null, 2))
diff --git a/_code-samples/permissioned-domains/js/delete-domain.js b/_code-samples/permissioned-domains/js/delete-domain.js
new file mode 100644
index 0000000000..91eb1a8241
--- /dev/null
+++ b/_code-samples/permissioned-domains/js/delete-domain.js
@@ -0,0 +1,46 @@
+import xrpl from 'xrpl'
+import { stringToHex } from '@xrplf/isomorphic/dist/utils/index.js'
+import fs from 'fs'
+
+// Set up client --------------------------------------------------------------
+const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233')
+await client.connect()
+
+// Load setup data ------------------------------------------------------------
+if (!fs.existsSync('setup.json')) {
+ console.error('Config data not found. Did you run create_domain.py first?')
+ process.exit(1)
+}
+const configData = JSON.parse(fs.readFileSync('setup.json', 'utf8'))
+const wallet = xrpl.Wallet.fromSeed(configData.owner.seed)
+if (wallet.address !== configData.owner.address) {
+ console.error('Address did not match saved value. Did you use the wrong ',
+ 'cryptographic algorithm?',
+ '\n\tSaved:', configData.owner.address,
+ '\n\tGenerated:', wallet.address)
+ client.disconnect()
+ process.exit(2)
+}
+
+const domainID = configData.domain_id
+
+console.log('Domain ID:', domainID)
+console.log('Domain owner:', wallet.address)
+
+// Delete a permissioned domain -----------------------------------------------
+const pDomainDel = {
+ TransactionType: "PermissionedDomainDelete",
+ Account: wallet.address,
+ DomainID: domainID
+}
+console.log('Submitting transaction', JSON.stringify(pDomainDel, null, 2))
+const response = await client.submitAndWait(pDomainDel, { wallet, autofill: true})
+console.log(response)
+const resultCode = response.result.meta.TransactionResult
+if (resultCode !== 'tesSUCCESS') {
+ console.error(`PermissionedDomainDelete failed with code ${resultCode}`)
+ client.disconnect()
+ process.exit(3)
+}
+console.log('Successfully deleted permissioned domain.')
+client.disconnect()
diff --git a/_code-samples/permissioned-domains/js/modify-domain.js b/_code-samples/permissioned-domains/js/modify-domain.js
new file mode 100644
index 0000000000..9b2e07e215
--- /dev/null
+++ b/_code-samples/permissioned-domains/js/modify-domain.js
@@ -0,0 +1,60 @@
+import xrpl from 'xrpl'
+import { stringToHex } from '@xrplf/isomorphic/dist/utils/index.js'
+import fs from 'fs'
+
+// Set up client --------------------------------------------------------------
+const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233')
+await client.connect()
+
+// Load setup data ------------------------------------------------------------
+if (!fs.existsSync('setup.json')) {
+ console.error('Config data not found. Did you run create_domain.py first?')
+ process.exit(1)
+}
+const configData = JSON.parse(fs.readFileSync('setup.json', 'utf8'))
+const wallet = xrpl.Wallet.fromSeed(configData.owner.seed)
+if (wallet.address !== configData.owner.address) {
+ console.error('Address did not match saved value. Did you use the wrong ',
+ 'cryptographic algorithm?',
+ '\n\tSaved:', configData.owner.address,
+ '\n\tGenerated:', wallet.address)
+ client.disconnect()
+ process.exit(2)
+}
+
+const issuerAddress = configData.issuer_address
+const domainID = configData.domain_id
+
+console.log('Domain ID:', domainID)
+console.log('Domain owner:', wallet.address)
+console.log('Credential issuer:', issuerAddress)
+
+// Modify a permissioned domain -----------------------------------------------
+// To demonstrate updating the domain, this tutorial uses a different credential
+// type (issued by the same issuer, unless you modified setup.json)
+const credentialType = stringToHex("new-credential-type")
+
+const pDomainSet = {
+ TransactionType: "PermissionedDomainSet",
+ Account: wallet.address,
+ DomainID: domainID,
+ AcceptedCredentials: [
+ {
+ Credential: {
+ Issuer: issuerAddress,
+ CredentialType: credentialType
+ }
+ }
+ ]
+}
+console.log('Submitting transaction', JSON.stringify(pDomainSet, null, 2))
+const response = await client.submitAndWait(pDomainSet, { wallet, autofill: true})
+console.log(response)
+const resultCode = response.result.meta.TransactionResult
+if (resultCode !== 'tesSUCCESS') {
+ console.error(`PermissionedDomainSet failed with code ${resultCode}`)
+ client.disconnect()
+ process.exit(3)
+}
+console.log('Successfully modified permissioned domain.')
+client.disconnect()
diff --git a/_code-samples/permissioned-domains/js/package.json b/_code-samples/permissioned-domains/js/package.json
new file mode 100644
index 0000000000..881ed55905
--- /dev/null
+++ b/_code-samples/permissioned-domains/js/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "permissioned-domains",
+ "description": "Sample code for managing permissioned domains on the XRP Ledger.",
+ "dependencies": {
+ "xrpl": "^5.0.0"
+ },
+ "type": "module"
+}
diff --git a/_code-samples/permissioned-domains/py/create_domain.py b/_code-samples/permissioned-domains/py/create_domain.py
index f7017f75a5..202f9fcaef 100755
--- a/_code-samples/permissioned-domains/py/create_domain.py
+++ b/_code-samples/permissioned-domains/py/create_domain.py
@@ -53,7 +53,7 @@ for modified_node in pds_response.result["meta"]["AffectedNodes"]:
domain_id = modified_node["CreatedNode"]["LedgerIndex"]
break
if not domain_id:
- print("Couldn't find a created Permissioned Domain in transaction metadata."
+ print("Couldn't find a created PermissionedDomain in transaction metadata."
" This is not typical.")
sys.exit(3)
print("Domain ID of created domain:", domain_id)
diff --git a/_code-samples/permissioned-domains/py/modify_domain.py b/_code-samples/permissioned-domains/py/modify_domain.py
index 87d504d820..606c5f69ca 100755
--- a/_code-samples/permissioned-domains/py/modify_domain.py
+++ b/_code-samples/permissioned-domains/py/modify_domain.py
@@ -24,9 +24,9 @@ with open("setup.json") as f:
wallet = Wallet.from_seed(config_data["owner"]["seed"])
if wallet.address != config_data["owner"]["address"]:
print("ERROR: Address did not match saved value. Did you use the wrong "
- "cryptographic algorithm?\n"
- "\tSaved:", config_data["owner"]["address"],
- "\tGenerated:", wallet.address)
+ "cryptographic algorithm?"
+ "\n\tSaved:", config_data["owner"]["address"],
+ "\n\tGenerated:", wallet.address)
sys.exit(2)
issuer_address = config_data["issuer_address"]
diff --git a/docs/img/create-permissioned-domain-1.png b/docs/img/create-permissioned-domain-1.png
deleted file mode 100644
index 6c46495f68..0000000000
Binary files a/docs/img/create-permissioned-domain-1.png and /dev/null differ
diff --git a/docs/img/create-permissioned-domain-2.png b/docs/img/create-permissioned-domain-2.png
deleted file mode 100644
index fef092cf7b..0000000000
Binary files a/docs/img/create-permissioned-domain-2.png and /dev/null differ
diff --git a/docs/img/create-permissioned-domain-3.png b/docs/img/create-permissioned-domain-3.png
deleted file mode 100644
index 271bbd535f..0000000000
Binary files a/docs/img/create-permissioned-domain-3.png and /dev/null differ
diff --git a/docs/img/create-permissioned-domain-4.png b/docs/img/create-permissioned-domain-4.png
deleted file mode 100644
index dd9212b416..0000000000
Binary files a/docs/img/create-permissioned-domain-4.png and /dev/null differ
diff --git a/docs/img/create-permissioned-domain-5.png b/docs/img/create-permissioned-domain-5.png
deleted file mode 100644
index 9e877ebf7d..0000000000
Binary files a/docs/img/create-permissioned-domain-5.png and /dev/null differ
diff --git a/docs/tutorials/compliance-features/create-permissioned-domains-in-javascript.md b/docs/tutorials/compliance-features/create-permissioned-domains-in-javascript.md
deleted file mode 100644
index fcc7982f05..0000000000
--- a/docs/tutorials/compliance-features/create-permissioned-domains-in-javascript.md
+++ /dev/null
@@ -1,124 +0,0 @@
----
-seo:
- description: Create a permissioned domain to restrict access to financial services that meet compliance requirements.
-labels:
- - Decentralized Finance
- - Permissioned Domains
----
-# Create Permissioned Domains in JavaScript
-
-Permissioned domains are controlled environments within the broader ecosystem of the XRP Ledger blockchain. Domains restrict access to other features such as Permissioned DEXes and Lending Protocols, only allowing access to them for accounts with specific credentials.
-
-This example shows how to:
-
-1. Issue a credential to an account.
-2. Create a permissioned domain with the issued credential.
-3. Delete the permissioned domain.
-
-[](/docs/img/create-permissioned-domain-1.png)
-
-Download the [Modular Tutorials](https://github.com/XRPLF/xrpl-dev-portal/tree/master/_code-samples/modular-tutorials/) folder.
-
-{% admonition type="info" name="Note" %}
-Without the Modular Tutorial Samples, you will not be able to try the examples that follow.
-{% /admonition %}
-
-## Get Accounts
-
-To get test accounts:
-
-1. Open `create-permissioned-domains.html` in a browser.
-2. Get test accounts.
- - If you copied the gathered information from another tutorial:
- 1. Paste the gathered information to the **Result** field.
- 2. Click **Distribute Account Info**.
- - If you have an existing account seed:
- 1. Paste the account seed to the **Account 1 Seed** or **Account 2 Seed** field.
- 2. Click **Get Account 1 from Seed** or **Get Account 2 from Seed**.
- - If you do not have existing accounts:
- 1. Click **Get New Account 1**.
- 2. Click **Get New Account 2**.
-
-[](/docs/img/create-permissioned-domain-2.png)
-
-
-## Issue a Credential
-
-1. Click the **Account 1** radial button. This account will be the credential issuer.
-2. Copy the account 2 address into **Subject**.
-3. Enter a **Credential Type**. For example, _KYC_.
-4. Click **Create Credential**.
-
-[](/docs/img/create-permissioned-domain-3.png)
-
-
-## Create a Permissioned Domain
-
-1. Click **Create Permissioned Domain**.
-2. Copy the _LedgerIndex_ value from the metadata response.
-3. (Optional) Update the permissioned domain with a different credential.
- 1. Change the **Credential Type**.
- 2. Click **Create Credential**.
- 3. Copy the _LedgerIndex_ value into **DomainID**.
- 4. Click **Create Permissioned Domain**.
-
-[](/docs/img/create-permissioned-domain-4.png)
-
-
-## Delete a Permissioned Domain
-
-1. Copy the _LedgerIndex_ value into **DomainID**.
-2. Click **Delete Permissioned Domain**.
-
-[](/docs/img/create-permissioned-domain-5.png)
-
-
-
-# Code Walkthrough
-
-## credential-manager.js
-
-### Create Credential
-
-Define a function that issues a credential to a subject and connects to the XRP Ledger.
-
-{% code-snippet file="/_code-samples/modular-tutorials/credential-manager.js" language="js" from="// Create credential function" before="// Gather transaction info" /%}
-
-Gather the issuer information, subject, and credential type. Convert the credential type value to a hex string if not already in hex. Wrap the code in a `try-catch` block to handle errors.
-
-{% code-snippet file="/_code-samples/modular-tutorials/credential-manager.js" language="js" from="// Gather transaction info" before="// Submit transaction" /%}
-
-Submit the `CredentialCreate` transaction and report the results. Parse the metadata response to return only relevant credential info.
-
-{% code-snippet file="/_code-samples/modular-tutorials/credential-manager.js" language="js" from="// Submit transaction" /%}
-
-
-## permissioned-domain-manager.js
-
-### Create Permissioned Domain
-
-Define a function that creates a permissioned domain and connects to the XRP Ledger.
-
-{% code-snippet file="/_code-samples/modular-tutorials/permissioned-domain-manager.js" language="js" from="/// Create permissioned domain" before="// Gather transaction info" /%}
-
-Gather issuer information, credential type, and domain ID. Format the transaction depending on if the optional domain ID field is included. Wrap the code in a `try-catch` block to handle errors.
-
-{% code-snippet file="/_code-samples/modular-tutorials/permissioned-domain-manager.js" language="js" from="// Gather transaction info" before="// Submit transaction" /%}
-
-Submit the `PermissionedDomainSet` transaction and report the results. The metadata is formed differently if a domain ID is included; parse the response accordingly.
-
-{% code-snippet file="/_code-samples/modular-tutorials/permissioned-domain-manager.js" language="js" from="// Submit transaction" before="// End create permissioned domain" /%}
-
-### Delete Permissioned Domain
-
-Define a function to delete a permissioned domain and connect to the XRP Ledger.
-
-{% code-snippet file="/_code-samples/modular-tutorials/permissioned-domain-manager.js" language="js" from="// Delete permissioned domain" before="// Get delete domain transaction info" /%}
-
-Gather account information and domain ID values. Wrap the code in a `try-catch` block to handle errors.
-
-{% code-snippet file="/_code-samples/modular-tutorials/permissioned-domain-manager.js" language="js" from="// Get delete domain transaction info" before="// Submit delete domain transaction" /%}
-
-Submit the `PermissionedDomainDelete` transaction and report the results.
-
-{% code-snippet file="/_code-samples/modular-tutorials/permissioned-domain-manager.js" language="js" from="// Submit delete domain transaction" /%}
diff --git a/docs/tutorials/compliance-features/manage-permissioned-domains.md b/docs/tutorials/compliance-features/manage-permissioned-domains.md
index 1cbe49d5bf..b6158a4fa1 100644
--- a/docs/tutorials/compliance-features/manage-permissioned-domains.md
+++ b/docs/tutorials/compliance-features/manage-permissioned-domains.md
@@ -5,7 +5,7 @@ labels:
- Decentralized Finance
- Permissioned Domains
---
-# Use Permissioned Domains
+# Manage Permissioned Domains
This tutorial shows how to create a [permissioned domain](../../concepts/tokens/decentralized-exchange/permissioned-domains.md), which can be used to grant access to specific other features like [Permissioned DEXes](../../concepts/tokens/decentralized-exchange/permissioned-dexes.md) and [Single Asset Vaults](../../concepts/tokens/single-asset-vaults.md). It also shows how to modify a domain to update its set of accepted credentials and how to delete a permissioned domain.
@@ -24,6 +24,13 @@ To complete this tutorial, you should:
- Have a basic understanding of the XRP Ledger, including what [permissioned domains](../../concepts/tokens/decentralized-exchange/permissioned-domains.md) and [credentials](../../concepts/decentralized-storage/credentials.md) are.
- Have an [XRP Ledger client library](../../references/client-libraries.md), such as **xrpl.js**, installed.
+{% admonition type="success" name="Tip" %}
+This tutorial doesn't cover issuing and accepting credentials, which aren't necessary for creating and managing a permissioned domain. Valid credentials _are_ necessary for actually using something that's gated by a permissioned domain. For examples of issuing and accepting credentials, see:
+
+- [Manage Credentials](./manage-credentials.md)
+- [Build a Credential Issuing Service in JavaScript](../sample-apps/credential-issuing-service-in-javascript.md) or [in Python](../sample-apps/credential-issuing-service-in-python.md)
+{% /admonition %}
+
## Source Code
@@ -35,6 +42,14 @@ You can find the complete source code for this tutorial's examples in the {% rep
### 1. Install dependencies
{% tabs %}
+{% tab label="JavaScript" %}
+From the code sample folder, use `npm` to install dependencies:
+
+```sh
+npm i
+```
+{% /tab %}
+
{% tab label="Python" %}
From the code sample folder, set up a virtual environment and use `pip` to install dependencies:
@@ -50,14 +65,11 @@ pip install -r requirements.txt
To get started, import the client library and instantiate an API client. You also need an issuer address and credential type for the credential that will grant access to your domain. The credentials themselves don't have to be issued yet; you can do that separately before or after setting up the domain, or you can rely on credentials issued by a third party.
-{% admonition type="success" name="Tip" %}
-This tutorial doesn't cover the process of issuing and accepting credentials. For examples of that, see:
-
-- [Manage Credentials](./manage-credentials.md)
-- [Build a Credential Issuing Service in JavaScript](../sample-apps/credential-issuing-service-in-javascript.md) or [in Python](../sample-apps/credential-issuing-service-in-python.md)
-{% /admonition %}
-
{% tabs %}
+{% tab label="JavaScript" %}
+{% code-snippet file="/_code-samples/permissioned-domains/js/create-domain.js" language="js" before="// Create a domain" /%}
+{% /tab %}
+
{% tab label="Python" %}
{% code-snippet file="/_code-samples/permissioned-domains/py/create_domain.py" language="py" before="# Create a domain" /%}
{% /tab %}
@@ -69,6 +81,10 @@ This tutorial doesn't cover the process of issuing and accepting credentials. Fo
To create a permissioned domain, send a [PermissionedDomainSet transaction][] omitting the `DomainID` field. In the `AcceptedCredentials` field, specify the credentials that grant access to the domain.
{% tabs %}
+{% tab label="JavaScript" %}
+{% code-snippet file="/_code-samples/permissioned-domains/js/create-domain.js" language="js" from="// Create a domain" before="// Find Domain ID" /%}
+{% /tab %}
+
{% tab label="Python" %}
{% code-snippet file="/_code-samples/permissioned-domains/py/create_domain.py" language="py" from="# Create a domain" before="# Find Domain ID" /%}
{% /tab %}
@@ -79,6 +95,10 @@ To create a permissioned domain, send a [PermissionedDomainSet transaction][] om
To identify the permissioned domain later, you need its Domain ID. It is possible to calculate this using the [Permissioned Domain ID format](/docs/references/protocol/ledger-data/ledger-entry-types/permissioneddomain#permissioneddomain-id-format), but it is often easier to find it in the metadata of the transaction that created the domain. Look through the [transaction metadata](/docs/references/protocol/transactions/metadata) for a `CreatedNode` of type `PermissionedDomain`. The `LedgerIndex` field of that entry is the Domain ID.
{% tabs %}
+{% tab label="JavaScript" %}
+{% code-snippet file="/_code-samples/permissioned-domains/js/create-domain.js" language="js" from="// Find Domain ID" before="// Save config" /%}
+{% /tab %}
+
{% tab label="Python" %}
{% code-snippet file="/_code-samples/permissioned-domains/py/create_domain.py" language="py" from="# Find Domain ID" before="# Save config" /%}
{% /tab %}
@@ -86,19 +106,23 @@ To identify the permissioned domain later, you need its Domain ID. It is possibl
You need to know the Domain ID to modify or delete the domain, as well as when setting up a [permissioned DEX](/docs/concepts/tokens/decentralized-exchange/permissioned-dexes) or anything else that uses the permissioned domain for access.
-{% admonition type="info" name="Caution" %}
-The sample code also saves the generated values for use with other sample scripts. Of course, saving secret keys in plaintext on disk is not ideal from a security perspective, but it's acceptable for Testnet accounts with no real-world value. You should use a more robust system when working with Mainnet accounts.
+{% admonition type="info" name="Note" %}
+The sample code saves the domain owner account's address and seed, along with the configured issuer address and generated domain ID, to a JSON file for use with other sample scripts. Saving secret keys in plaintext on disk is not ideal from a security perspective, but it's acceptable for Testnet accounts with no real-world value. You should use a more robust system when working with Mainnet accounts.
{% /admonition %}
## Other Tasks
-Other tasks you might do with a permissioned domain include modifying it to change the set of accepted credentials, or deleting it. The code samples below omit the setup steps for these tasks, but you can see the {% repo-link path="_code-samples/permissioned-domains/" %}full source code{% /repo-link %} for specifics.
+Other tasks you might do with a permissioned domain include modifying it to change the set of accepted credentials, or deleting it. The code samples below omit the redundant setup steps for these tasks, but you can see the {% repo-link path="_code-samples/permissioned-domains/" %}full source code{% /repo-link %} for specifics.
### Modify a Permissioned Domain
To modify an existing domain, send a [PermissionedDomainSet transaction][] like the one that created it, except this time you actually _do_ specify the `DomainID` field.
{% tabs %}
+{% tab label="JavaScript" %}
+{% code-snippet file="/_code-samples/permissioned-domains/js/modify-domain.js" language="js" from="// Modify a permissioned domain" /%}
+{% /tab %}
+
{% tab label="Python" %}
{% code-snippet file="/_code-samples/permissioned-domains/py/modify_domain.py" language="py" from="# Modify a permissioned domain" /%}
{% /tab %}
@@ -109,6 +133,10 @@ To modify an existing domain, send a [PermissionedDomainSet transaction][] like
To delete a permissioned domain that you own, send a [PermissionedDomainDelete transaction][] with the `DomainID` of the domain to delete.
{% tabs %}
+{% tab label="JavaScript" %}
+{% code-snippet file="/_code-samples/permissioned-domains/js/delete-domain.js" language="js" from="// Delete a permissioned domain" /%}
+{% /tab %}
+
{% tab label="Python" %}
Make sure to import the correct transaction type first.
diff --git a/docs/tutorials/defi/lending/use-single-asset-vaults/create-a-single-asset-vault.md b/docs/tutorials/defi/lending/use-single-asset-vaults/create-a-single-asset-vault.md
index 59aa8d2732..4d1087141f 100644
--- a/docs/tutorials/defi/lending/use-single-asset-vaults/create-a-single-asset-vault.md
+++ b/docs/tutorials/defi/lending/use-single-asset-vaults/create-a-single-asset-vault.md
@@ -181,7 +181,7 @@ This confirms that you have successfully created an empty single asset vault.
**Tutorials**:
- [Issue Credentials](../../../sample-apps/credential-issuing-service-in-javascript.md)
- - [Create Permissioned Domain](../../../compliance-features/create-permissioned-domains-in-javascript.md)
+ - [Manage Permissioned Domains](../../../compliance-features/manage-permissioned-domains.md)
- [Deposit Assets into a Vault](./deposit-into-a-vault.md)
**References**:
diff --git a/docs/use-cases/defi/enable-compliance-focused-cross-currency-payments-using-a-permissioned-dex.md b/docs/use-cases/defi/enable-compliance-focused-cross-currency-payments-using-a-permissioned-dex.md
index 4a4d0a7461..7eb692ea59 100644
--- a/docs/use-cases/defi/enable-compliance-focused-cross-currency-payments-using-a-permissioned-dex.md
+++ b/docs/use-cases/defi/enable-compliance-focused-cross-currency-payments-using-a-permissioned-dex.md
@@ -76,7 +76,7 @@ If you run a credential issuing service, don't forget to issue yourself a creden
A permissioned domain uses credentials to control who can access a permissioned DEX. As the owner of the permissioned domain, you control which credentials it accepts. A domain can accept one or several credentials, so that anyone who holds any of the specified credentials gains access. For more information, see:
- [Permissioned Domains](../../concepts/tokens/decentralized-exchange/permissioned-domains.md)
-- [Create Permissioned Domains](../../tutorials/compliance-features/create-permissioned-domains-in-javascript.md)
+- [Manage Permissioned Domains](../../tutorials/compliance-features/manage-permissioned-domains.md)
### Use the permissioned DEX to facilitate payments and offers
diff --git a/docs/use-cases/defi/institutional-credit-facilities.md b/docs/use-cases/defi/institutional-credit-facilities.md
index 91b847ff65..447d93816f 100644
--- a/docs/use-cases/defi/institutional-credit-facilities.md
+++ b/docs/use-cases/defi/institutional-credit-facilities.md
@@ -68,7 +68,7 @@ As a **Loan Broker**, I need to:
| Step | Description | Technical Implementation |
|:-------------------------------|:------------|:-------------------------|
-| Vault Setup | The Loan Broker creates a Single Asset Vault to aggregate one type of asset to lend out. They define a [permissioned domain][] to ensure only accounts that meet KYB (Know Your Business) compliance requirements can deposit into the vault. | - [Create Permissioned Domains](../../tutorials/compliance-features/create-permissioned-domains-in-javascript.md) - [Create a Single Asset Vault](../../tutorials/defi/lending/use-single-asset-vaults/create-a-single-asset-vault.md) |
+| Vault Setup | The Loan Broker creates a Single Asset Vault to aggregate one type of asset to lend out. They define a [permissioned domain][] to ensure only accounts that meet KYB (Know Your Business) compliance requirements can deposit into the vault. | - [Create Permissioned Domains](../../tutorials/compliance-features/manage-permissioned-domains.md) - [Create a Single Asset Vault](../../tutorials/defi/lending/use-single-asset-vaults/create-a-single-asset-vault.md) |
| Lending Protocol Setup | The Loan Broker sets up the Lending Protocol instance, linking it to the Single Asset Vault they created, and defining parameters such as payment fees. | [Create a Loan Broker](../../tutorials/defi/lending/use-the-lending-protocol/create-a-loan-broker.md) |
| First-loss Capital Maintenance | The Loan Broker deposits first-loss capital into the Lending Protocol to meet the minimum cover required. When there is excess cover, they withdraw first-loss capital. | [Deposit and Withdraw First-Loss Capital](../../tutorials/defi/lending/use-the-lending-protocol/deposit-and-withdraw-cover.md) |
{% /tab %}
diff --git a/redirects.yaml b/redirects.yaml
index a95b8d1c13..6c7df500b3 100644
--- a/redirects.yaml
+++ b/redirects.yaml
@@ -1,5 +1,7 @@
# Docs redirects for moved pages -----------------------------------------------
# (not associated with a major reorg)
+/docs/tutorials/compliance-features/create-permissioned-domains-in-javascript:
+ to: /docs/tutorials/compliance-features/manage-permissioned-domains/
/docs/tutorials/defi/dex/trade-with-auction-slot-in-javascript/:
to: /docs/tutorials/defi/dex/use-amm-auction-slot-for-lower-fees/
/resources/contribute-documentation/tutorial-structure/:
diff --git a/sidebars.yaml b/sidebars.yaml
index b79db5d9f7..c610bbe640 100644
--- a/sidebars.yaml
+++ b/sidebars.yaml
@@ -300,7 +300,7 @@
- page: docs/tutorials/compliance-features/require-destination-tags.md
- page: docs/tutorials/compliance-features/manage-credentials.md
- page: docs/tutorials/compliance-features/verify-credentials.md
- - page: docs/tutorials/compliance-features/create-permissioned-domains-in-javascript.md
+ - page: docs/tutorials/compliance-features/manage-permissioned-domains.md
- group: Programmability
groupTranslationKey: sidebar.docs.tutorials.programmability
expanded: false