DID: Decentralized identifiers (DIDs) (XLS-40): (#4636)

Implement native support for W3C DIDs.

Add a new ledger object: `DID`.

Add two new transactions:
1. `DIDSet`: create or update the `DID` object.
2. `DIDDelete`: delete the `DID` object.

This meets the requirements specified in the DID v1.0 specification
currently recommended by the W3C Credentials Community Group.

The DID format for the XRP Ledger conforms to W3C DID standards.
The objects can be created and owned by any XRPL account holder.
The transactions can be integrated by any service, wallet, or application.
This commit is contained in:
Mayukha Vadari
2026-02-19 17:20:59 +09:00
committed by tequ
parent ca591b7c1d
commit 74432a37bb
33 changed files with 1062 additions and 8 deletions

View File

@@ -2170,6 +2170,7 @@ public:
cron::repeat(200),
fee(XRP(1)),
ter(tesSUCCESS));
env.close();
std::string const ledgerHash{to_string(env.closed()->info().hash)};
@@ -2232,6 +2233,57 @@ public:
}
}
void
testLedgerEntryDID()
{
testcase("ledger_entry Request DID");
using namespace test::jtx;
using namespace std::literals::chrono_literals;
Env env{*this};
Account const alice{"alice"};
env.fund(XRP(10000), alice);
env.close();
// Lambda to create a DID.
auto didCreate = [](test::jtx::Account const& account) {
Json::Value jv;
jv[jss::TransactionType] = jss::DIDSet;
jv[jss::Account] = account.human();
jv[sfDIDDocument.jsonName] = strHex(std::string{"data"});
jv[sfURI.jsonName] = strHex(std::string{"uri"});
return jv;
};
env(didCreate(alice));
env.close();
std::string const ledgerHash{to_string(env.closed()->info().hash)};
{
// Request the DID using its index.
Json::Value jvParams;
jvParams[jss::did] = alice.human();
jvParams[jss::ledger_hash] = ledgerHash;
Json::Value const jrr = env.rpc(
"json", "ledger_entry", to_string(jvParams))[jss::result];
BEAST_EXPECT(
jrr[jss::node][sfDIDDocument.jsonName] ==
strHex(std::string{"data"}));
BEAST_EXPECT(
jrr[jss::node][sfURI.jsonName] == strHex(std::string{"uri"}));
}
{
// Request an index that is not a DID.
Json::Value jvParams;
jvParams[jss::did] = env.master.human();
jvParams[jss::ledger_hash] = ledgerHash;
Json::Value const jrr = env.rpc(
"json", "ledger_entry", to_string(jvParams))[jss::result];
checkErrorValue(jrr, "entryNotFound", "");
}
}
void
testLedgerEntryInvalidParams(unsigned int apiVersion)
{
@@ -2983,6 +3035,7 @@ public:
testNoQueue();
testQueue();
testLedgerAccountsOption();
testLedgerEntryDID();
test::jtx::forAllApiVersions(std::bind_front(
&LedgerRPC_test::testLedgerEntryInvalidParams, this));