Repository navigation
feat: generate XE addresses with standard BIP39 recovery phrases (v2) - #294
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.
Moves the XE address generator (added in #293, claim XE flow) from the first XE recovery phrase scheme to XE recovery phrase v2: standard BIP39 + SLIP-0010 ed25519, as specified in xeprotocol/core#1013 (design: standard BIP39 recovery phrase) and implemented in xeprotocol/core#1014.
Companion PRs
corepackage,xeCLI, embedded web wallet, the v2 vectors file (owner).Wallet.generatePhrase/fromPhrase/validatePhrase.Why
The first scheme used the BIP39 word list and checksum but treated the 24 words as the ed25519 seed itself, with no PBKDF2 and no derivation path. Every other ed25519 chain (Solana, Stellar, Cardano, NEAR, Aptos) derives the key from BIP39 words with PBKDF2-HMAC-SHA512 and SLIP-0010. The same words therefore gave one account in XE software and a different one in every standard tool, and ruled out hardware wallet and multi-chain wallet support. v2 adopts the standard derivation; the address rule (
sha256("xe/account/v1" || pubkey)) does not change.Derivation
Coin type
1is provisional (RECOVERY_PHRASE_COIN_TYPE), pending a SLIP-0044 registration for XE.Changes
src/utils/xe-account.jsnewXeAccount({ passphrase })xeAccountFromPhrase(phrase, { passphrase, account }){ phrase, words, account, seed, address }.validatePhrase(phrase)PhraseErrorwithcodeword_count,unknown_word(withposition) orchecksum.slip10Ed25519(seed, path)normalizePhrase,publicKeyFromSeed,addressFromPublicKey,pickCheckPositions,PhraseError,RECOVERY_PHRASE_COIN_TYPEpickCheckPositionsis unchanged.phraseFromSeed(the old words-are-the-seed encoding) is gone.@scure/bip392.4,@noble/curves2.4 and@noble/hashes2.4 cover everything.src/components/tx/XeAddressModal.vueTests and config
src/utils/xe-recovery-phrase-vectors.json: byte-identical copy of core's v2 vectors (SHA-256ef19072c0ead1a53817cd7af926c1a14504f9740ca072abc0ea7df0750e3e61e): 24 official BIP39 vectors with seeds, 12 SLIP-0010 ed25519 chains, 10 XE end-to-end cases, 4 invalid cases.src/utils/xe-account.test.js: pins the vectors and the word list hash; every BIP39 vector, every SLIP-0010 chain, every XE case (seed and address), every invalid case with its code and position; invalid account values; Unicode whitespace and NFKD passphrase normalisation; a new phrase for every account-0 address; check positions.src/components/tx/XeAddressModal.test.js(new): the three-word gate before the address is emitted; identical passphrase entries required and both cleared after apply; a fresh phrase on New address with both passphrase inputs cleared.vitest.config.js: adds@vitejs/plugin-vueso component tests can mount.vuefiles.Verification
npm testdevelop)npm run buildscripts/test-1013-recovery/cross.mjs), plus a separate 32/32 run at accounts 0 and 5 against an independent Python referenceCompatibility
m/44'/1'/0'.Before merge
1is provisional. A SLIP-0044 registration changesRECOVERY_PHRASE_COIN_TYPEand the vectors (copied again from core). Accepted as1for the Edge testnet (2026-10-15). The coin type must be final before xe-claim go-live: claimed XE sits at addresses derived on this path.Merge after xeprotocol/core#1014, which owns the vectors file.xeprotocol/core#1014 merged as92d83d1(2026-10-15); the vectors file here is still byte-identical to core's (SHA-256ef19072c…e61e).developonly, for the Edge testnet wallet; thedeveloptomasterrelease waits for the go-live approval.