Skip to content

[Bug]: Non-compatible value is returned as 'XRP Private key' that cannot be used as import in other wallets #12

Description

@L03TJ3

Summary

GoodWallet currently shows a valid native XRPL address, but the XRP "copy private key" action exports an intermediate derivation value instead of an XRPL-compatible import secret. As a result, users who try to import that value into regular XRP wallets often get a different address or an invalid import. The target outcome is to make XRP export/import behavior consistent with the address shown in GoodWallet and compatible with standard XRPL wallet expectations.

Scope

  • Repo: GoodWallet
  • Packages:
    • app wallet client
  • Main files:
    • src/sections/Options/OptionsView.tsx
    • src/login/adapters/privatekey.ts
    • src/utils/derivationPaths.ts
    • Any related translations or export copy for XRP key material

Current Problems

  • The XRP address shown in wallet UI is derived from native XRPL Ed25519 logic, not from an EVM sidechain flow.
  • The current XRP "copy private key" export returns the 32-byte HD derivation output, not the XRPL secret users need for import.
  • GoodWallet then derives the actual XRPL account from only the first 16 bytes of that value by encoding an Ed25519 XRPL seed and deriving the final XRPL keypair/address.
  • Regular XRP wallets typically expect an XRPL seed or wallet-supported secret format, so importing the exported hex often produces a different address or fails.
  • The current UI label "private key" is misleading for XRP because the exported value is not the final XRPL import secret.

Required Changes

  • Change XRP export to return the actual XRPL Ed25519 seed derived by GoodWallet, not the intermediate 32-byte hex.
  • Rename the XRP export label so it reflects the real format being copied, for example XRPL Secret Seed.
  • Make the XRP export flow clearly identify the algorithm as Ed25519.
  • Keep the displayed XRP address derivation unchanged unless a broader migration is explicitly requested.
  • Ensure non-XRP chains keep current export behavior unless they are separately updated.

Implementation Notes

  • Current XRP derivation path is m/44'/144'/0'/0'.
  • Current logic:
    • derive a 32-byte Ed25519 HD value from the wallet masterSeed
    • take the first 16 bytes
    • encode them as an XRPL Ed25519 seed
    • derive XRPL public key and classic address from that seed
  • The exported value should match the secret format that reproduces the existing GoodWallet XRP address in standard XRPL tooling.
  • Prefer a small XRP-specific export helper instead of overloading the generic getPrivateKeyHex() behavior.
  • Update any user-facing copy so XRP does not imply raw private-key interoperability when the exported format is actually an XRPL seed.
  • If advanced export formats are kept, they should be explicitly labeled and separated from the default user-facing export.

Acceptance Criteria

  • Copying the XRP secret from GoodWallet and importing it into a standard XRPL wallet reproduces the same XRPL address shown in GoodWallet.
  • The default XRP export no longer returns the intermediate 32-byte derivation hex.
  • XRP export UI copy clearly indicates the exported format is an XRPL secret seed.
  • XRP export flow clearly indicates the algorithm is Ed25519.
  • No changes break existing XRP signing inside GoodWallet.
  • No changes affect non-XRP chain export behavior.

Testing / Verification

  • Verify the copied XRP export reproduces the exact same XRPL classic address in external XRPL tooling or wallet import flows that support Ed25519 seeds.
  • Verify the currently displayed GoodWallet XRP address remains unchanged after the export fix.
  • Verify importing the exported XRP secret no longer derives a different address due to format mismatch.
  • Verify non-XRP chains still copy the same key material they did before.
  • Verify the options UI and confirmation flow still behave correctly after the XRP-specific export change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions