Ephemeral Signers (ES) is a pretty common pattern in the Solana apps ecosystem. ES are keys that are expected to sign the transaction and be discarded right after. An example of when they are needed is the SystemProgram.createAccount instruction. When creating a non-PDA account, this instruction requires the new account to be a signer to verify that whoever calls this instruction actually holds authority over this account.
Most of the time, app developers use Keypair.generate() to create Ephemeral Signers. Then they sign a transaction that requires an ES with the Keypair and throw it away immediately after. This pattern works pretty well when the signed transaction is immediately sent and executed. That said, it prevents a certain class of use-cases when the transaction is stored on chain and executed later when a certain condition is met, e.g. time lock is released, multisig approval threshold is reached, such as with some Smart Wallet implementations (Realms, Squads, Clockwork etc). In these cases, the Ephemeral Keypair will not be available to sign the "execute" transaction because it has already been "forgotten".
Proposed Solution
We suggest a new Wallet Standard feature -getEphemeralSigners(numberOfSigners: number): Promise<Array<Pubkey>> that would allow apps to request any number of ESs from the wallet. The wallet would return an array of public keys that the app developer can use in their transactions.
Implementation of this feature can vary depending on the type of the wallet being used. For instance, for a multisig wallet, an ES can be a PDA owned by the Multisig Program, enabling the Program to sign the transaction on behalf of that account. While for a regular wallet (Phantom, Glow, etc.), it can be a Keypair generated by the wallet itself and stored securely in the extension's background storage over the course of the browser session.
Regardless of the implementation, the app developer doesn't have to worry about how the ES was generated; they can assume that the public key will be a signer of the transaction when it comes to the execution time.
Benefits for Apps
By detecting and using this Wallet Standard feature, app developers can be sure that their app will work with all existing and future wallet implementations out of the box and no hacks are needed.
There’s also a security benefit of never exposing the Ephemeral Signer Keypair to your app code directly - it is kept in the wallet secured storage, so a malicious dependency can’t steal it and use in any sort of re-initialization attacks.
Benefits for Wallets
By exposing this functionality via the Wallet Standard interface, wallets reserve a place for themselves to innovate and add Smart Wallet features in the future without changing their public interface.
Usage
Detecting the feature and requesting an Ephemeral Signer can be as easy as this:
const ephemeralSignerPubkey = "standard" in adapter && "solana:getEphemeralSigners" in adapter.wallet.features && await adapter.wallet
.features["solana:getEphemeralSigners"]
.getEphemeralSigners(1)[0]
Here we check that our wallet adapter is a Wallet Standard implementation and if it exposes the solana:getEphemeralSigners feature. If so we request 1 Ephemeral Signer public key from the wallet, which now can be passed as an account into a transaction that needs an extra signer.
Proof of Concept
We (Squads) implemented a proof of concept for this feature as part of our multisig-powered Smart Wallet - Fuse. We tested the integration with Jupiter Limit Orders product and are currently in conversation with other app developers regarding the adoption. We also received some positive initial feedback from other ecosystem participants (Realms). We believe, standardizing this feature will significantly help with its adoption and enable proliferation of Smart Wallets ecosystem on Solana.
Next steps
[x] ~Create an sRFC for this feature proposal and refine the design if necessary~ sRFC
If must/can/should be, then what should the path look like?
If must not; how does a wallet know when to dispose of the ephemeral key?
Do dApps expect the ephemeral key to be accessible across devices?
Say I have two browser extensions on two desktop devices with the same seed, should both devices be aware that an ephemeral address has been granted?
Can ephemeral addresses be re-used multiple times?
Two devices with the same seed may accidentally hand out the same ephemeral key to two dApps because the fact that it's being used may not be synced between the two wallets.
Problem
Ephemeral Signers (ES) is a pretty common pattern in the Solana apps ecosystem. ES are keys that are expected to sign the transaction and be discarded right after. An example of when they are needed is the
SystemProgram.createAccount
instruction. When creating a non-PDA account, this instruction requires the new account to be a signer to verify that whoever calls this instruction actually holds authority over this account.Most of the time, app developers use
Keypair.generate()
to create Ephemeral Signers. Then they sign a transaction that requires an ES with the Keypair and throw it away immediately after. This pattern works pretty well when the signed transaction is immediately sent and executed. That said, it prevents a certain class of use-cases when the transaction is stored on chain and executed later when a certain condition is met, e.g. time lock is released, multisig approval threshold is reached, such as with some Smart Wallet implementations (Realms, Squads, Clockwork etc). In these cases, the Ephemeral Keypair will not be available to sign the "execute" transaction because it has already been "forgotten".Proposed Solution
We suggest a new Wallet Standard feature -
getEphemeralSigners(numberOfSigners: number): Promise<Array<Pubkey>>
that would allow apps to request any number of ESs from the wallet. The wallet would return an array of public keys that the app developer can use in their transactions.Implementation of this feature can vary depending on the type of the wallet being used. For instance, for a multisig wallet, an ES can be a PDA owned by the Multisig Program, enabling the Program to sign the transaction on behalf of that account. While for a regular wallet (Phantom, Glow, etc.), it can be a Keypair generated by the wallet itself and stored securely in the extension's background storage over the course of the browser session.
Regardless of the implementation, the app developer doesn't have to worry about how the ES was generated; they can assume that the public key will be a signer of the transaction when it comes to the execution time.
Benefits for Apps
By detecting and using this Wallet Standard feature, app developers can be sure that their app will work with all existing and future wallet implementations out of the box and no hacks are needed. There’s also a security benefit of never exposing the Ephemeral Signer Keypair to your app code directly - it is kept in the wallet secured storage, so a malicious dependency can’t steal it and use in any sort of re-initialization attacks.
Benefits for Wallets
By exposing this functionality via the Wallet Standard interface, wallets reserve a place for themselves to innovate and add Smart Wallet features in the future without changing their public interface.
Usage
Detecting the feature and requesting an Ephemeral Signer can be as easy as this:
Here we check that our wallet adapter is a Wallet Standard implementation and if it exposes the
solana:getEphemeralSigners
feature. If so we request 1 Ephemeral Signer public key from the wallet, which now can be passed as an account into a transaction that needs an extra signer.Proof of Concept
We (Squads) implemented a proof of concept for this feature as part of our multisig-powered Smart Wallet - Fuse. We tested the integration with Jupiter Limit Orders product and are currently in conversation with other app developers regarding the adoption. We also received some positive initial feedback from other ecosystem participants (Realms). We believe, standardizing this feature will significantly help with its adoption and enable proliferation of Smart Wallets ecosystem on Solana.
Next steps