Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/covenant-gov/pacto-app/llms.txt

Use this file to discover all available pages before exploring further.

Pacto uses a single BIP-39 mnemonic as the root of trust for everything: your Nostr keypair and all of your HD EVM accounts come from the same phrase. There is no separate “wallet seed” to manage. Backing up your recovery phrase is sufficient to restore both your Nostr identity and every HD-derived EVM account.

Derivation path

Pacto derives EVM accounts using standard BIP-44 with coin type 60 (Ethereum):
ParameterValue
Templatem/44'/60'/0'/0/{i}
Coin type60 (Ethereum)
Account0
Change0
Index iHD account index (shown in Settings → Wallet)
Version tagpacto-hd-evm-v1
Scheme columnbip44_v1
Index i starts at 0 and increments each time you add an HD account in Settings → Wallet (“Add HD account” appends the next index). The derivation entry point in the Tauri codebase is derive_eth_bip44_v1_from_mnemonic_phrase in src-tauri/src/evm.rs. Account persistence and the active-account selection live in src-tauri/src/evm_accounts.rs and src-tauri/src/wallet_ops.rs.

Address from private key

For any 32-byte secp256k1 private key, the Ethereum address is computed as:
address = last 20 bytes of keccak256(x || y)
where x and y are the two 32-byte coordinates of the uncompressed public key point. The SEC1 prefix byte 0x04 must not be included in the hash input. This is the same rule used by MetaMask, Ledger, and all other standard Ethereum wallets. A consequence of this rule is that exporting a Pacto private key and importing it into another wallet will show the same address for that key — the address is fully portable.

Relationship to Nostr keys

Nostr keys are derived from the same mnemonic using the SDK’s NIP-06-compatible path (Keys::from_mnemonic in nostr-sdk). EVM accounts are sibling derivations — they do not build on the Nostr secret key. Neither key type depends on the other after derivation.

Reference test vector

Use this vector to verify a new derivation implementation or to confirm a migration is correct:
FieldValue
Mnemonicabandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
Pathm/44'/60'/0'/0/0
Expected address0x9858EfFD232B4033E47d90003D41EC34EcaEda94
# Verified with Foundry cast:
cast wallet address --mnemonic "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" --mnemonic-index 0

Imported accounts

Keys added via Import private key are not derived from the mnemonic — they use the imported_private_key scheme and are stored encrypted per row. Imported accounts cannot be used as the active signer for treasury deployment or Gnosis Safe operations inside the app, which require an HD-derived account.

Legacy derivation history

Two retired approaches existed in earlier builds:

Legacy SHA-256 formula (retired)

Early versions derived the EVM secret as:
evm_secret = SHA256(nostr_secret || "pacto-evm-derivation-v1")
This path is no longer used for new HD accounts. On first wallet use with a stored recovery phrase, account bip44-v1-0 becomes the primary account and signing aligns to BIP-44 index 0. Installations that have only an encrypted legacy evm_pkey and no recovery phrase are assigned a single imported row until the user restores a phrase-backed profile.

Legacy address hash bug (LF-001)

Older builds hashed 0x04 || x || y instead of x || y, which produced a non-standard address for the same key. The repair path is documented in docs/legacy-fixes/LF-001-evm-address-repair.md.

Seed parity note

Pacto does not claim seed parity with MetaMask, Rabby, or any other wallet for the same recovery phrase. The phrase is the canonical backup for Pacto Nostr keys and Pacto HD EVM accounts — not a guarantee that external wallets will derive identical addresses from the same words.If you need another wallet to display the same address, export the private key for that account from Pacto and import it into the other wallet. Do not assume the phrase alone will reproduce the same addresses elsewhere.

Build docs developers (and LLMs) love