Account Abstraction with Stackup & Lit
With the announcement and deployment of ERC-4337 at ETHDenver, the era of account abstraction (AA) is here!
AA is possible through smart contracts accounts, where the accounts have their own logic to define what a valid transaction is. In account abstraction, authentication, signing, and submitting transactions are unbundled. This is made possible by separating the transaction's signature from the account address, allowing for possibilities like switching between different accounts in a single transaction. To learn more about account abstraction and multi-party computation (MPC), read The Future Wallet: Where Lit & Account Abstraction Meet.
This post will explore how Lit’s MPC wallet can work with Stackup to extend applications of account abstraction.
A Quick Intro to Lit Actions & PKP
Lit Actions are used in conjunction with Programmable Key Pairs (PKPs) to give smart contracts signing capabilities. Each PKP is generated collectively by the Lit network in a process called Distributed Key Generation (DKG) whereby each node only holds a share of the underlying private key (a key-share) and the complete private key never exists in its entirety.
To control this distributed key pair, you must mint it in the form of an ERC-721 NFT. The NFT stands as the “symbol” or method for controlling the distributed key custodied by the Lit network. This means that only the wallet address or smart contract holding the PKP NFT can authorize how it is used for signing.
PKP signatures are the validation result of Lit Actions code when using a signature to prove that a particular interaction took place. Lit Actions can validate the information from external sources, such as from a Weather API, or data that is stateless such as checking if a number is prime.
Ideal cases for PKPs and Lit Actions
- Generating proofs: ideal for usage with account abstraction (or smart contract) wallets, essentially this is programmable transaction validation through Lit’s network with a signer
- Looking up permitted actions, addresses, and auth methods associated with a PKP
- Checking access control conditions with conditional signing
Stackup is creating developer tools and infrastructure for building Web3 apps with smart contract accounts. Some tools currently available through Stackup:
- Access ERC-4337 Bundlers & Ethereum Nodes
- Sponsor gasless transactions
The goal of Stackup is to support developers building AA projects to allow:
- 🔑 Arbitrary verification logic: Support single and multi sig verification and any arbitrary signature scheme.
- 💱 Sponsored transactions: Allow users to pay transaction fees in ERC-20 tokens or build your own fee logic, including sponsoring transaction fees on your app.
- 🔒 Account security: Enable social recovery and security features like time-locks and withdraw limits.
- ⚛️ Atomic multi-operations: Build flows that better align with your user's intent such as trading in one click rather than approving and swapping separately.
For example code to understand ERC-4337, check out this Stackup repository.
All components of ERC-4337 revolve around a
UserOperation which is used to execute actions through a smart contract account.
UserOperation looks like a transaction; it’s an ABI-encoded struct that includes fields like:
sender: the wallet making the operation
signature: parameters passed into the wallet’s verification function so the wallet can verify an operation
initCode: the init code to create the wallet if the wallet does not exist
callData: data to call the wallet for the execution step
Bundler is a class of actors that can do several things:
- Listen in to a
- Runs simulations.
- Bundles an array of operations.
- Relays bundles to the
Check out Stackup’s modular Go implementation of an ERC-4337 Bundler.
In the context of ERC-4337, a bundler is a fundamental infrastructure component that enables account abstraction on any EVM network. Its purpose is to work with a mempool of UserOperations to get the transaction included on-chain. Signing occurs with Lit's Programmable Key Pair (PKP) in conjunction with a UserOperation, and submitting transactions happens through Stackup's bundlers.
By leveraging the capabilities of Lit Actions, PKPs, and Stackup's tools, developers can create powerful infrastructure to enable more sophisticated and flexible account abstraction applications. Let’s get into how that’s possible, starting with creating an MPC wallet with Lit and then using the signature from the wallet to be the signer for a smart contract account.
Create an MPC wallet with Lit.Auth
As a distributed key management network, Lit provides developers with the ability to add programmable signing to their applications and wallets. These distributed wallets are known as Programmable Key Pairs (PKP) and the application logic that dictates when and why that key-pair will sign is known as a Lit Action.
When you call a Lit Action, you may pass authentication methods that should be resolved. An authentication method refers to the specific credential (i.e a wallet address, Google oAuth, or Discord account) that is programmatically tied to the PKP and used to control the underlying key-pair. Only the auth method associated with a particular PKP has the ability to combine the underlying shares. You can read more about how authentication works with PKPs on our blog.
Inside of Lit Actions, there is an object called
Lit.Auth that will be pre-populated with the resolved auth methods. If you pass a Google oAuth Token, then the Lit Nodes will resolve the oAuth Token into a user ID and application ID and those will be available to you in
Lit.Auth has the following members:
- actionIpfsIds: An array of IPFS IDs that are being called by this Lit Action. This will typically only have a single item, but if you call multiple Lit Actions from inside your Lit Action, they will all be included here. For example, if you have two Lit Actions, A, and B, and A calls B, then the first item in the array will be A and the last item will be B. Therefore, the last item in the array is always the IPFS ID of the Lit Action that is currently running.
- authSigAddress: A verified wallet address, if one was passed in. This is the address that was used to sign the AuthSig.
- authMethodContexts: An array of auth method contexts. Each entry will contain the following items:
authMethodType. A list of AuthMethodTypes can be found here
Important to note on Authentication Helpers: authorization is not included. This means that a user can present a Google oAuth JWT as an auth method to be resolved and validated by your Lit Action. The Action will then put the result inside the Lit.Auth object. In this case, the result would be the users verified Google account info like their user id, email address, and more.
In the case that a user doesn’t own a wallet (and therefore cannot produce a valid AuthSig), they can present their alternative auth method to the Lit SDK which will convert it into a “compliant” AuthSig. This is documented in our docs. The flow is as follows:
- Present a PKP public key and an auth token from an authorized auth method (like a Google OAuth JWT), as well as a session public key for a local key-pair that is generated and stored locally.
- The PKP is used to sign a SIWE signature which authorizes the session key-pair going forward.
- The Lit SDK will use the session key to sign future requests. Instead of signing the session key-pair with a wallet, you can sign it using the PKP by communicating with the Lit nodes and presenting proof that you are authorized.
Through this flow, a person can use a Google account to create and own a web3 account with signing capabilities.
Adding a Lit MPC Key as a Signer
Smart contract accounts alone do not allow key-based signatures. However, using Lit’s technology, key-based signatures — which is necessary for first-time verifications — are produced and managed through Lit Actions and PKPs.
AuthSigs With Smart Contracts
Let's say your smart contract has its own validation logic, like an ERC-4337 smart contract account. If you want a smart contract to sign with a PKP, you’ll need an authSig which can be produced via EIP-1271. This enables smart contracts to authorize PKPs to sign on its behalf.
Smart Contract Authsig (EIP1271) | Lit Protocol Developer Docs
You can use the code from the documentation to give signing rights to a smart contract. Once that smart contract has an authSig, it can be the method of authorization for a PKP. Essentially, the contract has some logic to ensure that the message has been signed by the correct users or entities before approving or verifying logic.
An example use case is enabling two-factor authentication for accessing a smart contract account. We can think of this as a multi-smart contract authentication, creating multiple ways of authorization. Imagine that one of the keys for your account is managed by a service that will only co-sign if you've confirmed with a second factor like email or SMS. If you confirm the second factor, the transaction succeeds. If you don’t, it’s automatically blocked.
This additional layer of security reduces the risk of unauthorized transactions and protects your assets from being stolen by hackers or malicious actors. By requiring the use of a secondary factor, multi-factor authentication (MFA) makes it much more difficult for an attacker to access your account, even if they have obtained one method of authorization to sign.
UserOperation <> Bundler
A signature (obtained through the PKPs) can now be packaged and used in a
UserOperation . A smart contract account takes in the
UserOperation object, and validates the signature and executes additional logic, such as checking if there additional signatures or keys needed to pass a MFA check before sending the transaction for the bundler to process. The UserOperation reaches the client through any arbitrary transport layer (e.g. HTTP or P2P). Stackup’s Bundler receives
UserOperations via a JSON RPC Client and submits them to the
Account abstraction is a powerful concept that has huge potential in changing the ways people interact with blockchain networks. The release of ERC-4337 has been eagerly anticipated, as it promises to unblock crucial usability and user experience features.
One example highlighted by Vitalik is a decentralized fee market that does not depend on centralized parties, reputation systems, or Ethereum held in a separate externally owned account (EOA).
Ultimately, AA will have a significant impact on the way that people interact with blockchain networks, opening up new possibilities for innovation and growth. By leveraging the capabilities of Lit Actions, PKPs, and Stackup's tools, developers can create powerful infrastructure to enable more sophisticated and flexible account abstraction applications. We are excited to see the innovative ways in which developers will use these tools to create new and exciting applications to push forward upgraded standards of usability within the web3 ecosystem and beyond.
Stackup makes it easy for developers to use account abstraction and smart contract wallets to simplify blockchain for their users. Using Stackup's SDKs and EIP-4337 infrastructure, developers can create custom transaction experiences. Stackup enables gasless transactions, allows you to instantly create wallets for your users using social logins on any EVM blockchain, and lets you make any sequence of transactions one click.
Developer Documentation | Discord | GitHub | Twitter | Website
Lit Protocol lets you create and manage distributed cryptographic key-pairs for condition-based encryption and programmatic signing. A decentralized key management network, Lit can be used in place of centralized key custodians and other key management solutions.
Developer Documentation | Discord | GitHub | Twitter | Website
If you feel inspired to build, Lit has a grants program! The team is looking to fund open source tooling and projects that extend the use of Lit Actions and Programmable Key Pairs.