Repository navigation
feat: read an account's XRPL public key, and fix raw signing for Vault accounts - #59
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
High Level Overview of Change
Read an account's XRPL public key. The new
api.getPublicKeylooks up the Custody account that holds an address and returns its XRPL public key in the form XRPL uses (SigningPubKey: compressed secp256k1, uppercase hex). Use it wherever the key itself is needed, such as setting a regular key or adding the account to a signer list:findByAddress, so it searches every domain the API user can see, andledgerId/domainIdnarrow an ambiguous address.AccountNotFoundErrorfor an unknown address, and a clear error when the account has no key on file yet (e.g. still provisioning).Fix: raw signing read the wrong key field, in the wrong form. The raw-signing path (
allowRawSigning) stamps the account's key into the signing preimage asSigningPubKey. It had three problems:providerDetails.keyInformation.publicKey, which the spec marks deprecated and which current Vault accounts leave empty. The sandbox primary has none, so raw signing failed there with "no exportable signing public key".ExtendedPublicKeyentries as non-exportable. For Vault accounts, that entry's value is the account's signing key.The fix: one shared reader in
submission/account-key.tsserves bothgetPublicKeyand raw signing.SECP256K1_CUSTODY_1key fromproviderDetails.keys, and falls back to the deprecated field on older Custody versions that don't populatekeys.toXrplPublicKey) compresses an SPKI key or a raw uncompressed point, and hex-encodes an already-compressed key unchanged, so older instances behave as before.buildSigningPreimagenow takes the XRPL-form key directly.Docs. The README's Custody API section covers
getPublicKey.Context of Change
Reading an account's key is part of what an integration needs around Custody accounts, for example to configure regular keys or signer lists. Building it showed that the raw-signing path's key source no longer matched current Custody accounts.
This was checked against the sandbox before changing anything. The primary account has no
keyInformation.publicKey. ItsSECP256K1_CUSTODY_1key, once compressed, is exactly theSigningPubKeythe XRPL testnet recorded on that account's own transactions. No live test exercised the raw path, which is how the mismatch went unnoticed.Type of Change
Test Plan
02and03prefixes appear), checked against an independent implementation (@noble/curves). A raw uncompressed point is compressed, and an already-compressed key passes through unchanged.SECP256K1_CUSTODY_1entry is read fromkeysand other key ids are ignored;keyswins over the deprecated field;keysfalls back tokeyInformation;SignerCapabilityErroras before.getPublicKeyresolves the account and returns the compressed key, and throws for an unknown address, an account with no key, and an address on several ledgers. The raw-signing preimage test still reproduces exactly whatWallet.sign()computes.getPublicKeyon the primary returns a valid compressed key that derives back to the primary's address (deriveAddress).