Skip to content
Open
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
4 changes: 4 additions & 0 deletions _code-samples/walk-owner-directory/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Walk Owner Directory
Iterate over an account's owner directory and display how many ledger entries are in each page. In cases of highly active accounts, this can demonstrate the extent of "fragmentation" with skipped page numbers and non-full pages.

This code sample demonstrates the low-level structure of owner directories. If you don't need to see the breakdown by pages, you can use [`account_objects`](https://xrpl.org/docs/references/http-websocket-apis/public-api-methods/account-methods/account_objects) instead, since it provides a more convenient list of ledger entries attached to an account.
55 changes: 55 additions & 0 deletions _code-samples/walk-owner-directory/js/iterate-owner-directory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// iterate-owner-directory.js
// Iterate over an account's owner directory and display how many ledger entries
// are in each page. In cases of highly active accounts, it can demonstrate
// the extent of "fragmentation" with skipped page numbers and non-full pages.

import xrpl from 'xrpl'

const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233')
await client.connect()

const owner = "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe" // Testnet faucet
Copy link
Contributor

@pdp2121 pdp2121 Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constant should be upper case, same with 2 constants below

// const owner = "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd" // TST issuer

// Set initial values for iterating
let sub_index = 0 // Directory root
let ledger_index = "validated"

// Query pages from the owner directory until they run out
console.log("Page #\t\t\tEntry count")
console.log("-----------------------------------")
while (true) {
// console.log(`Getting directory page ${sub_index}`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer we keeping the logs (instead of commenting out), so that users are aware of what's going on. Also, for log before an async call, probably consider adding ... so users know to wait for the call to finish

const resp = await client.request({
"command": "ledger_entry",
"directory": {
"owner": owner,
"sub_index": sub_index
},
"ledger_index": ledger_index
})
if (resp.error) {
console.error("ledger_entry failed with error",resp.error)
break
}

// Consistently iterate the same ledger: query by index after the first
if (ledger_index === "validated") {
ledger_index = resp.result.ledger_index
}

console.log(`${sub_index}\t\t\t${resp.result.node.Indexes.length}`)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd prefer this have a sentence format for clarity or a descriptor of some kind, similar to the commented out log below

// console.log(`This page contains ${resp.result.node.Indexes.length} items.`)

// Continue onto another page if this one has more
if (resp.result.node.hasOwnProperty("IndexNext")) {
// The directory continues onto another page.
// IndexNext is returned as hex but sub_index needs decimal
sub_index = parseInt(resp.result.node.IndexNext, 16)
} else {
console.info("This is the last page of the directory")
break
}
}

client.disconnect()
5 changes: 5 additions & 0 deletions _code-samples/walk-owner-directory/js/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"xrpl": "^4.4.3"
}
}
55 changes: 55 additions & 0 deletions _code-samples/walk-owner-directory/py/iterate-owner-directory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# iterate-owner-directory.py
# Iterate over an account's owner directory and display how many ledger entries
# are in each page. In cases of highly active accounts, it can demonstrate
# the extent of "fragmentation" with skipped page numbers and non-full pages.
from xrpl.clients import JsonRpcClient
from xrpl.models.requests import LedgerEntry
from xrpl.clients import XRPLRequestFailureException

OWNER_ADDRESS = "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe" # Testnet faucet
# OWNER_ADDRESS = "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd" # TST issuer

client = JsonRpcClient("https://s.altnet.rippletest.net:51234/")

# Set initial values for iterating
sub_index = 0 # Directory root
ledger_index = "validated"

# Query pages from the owner directory until they run out
print("Page #\t\t\tEntry count")
print("-----------------------------------")
while True:
# Construct the LedgerEntry request for the directory page
directory_request = LedgerEntry(
directory={
"owner": OWNER_ADDRESS,
"sub_index": sub_index
},
ledger_index=ledger_index
)

# Send the request
try:
response = client.request(directory_request)
except Exception as e:
print(f"\nError: ledger_entry failed: {e}")
break

# The 'ledger_index' is consistently set after the first successful query.
# This ensures subsequent pages are read from the same ledger version.
if ledger_index == "validated":
ledger_index = response.result["ledger_index"]

# The entries are stored in the 'Indexes' field of the 'DirectoryNode'
entry_count = len(response.result["node"]["Indexes"])
print(f"{sub_index}\t\t\t{entry_count}")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here as other comment


# Check for the next page indicator
if "IndexNext" in response.result["node"].keys():
# The directory continues onto another page.
# Convert IndexNext from hex to decimal for sub_index.
hex_next = response.result["node"]["IndexNext"]
sub_index = int(hex_next, 16)
else:
print("\nThis is the last page of the directory.")
break
1 change: 1 addition & 0 deletions _code-samples/walk-owner-directory/py/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
xrpl-py==4.3.1