Skip to content

feat(mobile): verify fee-payer HKDF derivation on native - #598

Open
Lazyartist1 wants to merge 1 commit into
Miracle656:mainfrom
Lazyartist1:feat/mobile-feepayer-hkdf
Open

feat(mobile): verify fee-payer HKDF derivation on native#598
Lazyartist1 wants to merge 1 commit into
Miracle656:mainfrom
Lazyartist1:feat/mobile-feepayer-hkdf

Conversation

@Lazyartist1

Copy link
Copy Markdown

Summary

Adds and verifies the native fee-payer (sponsor) key derivation (backlog item 20). The wallet is fee-sponsored, so the deterministic keypair the SDK derives from the passkey must be byte-identical on web and native — a mismatch would pay fees from the wrong account. This is a correctness check on the HKDF path under the native crypto polyfills.

Approach

The web derives the Ed25519 seed with WebCrypto HKDF (crypto.subtle.deriveBits), which has no equivalent under React Native's crypto polyfills. The native port uses @noble/hashes HKDF-SHA-256 with the same salt/info. HKDF (RFC 5869) is a fixed standard, so both implementations produce the same 32 bytes → the same Ed25519 seed → the same G… address.

Changes

  • lib/deriveFeePayer.ts (new) — native port of frontend/wallet/lib/deriveFeePayer.ts:
    • deriveFeePayerKeypair(credentialIdBase64url) — base64url credential id → noble HKDF-SHA-256 (salt veil:feepayer:salt:v1, info veil:feepayer:ed25519:v1) → 32-byte Ed25519 seed → Keypair.
    • deriveStoredFeePayer() — derives from the credential id in secure store; null when no passkey is registered.

Acceptance

  • Same passkey → identical G… fee-payer address on web and native

Verified: for credential id AQIDBAUGBwgJCgsMDQ4PEA, both the web WebCrypto path and the native noble path derive GDNLN66V4YFQQPDVNMADJSWUF2EFSLM2BHOF2LDUGVQPQUBG7H4WRFDQ. That address is pinned as the golden value in the test, so any drift in the native derivation fails CI.

Testing

  • tsc --noEmit clean
  • jest lib/__tests__/deriveFeePayer.test.ts — 5/5 passing (matches the web-derived golden address, deterministic, distinct id → distinct account, derives from stored credential, null when unregistered)

Closes #448

Confirm the deterministic fee-payer (sponsor) keypair the SDK derives from the
passkey is byte-identical on native and web. The wallet is fee-sponsored, so a
mismatch would pay fees from the wrong account.

The web derives the Ed25519 seed with WebCrypto HKDF (crypto.subtle), which has
no equivalent under React Native's crypto polyfills, so this native port uses
@noble/hashes HKDF-SHA-256 with the same salt/info. HKDF is a fixed standard, so
the two produce the same 32 bytes and therefore the same G… address — checked
against a golden address derived through the web WebCrypto path.

- lib/deriveFeePayer.ts: deriveFeePayerKeypair (base64url credential id → noble
  HKDF → Ed25519 seed → Keypair) and deriveStoredFeePayer (from the secure-store
  credential id).

Closes Miracle656#448
@Lazyartist1
Lazyartist1 requested a review from Miracle656 as a code owner July 30, 2026 07:03
@vercel

vercel Bot commented Jul 30, 2026

Copy link
Copy Markdown

@Lazyartist1 is attempting to deploy a commit to the miracle656's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jul 30, 2026

Copy link
Copy Markdown

@Lazyartist1 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20. Verify fee-payer HKDF on native

1 participant