Passkeys Prerequisites
Passkeys are an amazing way to help dapp developers (like yourself) connect users with their projects, protocols, applications, etc. Learn more on the smart wallets page.
We have been hard at work pioneering some tools to increase the adoption and ease-of-use for passkeys on Stellar. For this tutorial we'll be using the incredible passkey-kit
package, which takes SO MUCH of the headache and hassle out of the equation.
Before we get into the nitty gritty on passkeys, we have some chores to do. First, we'll set up Launchtube, a service that will help get our transactions on-chain without worrying about gas fees, sequence numbers, or source accounts. Really useful. Then, we'll create a Mercury indexing program, which will be used to keep track of the public key half of a user-generated passkey and then do a reverse lookup to see which smart wallet address the passkey has been added to.
Launchtube
Let's start with Launchtube. As we mentioned earlier, Launchtube is similar to a "paymaster" service, if you're familiar with account abstraction in EVM networks. We won't actually need to interact with Launchtube directly. All that will be handled by the passkey-kit
package. However, we'll need to get a JWT token that will allow us to authenticate our dapp with Launchtube.
For Testnet Launchtube tokens, we can generate one any time we like. All you have to do is visit https://testnet.launchtube.xyz/gen
to receive a JWT token that will be valid for three months, and will have 100 XLM in credits (these credits will be consumed when you submit network transactions through Launchtube). Go ahead, give it a try!
We do have Mainnet Launchtube tokens available! You can request a token in the #launchtube
channel on our Stellar Developer Discord server. In particular, pinging @kalepail
, @ElliotFriend
, @carsten.xlm
, or @Chris.anatalio.xlm
should get you on your way pretty quickly.
Once you have your Launchtube token, copy/paste it into the .env
file, as the PRIVATE_LAUNCHTUBE_JWT
variable:
PRIVATE_LAUNCHTUBE_JWT=<insert_your_launchtube_jwt_here>
The PRIVATE_
and PUBLIC_
environment variables are a SvelteKit convention, allowing us to access these variables in appropriate places throughout our codebase using the $env/static/private
and $env/static/public
modules, respectively.
Mercury
Now, on to Mercury. This is a data indexer, running on both Testnet and Mainnet. The team is developing some bleeding-edge data tools that are beginning to redefine what's possible with network data. One such development is the ZephyrVM: Mercury's cloud execution environment. In short, Zephyr allows you to write (Rust) programs that will run at the close of every ledger on the Stellar network. Inside that program, you can access any kind of current or past data, interact with external web services, create serverless functions, and populate databases. Similar to Launchtube, we won't be directly interacting with Mercury inside the Ye Olde Guestbook dapp. Those interactions will be handled by the passkey-kit
package. Also similar to Launchtube, this one takes some setting up.
The passkey-kit
package doesn't "ship" with a Zephyr program in the published package, but it does have all the Zephyr goodness you'll need in the source repository. Here's how you get that Zephyr program running on Mercury so you can access the indexed smart wallet events. By the way, these commands are probably best run outside the directory where you're building your guestbook dapp.
-
Clone the
passkey-kit
repository from GitHub and enter thezephyr
directory within it:git clone https://github.com/kalepail/passkey-kit
cd passkey-kit/zephyr -
Get an authentication token from the Mercury website. You can login to the Testnet dashboard here. Click on the Get access token button under the "Active subscriptions" section. You'll be given a JWT which will be valid for the next seven days.
Copy/paste this token into the
.env
file:PRIVATE_MERCURY_JWT=<insert_your_mercury_jwt_here>
-
(Optionally) You can get a long-lasting authentication token for your account using this token, and making a request to Mercury's API:
curl -X POST https://api.mercurydata.app/v2/key \
-H "authorization: Bearer <insert_your_mercury_jwt_here>This will give you an API key that can also be added to your
.env
file. The benefit of this API key is that it will not expire until you generate another API key.infoFor this tutorial, you'll only need one of these. You can specify the JWT or the API key, and get things working exactly the same. In the
PasskeyServer
, though, make sure you specify the corresponding value. -
Compile and deploy the event indexer Zephyr program to the Testnet network.
cargo install mercury-cli
export MERCURY_JWT="<insert_your_mercury_jwt_here>"
# Make sure you're using Rust version 1.79.0 or newer
mercury-cli --jwt $MERCURY_JWT --local false --mainnet false deploy
If everything succeeds, you're ready to go! Well done!
You're now ready to dive into the actual passkey implementation and get your users authenticated with the guestbook dapp! Let's get to it!
Troubleshooting
It's possible something has gone wrong during your execution of the processes above. Here are some general suggestions of fixes or things you can try if something goes wrong with your use of Launchtube or Mercury:
- Generate a new Launchtube token. It's possible the Launchtube token you're using has run out of credits. Since we're using Testnet for this tutorial, there's no harm in generating a brand new token any time by visiting
https://testnet.launchtube.xyz/gen
in your browser. - Make sure your Zephyr program successfully deployed. I've been stuck more than once with a not-working Mercury request because the Zephyr program hadn't actually deployed successfully. Make sure the
mercury-cli deploy
command's output doesn't have any errors in it. - Check the Mercury documentation. It's quite good and can help you get past a lot of the hurdles you might face.
In any case, feel free to ask questions or drop a chat in the #passkeys
and #launchtube
channels in the Stellar Developer Discord server. There's usually somebody around who's ready and willing to help out!