Technical Walkthrough
An overview of the background processes enabling Fluidkey.
Last updated
An overview of the background processes enabling Fluidkey.
Last updated
This walkthrough provides background on Fluidkey's core crypto functions, which are released as an .
To keep the walkthrough concise, we assume the reader has a basic understanding of the following concepts. If you're not familiar with them, you can start with the linked resources.
When a user signs into Fluidkey, they are asked to sign a key generation message with their existing Ethereum account. The signature of this message is used to derive the user's private key pair.
See in the kit.
The private key pair never leaves the user's client and is not stored locally. Every time the user re-opens the Fluidkey app and wants to send funds out, they must sign the key generation message again to derive their private keys.
The private key pair is composed of two keys:
A private spending key used to control user funds and sign transactions
A private viewing key used to retrieve user funds and view transactions
To allow Fluidkey to generate addresses on behalf of the user and retrieve their funds, the user shares a derived node of their private viewing key with Fluidkey.
The shared node is of the form m/5564'/N'
where N
is the number identifying the specific node shared. 5564 refers to , focused on standardizing the use of stealth addresses. Fluidkey currently uses 0
as the N
value for all users. In the future, N
may also be used to reference a specific time period (e.g. year, Unix timestamp) or other dimension to be able to give third parties view access to this specific dimension only.
By using Safe as the underlying smart account, Fluidkey users also benefit from the security of a battle-tested smart account implementation.
Each stealth account is controlled by a stealth EOA that acts as the sole signer authorized to approve transactions and control the stealth account.
The stealth EOA is derived pseudo-randomly using the viewing key node shared by the user (see section 2.). Every time a new stealth account is required, the ephemeral private key used to derive the stealth EOA is a new leaf of the shared viewing key node.
We use c0'/c1'
and p'/n'
to ensure no single number in the derivation path exceeds or equals 0x80000000
(2^31
) in line with BIP-32 requirements.
Currently Fluidkey uses a coinType corresponding to chainId 0
, which allows us to generate addresses valid across all EVM chains supported in the interface. A Fluidkey derivation path should therefore look like m/5564'/0'/8'/0'/0'/p'/n'
.
The pseudo-random derivation of the stealth EOA ensures that the user can independently replay all stealth addresses generated and recover funds without relying on Fluidkey.
Sending assets to a user's stealth account does not require the deployment of the underlying smart contract. Instead, the stealth account's address is counterfactually predicted and is only deployed at the moment of withdrawal.
Fluidkey provides users with a static ENS of the form username.fkey.id
and username.fkey.eth
. This identifier resolves a new stealth address controlled by the recipient on every query. This allows users to send funds to a single human-readable identifier while protecting recipient privacy.
See in the kit.
Fluidkey currently uses 1/1 as stealth accounts. They act as stealth addresses with the added UX benefits of smart accounts, such as gas sponsorship.
Specifically, each new stealth address request increments the viewing key node p/n
by one and derives the secret from the obtained leaf m/5564'/N'/c0'/c1'/0'/p'/n'
, where c0
and c1
represent the coinType of the chain used following .
See and in the kit.
See in the kit.
Fluidkey uses an to return stealth addresses.