Skip to content

Commit 0d1a3ea

Browse files
vveerrggclaude
andcommitted
fix: default userVerification to required and fix bech32 npub encoding
Set userVerification default to 'required' for WebAuthn registration/authentication. Fix npubToHex bech32 decoding and hexToNpub encoding with correct HRP handling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 43f74f9 commit 0d1a3ea

2 files changed

Lines changed: 8 additions & 9 deletions

File tree

src/client/webauthn.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export class WebAuthnClient {
4141
const publicKey: PublicKeyCredentialRequestOptions = {
4242
challenge: this.base64ToBuffer(challenge),
4343
timeout: this.options.timeout || 60000,
44-
userVerification: this.options.userVerification || 'preferred',
44+
userVerification: this.options.userVerification || 'required',
4545
rpId: this.options.rpId,
4646
};
4747

@@ -88,7 +88,7 @@ export class WebAuthnClient {
8888
timeout: this.options.timeout || 60000,
8989
authenticatorSelection: {
9090
authenticatorAttachment: 'platform',
91-
userVerification: this.options.userVerification || 'preferred',
91+
userVerification: this.options.userVerification || 'required',
9292
},
9393
attestation: 'none'
9494
};

src/utils/index.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,10 @@ export function npubToHex(npub: string): string {
1313
if (!npub.startsWith('npub1')) {
1414
throw new Error('Invalid npub: must start with npub1');
1515
}
16-
// Split the string into prefix and data parts
17-
const prefix = npub.slice(0, 5); // 'npub1'
18-
const data = npub.slice(5);
19-
const decoded = bech32.decode(`${prefix}1${data}`);
20-
const pubkeyWords = decoded.words.slice(0);
21-
const pubkeyBytes = bech32.fromWords(pubkeyWords);
16+
// Decode the full bech32 string directly — npub1... is already valid bech32
17+
// with 'npub' as the human-readable part and '1' as the separator
18+
const decoded = bech32.decode(npub, 1500);
19+
const pubkeyBytes = bech32.fromWords(decoded.words);
2220
return Buffer.from(pubkeyBytes).toString('hex');
2321
} catch (error) {
2422
throw new Error('Invalid npub format');
@@ -33,7 +31,8 @@ export function hexToNpub(hex: string): string {
3331
try {
3432
const bytes = Buffer.from(hex, 'hex');
3533
const words = bech32.toWords(bytes);
36-
return bech32.encode('npub1', words, 1000);
34+
// HRP is 'npub' — bech32.encode adds the '1' separator automatically
35+
return bech32.encode('npub', words, 1500);
3736
} catch (error) {
3837
throw new Error('Invalid hex format');
3938
}

0 commit comments

Comments
 (0)