Summary
Hedera wallets already commonly support EIP-712 signing for ECDSA alias accounts through eth_signTypedData_v4. It would be valuable to extend that same typed-data UX to Hedera ED25519 accounts, especially for dapps that need signatures verifiable on-chain through the Hedera Account Service (HAS) precompile.
The pragmatic proposal is:
- Support
eth_signTypedData_v4 for Hedera ED25519 accounts represented by their long-zero EVM address.
- Have wallets compute the normal EIP-712 digest and sign that 32-byte digest with the account's ED25519 key.
- Return a raw
0x-prefixed 64-byte ED25519 signature.
- Do not apply the Hedera
"\x19Hedera Signed Message:\n" prefix to EIP-712 typed data.
As a more explicit alternative, Hedera could introduce a native method such as hedera_signTypedData_v4, but eth_signTypedData_v4 support for ED25519 accounts is likely the lowest-friction path for existing dapps and EVM tooling.
Motivation
Some Hedera accounts are ED25519 accounts, not ECDSA alias accounts. These accounts can still authorize smart-contract flows on-chain when signatures are verified through HAS, but current wallet support for EIP-712 typed data appears focused on ECDSA alias accounts.
This creates a gap for protocols that rely on EIP-712 signatures. The on-chain path already works when the ED25519 key signs the same 32-byte EIP-712 digest that the contract computes. The missing piece is wallet support for producing that signature with a good typed-data UX.
Proposed behavior
For an ED25519 account, a dapp should be able to request:
await provider.request({
method: "eth_signTypedData_v4",
params: [
"0x00000000000000000000000000000000000003fe", // long-zero EVM address for 0.0.1022, example only
JSON.stringify(typedData),
],
});
The wallet would:
- Resolve the long-zero EVM address to the selected Hedera account.
- Render the typed data to the user using the same or similar UI used for ECDSA
eth_signTypedData_v4.
- Compute the EIP-712 v4 digest:
keccak256("\x19\x01" || domainSeparator || hashStruct(message))
- Sign that 32-byte digest with the account's ED25519 key.
- Return the raw ED25519 signature as
0x + 64 bytes.
ECDSA accounts should keep their existing behavior and continue returning standard 65-byte secp256k1 signatures.
Important: do not apply the Hedera message prefix
For this method, the wallet should not apply:
"\x19Hedera Signed Message:\n" + len(message) + message
That prefix belongs to hedera_signMessage / personal-message signing. It should not be added to EIP-712 typed data.
EIP-712 already has its own domain separation:
"\x19\x01" || domainSeparator || hashStruct(message)
The domain separator can include fields like:
name
version
chainId
verifyingContract
Adding the Hedera personal-message prefix on top of EIP-712 would produce a different digest from what contracts expect and would be redundant from a domain-separation perspective.
Why this matters for on-chain verification
Current HAS isAuthorizedRaw verification expects a 32-byte message hash. For ED25519 signatures, this means contracts can verify an ED25519 signature over a 32-byte EIP-712 digest.
This shape works:
typedDataDigest = EIP712Hash(domain, types, message) // bytes32
signature = ed25519_sign(typedDataDigest)
HAS verifies account + typedDataDigest + signature
This shape does not work for current HAS verification:
signature = ed25519_sign("\x19Hedera Signed Message:\n" + len + typedDataDigestOrJson)
because the wallet signs variable-length raw prefixed bytes, while HAS verifies a 32-byte hash.
Compatibility note
Returning a 64-byte ED25519 signature from eth_signTypedData_v4 is not standard Ethereum secp256k1 behavior. Generic Ethereum libraries may assume a 65-byte recoverable ECDSA signature and try to use ecrecover semantics.
For Hedera ED25519 accounts, verification must be understood as:
account key + EIP-712 digest + 64-byte ED25519 signature
not:
ecrecover(EIP-712 digest, signature)
That should be documented clearly so dapps know that ED25519 typed-data signatures are intended for Hedera-aware verification paths such as HAS.
WalletConnect / hedera-wallet-connect impact
For the pragmatic eth_signTypedData_v4 approach, the work in hedera-wallet-connect may be mostly documentation, examples, and ensuring method negotiation allows the request under Hedera EVM chains such as:
The larger implementation work is likely in wallet code:
- advertise/approve
eth_signTypedData_v4 for Hedera EVM sessions
- support ED25519 accounts represented by long-zero EVM addresses
- compute the EIP-712 v4 digest
- render typed-data fields safely to the user
- sign the digest with the ED25519 key
- return a
0x-prefixed 64-byte signature
Alternative: hedera_signTypedData_v4
If overloading eth_signTypedData_v4 with ED25519 behavior is considered too surprising, a Hedera-native method could be added instead:
Potential params:
{
signerAccountId: "hedera:testnet:0.0.1022",
typedData: {
domain: { name, version, chainId, verifyingContract },
types,
primaryType,
message,
}
}
Potential result:
{
signature: "0x...", // 64-byte ED25519 or 65-byte ECDSA depending on account key
accountId: "0.0.1022",
evmAddress: "0x00000000000000000000000000000000000003fe"
}
This is cleaner semantically, but it requires more ecosystem coordination because dapps and wallets would need to adopt a new Hedera-specific method. For that reason, eth_signTypedData_v4 support for ED25519 accounts seems like the better first step.
Suggested acceptance criteria
- A dapp can request
eth_signTypedData_v4 for a Hedera ED25519 account's long-zero EVM address.
- The wallet displays the EIP-712 typed data to the user.
- The wallet signs the EIP-712 digest directly with the ED25519 key.
- The returned signature is
0x + 64 bytes.
- The wallet does not apply the Hedera personal-message prefix.
- A Hedera smart contract can verify the returned signature through HAS against the same EIP-712 digest.
- Documentation clearly explains that ED25519 typed-data signatures are not recoverable Ethereum ECDSA signatures.
References
Summary
Hedera wallets already commonly support EIP-712 signing for ECDSA alias accounts through
eth_signTypedData_v4. It would be valuable to extend that same typed-data UX to Hedera ED25519 accounts, especially for dapps that need signatures verifiable on-chain through the Hedera Account Service (HAS) precompile.The pragmatic proposal is:
eth_signTypedData_v4for Hedera ED25519 accounts represented by their long-zero EVM address.0x-prefixed 64-byte ED25519 signature."\x19Hedera Signed Message:\n"prefix to EIP-712 typed data.As a more explicit alternative, Hedera could introduce a native method such as
hedera_signTypedData_v4, buteth_signTypedData_v4support for ED25519 accounts is likely the lowest-friction path for existing dapps and EVM tooling.Motivation
Some Hedera accounts are ED25519 accounts, not ECDSA alias accounts. These accounts can still authorize smart-contract flows on-chain when signatures are verified through HAS, but current wallet support for EIP-712 typed data appears focused on ECDSA alias accounts.
This creates a gap for protocols that rely on EIP-712 signatures. The on-chain path already works when the ED25519 key signs the same 32-byte EIP-712 digest that the contract computes. The missing piece is wallet support for producing that signature with a good typed-data UX.
Proposed behavior
For an ED25519 account, a dapp should be able to request:
The wallet would:
eth_signTypedData_v4.0x+ 64 bytes.ECDSA accounts should keep their existing behavior and continue returning standard 65-byte secp256k1 signatures.
Important: do not apply the Hedera message prefix
For this method, the wallet should not apply:
That prefix belongs to
hedera_signMessage/ personal-message signing. It should not be added to EIP-712 typed data.EIP-712 already has its own domain separation:
The domain separator can include fields like:
nameversionchainIdverifyingContractAdding the Hedera personal-message prefix on top of EIP-712 would produce a different digest from what contracts expect and would be redundant from a domain-separation perspective.
Why this matters for on-chain verification
Current HAS
isAuthorizedRawverification expects a 32-byte message hash. For ED25519 signatures, this means contracts can verify an ED25519 signature over a 32-byte EIP-712 digest.This shape works:
This shape does not work for current HAS verification:
because the wallet signs variable-length raw prefixed bytes, while HAS verifies a 32-byte hash.
Compatibility note
Returning a 64-byte ED25519 signature from
eth_signTypedData_v4is not standard Ethereum secp256k1 behavior. Generic Ethereum libraries may assume a 65-byte recoverable ECDSA signature and try to useecrecoversemantics.For Hedera ED25519 accounts, verification must be understood as:
not:
That should be documented clearly so dapps know that ED25519 typed-data signatures are intended for Hedera-aware verification paths such as HAS.
WalletConnect / hedera-wallet-connect impact
For the pragmatic
eth_signTypedData_v4approach, the work inhedera-wallet-connectmay be mostly documentation, examples, and ensuring method negotiation allows the request under Hedera EVM chains such as:The larger implementation work is likely in wallet code:
eth_signTypedData_v4for Hedera EVM sessions0x-prefixed 64-byte signatureAlternative:
hedera_signTypedData_v4If overloading
eth_signTypedData_v4with ED25519 behavior is considered too surprising, a Hedera-native method could be added instead:Potential params:
Potential result:
This is cleaner semantically, but it requires more ecosystem coordination because dapps and wallets would need to adopt a new Hedera-specific method. For that reason,
eth_signTypedData_v4support for ED25519 accounts seems like the better first step.Suggested acceptance criteria
eth_signTypedData_v4for a Hedera ED25519 account's long-zero EVM address.0x+ 64 bytes.References