algorand / algorand/js-algorand-sdk

mnemonicToSecretKey: unhelpful error when given a 24-word BIP-39 mnemonic (Pera Universal Wallet)

Abierto
#1,064 0 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
TypeScript
Estrellas
297
Forks
214
Merge medio
1 h 3 min
PR fusionados (30 d)
3

Descripción

## Summary

`algosdk.mnemonicToSecretKey()` throws a generic `failed to decode mnemonic` error when given a 24-word BIP-39 mnemonic exported from Pera Wallet's Universal Wallet. There is no indication that the format is wrong or what format is expected.

## Steps to Reproduce

1. Create a new wallet in Pera Wallet (iOS/Android) — the default type is **Universal Wallet**
2. Export the passphrase: Settings → Security → Show Passphrase
3. Copy the 24-word mnemonic
4. Try to use it with algosdk:

\`\`\`typescript
import algosdk from "algosdk";
algosdk.mnemonicToSecretKey("word1 word2 ... word24");
// ❌ Error: failed to decode mnemonic
\`\`\`

## Expected Behavior

The error message should indicate the format mismatch clearly, e.g.:

\`\`\`
Error: failed to decode mnemonic — expected a 25-word Algorand mnemonic, received 24 words.
Pera Universal Wallet exports a BIP-39 24-word mnemonic which is not compatible with algosdk.
Use a legacy Algorand Account in Pera (25 words) or generate one via algosdk.generateAccount().
\`\`\`

## Root Cause

Pera Wallet introduced **Universal Wallets** (BIP-39 HD standard, 24 words) alongside the legacy **Algo25 Wallets** (Algorand-native, 25 words + checksum). The two formats are incompatible. algosdk only supports the Algo25 format but gives no indication of this in the error.

## Impact

Developers using Pera Wallet (the most popular Algorand wallet) for local development or scripting will hit a silent dead end. The current error message `failed to decode mnemonic` gives zero actionable guidance — users assume they copied the wrong words, not that the format is fundamentally different.

## Workaround

In Pera Wallet, explicitly create a legacy **Algorand Account** (not a Universal Wallet) to get a 25-word algosdk-compatible mnemonic. Alternatively, generate one directly:

\`\`\`typescript
const account = algosdk.generateAccount();
const mnemonic = algosdk.secretKeyToMnemonic(account.sk); // always 25 words
\`\`\`

## Suggested Fix

In the `mnemonicToSecretKey` / `seedFromMnemonic` function, check the word count before attempting to decode and throw a descriptive error:

\`\`\`typescript
const words = mnemonic.trim().split(/\s+/);
if (words.length !== 25) {
throw new Error(
\`Invalid mnemonic: expected 25 words, got \${words.length}. \` +
\`If using Pera Wallet, make sure to export from a legacy Algorand Account, not a Universal Wallet.\`
);
}
\`\`\`

## Environment

- algosdk: v3.5.2
- Pera Wallet: Universal Wallet (default new account type)
- Discovered while building: https://github.com/firedintern/algorand-x402-api

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.