MPTokenIssuanceID and nothing else. The share token carries no price field. The MPTokenIssuance records who issued it and how many units are outstanding, but says nothing about what a unit is worth. Orma solves this by writing a pointer into the share token’s own MPTokenMetadata at vault creation — not a value, a URL template. Whoever holds the token reads its metadata off the ledger, substitutes the issuance ID they already have into the template, follows it, and receives a valuation computed from public ledger state. Nothing in that chain requires the lender to know Orma exists.
Two constraints that shape the whole design
The metadata is write-once, permanently
MPTokenMetadata can only be set on VaultCreate. Three transactions on Devnet confirm there is no correction path:
The third result is the important one. The issuer of a vault share is the vault’s pseudo-account, which carries
lsfDisableMaster and has no regular key. No key in existence can sign an update. The field is frozen for the life of the vault.
The pointer cannot name the thing it describes
MPTokenMetadata must be composed at the moment of VaultCreate submission — before the vault exists. At that moment the VaultID and the share MPTokenIssuanceID are both unknown (assigned by the transactor), and the field can never be corrected once either becomes known.
A self-referential URL is therefore impossible. Instead, Orma writes a template with a placeholder:
The pointer structure
The full metadata written to a vault share — XLS-89 conformance fields first, then one namespacedorma block:
Why the XLS-89 fields?
Why the XLS-89 fields?
rippled volunteers a warning when metadata is not XLS-89 shaped: it reports the token “might not be discoverable by Explorers and Indexers” and lists the five fields it expects —
ticker, name, icon, asset_class, issuer_name. A vault share created without metadata is invisible to every indexer that reads the standard. Five fields is a cheap price for being listed.asset_class: "rwa" is the closest true statement for a private credit facility (a real-world asset). The exact instrument type lives in orma.instrument as vault-share. The xls89Report() API response carries a taxonomyNote field explaining this so consumers are not misled by the coarser field.nav_url_param field exists so a consumer who has never read this page can still identify which substring to replace: substitute nav_url_param’s value with the issuance ID you hold.
How a second lender resolves the pointer
A lender holds an MPT issuance ID and nothing else — no relationship with the facility, no access to its reporting, no reason to trust any figure someone hands them.Using the API
To run the resolution loop via Orma’s API, callGET /api/mpt/:mptId/resolve:
issuer on the first step — r3hE8HanpccSZdgmeHCfYFEkwxFjdDmmvt — is the vault pseudo-account, the same account whose lsfDisableMaster flag makes the metadata permanent.
Valuing a pledge
To value a specific number of units — for example, 1,000,000 units pledged as collateral — callGET /api/mpt/:mptId/nav?units=1000000:
19.61% of the stated collateral value was not there. A haircut does not fix this: a haircut applies to the held value and absorbs volatility in a number that is correct. It does not absorb a number that is wrong.
The valuation response carries a
provenance block with the three raw ledger integers and a recompute formula, so you can verify the figure yourself without trusting Orma:
AssetsTotal and LossUnrealized from the Vault object on any Devnet node and apply the one-line formula in recompute. The numbers should match to the drop.
When resolution fails
Every failure mode is a normal outcome, not an error. The resolver reports a failed step and continues so the lender receives the most useful answer possible.Failure mode reference
Failure mode reference
unitValue, the pledge value response returns an explicit unpriced string rather than a number or an exception — a lender’s tool has to be able to say “I could not value this”.
Embedding the pointer at vault creation
Build and encode the metadata before submittingVaultCreate:
VaultKind: 1 with SubscriptionDate and RedemptionDate is required. A vault that is not closed-ended cannot have a LoanBroker, so every vault whose shares are worth valuing this way is a fixed-term fund.
API routes for second lenders
GET /api/mpt/:mptId/nav
Returns the current unit value (held and reported), divergence in basis points, and the raw provenance inputs. Add
?units=N to value a specific pledge.GET /api/mpt/:mptId/resolve
Traces every step of the resolution loop: reads the issuance, decodes the metadata, checks XLS-89 conformance, finds the pointer, and follows it. Add
?resolve=false to stop at the pointer without following it.