Repository navigation
Conversation
…for dApps Vaults list their P2 singleton addresses as derivations, can add more by nonce, and always send change back to the vault. A vault's keys only sign the vault's own custody spend that clear signing checked, so a dApp's spend can't use them for another coin or a second spend of the vault coin. Signing a message by a vault address returns a vaultsig proof. Every RPC endpoint's OpenAPI description says how it behaves for each wallet kind, and docs/wallet-kinds.md covers the RPC, WalletConnect and Sage Apps.
Rigidity
force-pushed
the
rigidity/vault-external
branch
from
November 15, 2026 06:00
5f21b68 to
2b73c64
Compare
This branch has not been deployed
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.
Closes #956. Part of #945. Stacked on #1017.
Summary
The whole external surface now has defined behavior for BLS, vault and watch wallets: the RPC, WalletConnect and the Sage Apps bridge. Vaults can sign dApp spends and messages.
endpoints.jsonhas a "Wallet kinds" note in its OpenAPI description (crates/sage-rpc/src/wallet_kinds.rs).docs/wallet-kinds.mdhas the full table, the signing rules and the recovery rules, including the endpoints added by Recover, cancel, finish and rekey vaults #1016 and Manage every asset and make, take and cancel offers from a vault #1017.get_derivationsreturns the P2 singleton addresses by nonce, with no public key, soDerivationRecord.public_keyis now optional.get_sync_statusreports the number of vault addresses.increase_derivation_indexadds vault addresses and refuses hardened ones.set_change_addressrefuses vault and watch wallets, though clearing an address still works.WalletKindNotSupportedandVaultSignatureNotAllowed. Watch wallets keep the existingWatchOnlyerror for every signing request.sign_coin_spendsfor a vault signs only with its custody signers' keys, after clear signing checks the vault spend.sign_message_by_addresswith a vault address signs as the vault with SDK 0.38.0'svault_message_envelope. It returns avaultsigproof insignature, and the vault'svault1id aspublic_key. ent-wallet has no convention for this response, so the format is new here.sign_message_with_public_keyis BLS only.get_asset_coinsreturns real P2 singleton and P2-conditions-or-singleton puzzle reveals.chip0002_getPublicKeysreturns no keys for vaults, so dApps usechia_getAddressandchip0002_getAssetCoinsinstead.wallet.listWalletsincludes each wallet's kind.wallet.signMessage, which signs by public key.no_vault_signersbefore the user is asked to approve.This hardens #1014's signing
Before this PR,
sign_within #1014 would sign any spend that didn't include the vault coin. A dApp could sendsign_coin_spendsa spend asking the custody key forAGG_SIG_MEon some other coin. It could also include the vault coin twice, with the second spend's delegated puzzle never checked by clear signing.Now a vault key signs
AGG_SIG_MEonly for the single vault spend that clear signing parsed, and both cases are refused. The stack lands together, so the hole is never released, but it's worth knowing when reviewing #1014 on its own.Deferred
get_asset_coins, so WalletConnect'schip0002_getAssetBalanceerrors for them too.Testing
vault_external.rs:verify_vault_signed_messagewatch_wallets.rs: checks the change address and sign-by-public-key refusals.sign_message_by_addressreturned avaultsig1...proof with thevault1id.get_derivationslisted vault addresses by nonce with no public keys.sign_message_with_public_keywas refused with a clear error.Screenshots