Skip to content
Last updated

Manage Permissioned Domains

This tutorial shows how to create a permissioned domain, which can be used to grant access to specific other features like Permissioned DEXes and Single Asset Vaults. It also shows how to modify a domain to update its set of accepted credentials and how to delete a permissioned domain.

Requires the PermissionedDomains amendment. Loading...

Goals

By following this tutorial, you should learn how to:

  • Create a permissioned domain.
  • Modify or delete a permissioned domain.

Prerequisites

To complete this tutorial, you should:

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:

Source Code

You can find the complete source code for this tutorial's examples in the code samples section of this website's repository.

Steps

1. Install dependencies

From the code sample folder, use npm to install dependencies:

npm i

2. Connect and get account(s)

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.

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")

3. Send PermissionedDomainSet transaction

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.

// 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.')

4. Find the Domain ID

To identify the permissioned domain later, you need its Domain ID. It is possible to calculate this using the Permissioned Domain 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 for a CreatedNode of type PermissionedDomain. The LedgerIndex field of that entry is the Domain ID.

// 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()

You need to know the Domain ID to modify or delete the domain, as well as when setting up a permissioned DEX or anything else that uses the permissioned domain for access.

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.

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 redundant setup steps for these tasks, but you can see the full source code 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.

// 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()

Delete a Permissioned Domain

To delete a permissioned domain that you own, send a PermissionedDomainDelete transaction with the DomainID of the domain to delete.

// 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()

See Also