Skip to content

feat: add Single Asset Vault support (XLS-0065)#47

Open
Patel-Raj11 wants to merge 11 commits into
sav-mainfrom
feature/SingleAssetVault
Open

feat: add Single Asset Vault support (XLS-0065)#47
Patel-Raj11 wants to merge 11 commits into
sav-mainfrom
feature/SingleAssetVault

Conversation

@Patel-Raj11

Copy link
Copy Markdown
Owner

Reference Links

High Level Overview of Change

Adds client support for XLS-0065 Single Asset Vaults, so SDK users can create and manage a tokenized vault that pools one asset (XRP or IOU) from many depositors and represents ownership as MPT shares — building and signing the six vault transactions, parsing the new Vault ledger entry, deriving a vault's ID before submission, and looking vaults up via vault_info.

Categories of work in this PR:

  • Serialization types — brings the Number type (STI_NUMBER = 9) live in ripple-binary-codec and regenerates the codec definitions (new fields, transaction types 65–70, the Vault ledger-entry type 0x0084, and the new tec/ter results).
  • Transaction modelsVaultCreate, VaultSet, VaultDelete, VaultDeposit, VaultWithdraw, and VaultClawback, each wired into the central validate switch.
  • Validation — required-field checks, flag-range validation (tfVaultPrivate / tfVaultShareNonTransferable), and byte-length bounds (Data ≤ 256 B, share MPTokenMetadata ≤ 1024 B).
  • Ledger object models — the new Vault entry, plus an optional VaultID on AccountRoot and an optional DomainID on MPTokenIssuance.
  • RPC models — the vault_info request/response and a vault selector on ledger_entry.
  • HelpershashVault for client-side VaultID derivation, and the VaultCreate base-fee computation wired into autofill.
  • Tests — unit tests (transaction models, STNumber codec, hashVault) and integration tests run against rippled.
  • DocsHISTORY.md updated in both xrpl and ripple-binary-codec.

Context of Change

This PR tracks the SingleAssetVault amendment (rippled #5224) and its prerequisite STNumber serialized type (#5121). Vault shares are an MPT issued by a pseudo-account (XLS-0064), so the SDK reuses its existing MPT surface for shares and adds only the vault-specific transactions, ledger entry, and vault_info lookup. Where the XLS and the merged rippled implementation diverge, the SDK follows rippled — see Notes for reviewers.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (non-breaking change that only restructures code)
  • Tests (You added tests for code that already exists, or your new feature included in this PR)
  • Documentation Updates
  • Release

Did you update HISTORY.md?

  • Yes
  • No, this change does not impact library users

Test Plan

  • Unit tests added: per-transaction model validation for all six vault transactions (required-field rejection, flag validation, byte-length bounds), STNumber encode/decode round-trip, and hashVault ID derivation.
  • Integration tests added (run live against a standalone rippled with the amendment enabled): the public XRP vault lifecycle (VaultCreateVaultDepositVaultWithdrawVaultDelete, parsing the Vault entry and vault_info), and a VaultClawback against an XRP vault being rejected.
  • Not covered by tests in this PR:
    • The account_objects type: vault filter value — not implemented in the SDK (follow-up).
    • Client-side refusal to sign for a vault pseudo-account — tecPSEUDO_ACCOUNT is enforced by rippled only; no construction-time guard is added.
    • MPT-as-asset vault flows — deferred to XRP/IOU per maintainer direction (the Asset model still accepts MPT, and shares-as-MPT behavior remains covered).
    • Live integration coverage for private/permissioned-domain vaults, a successful issuer clawback (IOU/MPT), non-transferable-share redeem-only, and vault-share-as-MPT escrow composition — these are exercised at the model/unit level but not yet as integration tests.

Notes for reviewers

  • Two MINOR code-review findings remain in the code (Round 1 verdict was PASS; both are non-blocking edge cases):
    • isXRPLNumber (models/transactions/common.ts) validates with Number.isFinite(Number(input)), so a Number string whose exponent exceeds JS double range (e.g. "1e1000") is rejected at construction even though rippled would accept it.
    • The Data and share MPTokenMetadata byte-length checks reject an empty hex string (byteLength < 1) although the spec states no minimum — an empty value is rejected rather than treated as omitted.
  • Deliberate divergences from the XLS, where the merged rippled implementation is authoritative:
    • Transaction type IDs are 65–70 (not the XLS's provisional 58–63).
    • VaultClawback.Amount is modeled as an Amount (STAmount), not a Number.
    • Scale (on the Vault entry / VaultCreate) and DestinationTag (on VaultWithdraw) from the XLS are intentionally not added — rippled does not implement them at these PRs.
  • Out of scope: the Clio-only vault_list RPC (XLS §4.2) is not implemented because no Clio PR ships it; its request/response field shapes should be re-verified against the Clio implementation once it lands.

Patel-Raj11 and others added 6 commits June 30, 2026 09:48
Add the Single Asset Vault amendment to xrpl.js:
- VaultCreate/Set/Delete/Deposit/Withdraw/Clawback transaction models with
  validation, flags, and full wiring (transaction union, validate switch,
  exports, txToFlag map)
- Vault ledger object plus optional VaultID on AccountRoot and DomainID on
  MPTokenIssuance, wired into the LedgerEntry union and filters
- vault_info request/response, ledger_entry `vault` selector, and
  account_objects `vault` filter
- STNumber (Number, type_code 9) serialized type in ripple-binary-codec
- hashVault keylet utility, 'V' ledger space, and VaultCreate owner-reserve
  base-fee autofill

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…hVault

Adds model validation tests for the six vault transactions, known-answer
encode/decode and round-trip tests for the STNumber serialized type, and a
hashVault ledger-index derivation test.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…integration tests

STNumber values were being serialized with the Large arithmetic mantissa
scale ([10^18, 10^19-1], log 18), but rippled serializes the STNumber wire
format using the Small scale ([10^15, 10^16-1], log 15). The mismatch made
rippled re-normalize the decoded Number on the receiving side, so the
signature it recomputed never matched the one the SDK signed, and every
VaultCreate carrying an AssetsMaximum (or any Number field) was rejected
with "fails local checks: Invalid signature." Verified byte-for-byte against
rippled's own serialization across a range of values.

Adds the XLS-65 vault integration suite (full public-XRP-vault lifecycle and
a VaultClawback-against-XRP rejection), now passing end-to-end against the
standalone rippled, and updates the codec known-answer encodings accordingly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace Jest-only `it.each` in the STNumber codec tests with the
`.forEach(... it())` pattern used elsewhere in ripple-binary-codec so
the cases also run under Karma/Jasmine (`test:browser`). Apply prettier
formatting and add the established `eslint-disable max-statements`
directive to the multi-step vault integration test.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Comment thread packages/xrpl/test/integration/transactions/vault.test.ts
Comment thread packages/ripple-binary-codec/src/types/st-number.ts
Comment thread packages/xrpl/test/integration/transactions/vault.test.ts Outdated
Comment thread packages/xrpl/test/integration/transactions/vault.test.ts
Comment thread packages/xrpl/test/integration/transactions/vault.test.ts
@Patel-Raj11 Patel-Raj11 changed the base branch from main to sav-main June 30, 2026 19:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant