From 6ea458a5b129196b83b5ec69038aeea6041cb1e8 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Wed, 11 Dec 2024 12:13:11 -0700 Subject: [PATCH 1/2] First couple sections --- docs/build/apps/guestbook/README.mdx | 2 +- docs/build/apps/guestbook/overview.mdx | 12 ++++++------ docs/build/apps/guestbook/smart-contract.mdx | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/build/apps/guestbook/README.mdx b/docs/build/apps/guestbook/README.mdx index d01349408..17f11731c 100644 --- a/docs/build/apps/guestbook/README.mdx +++ b/docs/build/apps/guestbook/README.mdx @@ -5,6 +5,6 @@ sidebar_position: 57 import DocCardList from "@theme/DocCardList"; -This section walks you through designing and building a decentralized application (dapp) that interacts with a smart contract guestbook, allowing users to read and write public messages. This tutorial also implements a passkey powered smart wallet for user authentication. +This section walks you through designing and building a decentralized application (dapp) that interacts with a smart contract guestbook, allowing users to read and write public messages. This tutorial also implements a passkey-powered smart wallet for user authentication. diff --git a/docs/build/apps/guestbook/overview.mdx b/docs/build/apps/guestbook/overview.mdx index fac7aa328..ecebe2b61 100644 --- a/docs/build/apps/guestbook/overview.mdx +++ b/docs/build/apps/guestbook/overview.mdx @@ -21,10 +21,10 @@ Although Ye Olde Guestbook is a full-fledged application on Stellar's Testnet, i To build this guestbook application, we'll need a few pieces. -- **Application framework:** we're using SvelteKit, opting for a type-checked project using TypeScript. SvelteKit (and Svelte on its own) is quite a capable framework, and we'll be using some of its features in this project. However, we will not be diving into those Svelte-specific areas very heavily in this tutorial. The source code of the project is freely open and available, and has some decent informational comments throughout, if you would like to peruse for those purposes. +- **Application framework:** we're using SvelteKit, opting for a type-checked project using TypeScript. SvelteKit (and Svelte on its own) is quite a capable framework, and we'll be using some of its features in this project. However, we will not be diving into those Svelte-specific areas very heavily in this tutorial. The source code of the project is freely open and available and has some decent informational comments throughout if you would like to peruse it for those purposes. - **Frontend framework:** We're using [Skeleton](https://www.skeleton.dev/) to simplify the use of [Tailwind CSS](https://tailwindcss.com/). -- **A way to interact with the network:** this is a TypeScript application, and we're using the `@stellar/stellar-sdk` for this. You could make traditional `fetch` requests if you wanted to, depending on your deployment decisions. In either case, we'll need the SDK to interact with Keypairs and transactions. We'll also be using a data indexer to access historical network events, and we'll cover more of this at a later point in the tutorial. -- **A way to interact with a user's account:** we're foregoing the traditional wallets here, and we'll use `passkey-kit` to give our users a smart wallet to interact with. They can interact with this smart wallet (via passkey-kit) through methods their already familiar with (thumbprints, face ID, etc.). +- **A way to interact with the network:** this is a TypeScript application, and we're using the `@stellar/stellar-sdk` for this. You could make traditional `fetch` requests if you wanted to, depending on your deployment decisions. In either case, we'll need the SDK to interact with keypairs and transactions. We'll also be using a data indexer to access historical network events, and we'll cover more of this at a later point in the tutorial. +- **A way to interact with a user's account:** we're foregoing the traditional wallets here, and we'll use `passkey-kit` to give our users a smart wallet to interact with. They can interact with this smart wallet (via passkey-kit) through methods they're already familiar with (thumbprints, face ID, etc.). :::note @@ -39,7 +39,7 @@ Some choices we've made during the course of development: - We're rolling our own passkeys service here. That means we'll set up and use `passkey-kit` (both client- and server-side components) in our own dapp. In the long run, this may not be the necessary usage pattern. It's likely that services will crop up to act as a "wallet factory" that can create smart wallets, and facilitate adding signers for various applications. Perhaps these services will be provided by existing wallets? Perhaps these services will be unknown to the user (and maybe even developers) in the future? Who knows! The sky's the limit! (But that's not the case yet, so we're doing it ourselves.) - It should be _relatively_ responsive, no promises, though - We've chosen a theme from Skeleton, so it looks nice right away. -- There's a mix of client- and server-side logic. This is due to the fact that we'll need to keep some authentication credentials secret, and we want to avoid leaking these to the user-facing code. Some of these techniques are a bit SvelteKit specific, but it should ultimately be understandable. +- There's a mix of client- and server-side logic. This is due to the fact that we'll need to keep some authentication credentials secret, and we want to avoid leaking these to the user-facing code. Some of these techniques are a bit SvelteKit-specific, but it should ultimately be understandable. - We're deploying to a free-tier Vercel project. We've had really good success in getting SvelteKit and Stellar projects deployed easily and quickly, and with very little configuration. Your mileage may vary, but this should be a pretty decent starting point. - The application is likely not as performant as it could be. Neither is it as optimized as it could be. We've tried to encapsulate the various functionalities in a way that makes sense to the developer reading the codebase, so there is some code duplication and things could be done in a "better" way. - We do _some_ error handling, but not nearly as much as you would want for a real-world application. If something seems like it's not working, and you're not seeing an error, open your developer console, and you might be able to figure out what has gone wrong. @@ -54,8 +54,8 @@ This tutorial is probably best viewed as "_nearly_ comprehensive." We aren't goi ### Dev helpers - [Passkey Kit](https://github.com/kalepail/passkey-kit): A TypeScript SDK for creating and managing Stellar smart wallets. -- [Launchtube](https://launchtube.xyz): Similar to a [Paymaster](https://eips.ethereum.org/EIPS/eip-4337#extension-paymasters) in the EVM world, the Launchtube service aims to alleviate all of the challenges and complexities of getting a transaction on-chain by giving you an API which accepts Soroban ops and then handles getting those entries successfully submitted to the network. -- [Stellar Lab](https://lab.stellar.org): an experimental playground to interact with the Stellar network +- [Launchtube](https://launchtube.xyz): Similar to a [Paymaster](https://eips.ethereum.org/EIPS/eip-4337#extension-paymasters) in the EVM world, the Launchtube service aims to alleviate all of the challenges and complexities of getting a transaction on-chain by giving you an API that accepts Soroban ops and then handles getting those entries successfully submitted to the network. +- [Stellar Lab](https://lab.stellar.org): An experimental playground to interact with the Stellar network. ## Getting started diff --git a/docs/build/apps/guestbook/smart-contract.mdx b/docs/build/apps/guestbook/smart-contract.mdx index dff1c8429..5ae8d1534 100644 --- a/docs/build/apps/guestbook/smart-contract.mdx +++ b/docs/build/apps/guestbook/smart-contract.mdx @@ -76,7 +76,7 @@ First things first, we need a function that will allow a message to be written i - We're using a helper function called `check_string_not_empty` to ensure that a non-empty value has been passed for both the `title` and `text` arguments. More on this function later on. - We're requiring authentication from the author's address, to ensure they've authorized the message entry to be associated with them. -- We're utilizing a `save_message` utility function to do the actual storage entry reading/writing. More on the specifics of this function [later on](#save_message), but for now just know it's storing the the `new_message` struct, and returning the ID of the stored message. +- We're utilizing a `save_message` utility function to do the actual storage entry reading/writing. More on the specifics of this function [later on](#save_message), but for now just know it's storing the `new_message` struct, and returning the ID of the stored message. ```rust /// Write a message to the guestbook. @@ -259,7 +259,7 @@ pub fn claim_donations(env: Env, token: Address) -> Result { ### Utility functions -We have some utility functions, too that aren't exposed to be invoked by the smart contract in a transaction. These functions exist so we don't have to code the same logic over and over (i.e. reading a message from the contract's storage). This is a fairly common approach to reduce contract size and make contract logic more consistent. +We have some utility functions, too that aren't exposed to be invoked by the smart contract in a transaction. These functions exist so we don't have to code the same logic over and over (i.e., reading a message from the contract's storage). This is a fairly common approach to reduce contract size and make contract logic more consistent. #### `check_string_not_empty` @@ -376,6 +376,6 @@ pub enum Error { #### Tests -We've written some tests that work through many (foreseen) usage patterns for this smart contract. It's too lengthy to dive into here, but it's worth checking out the [source code](https://github.com/ElliotFriend/ye-olde-guestbook/blob/main/contracts/ye_olde_guestbook/src/test.rs) to understand the logic about how the various contract functions are meant to work together. +We've written some tests that work through many (foreseen) usage patterns for this smart contract. It's too lengthy to dive into here, but it's worth checking out the [source code](https://github.com/ElliotFriend/ye-olde-guestbook/blob/main/contracts/ye_olde_guestbook/src/test.rs) to understand the logic of how the various contract functions are meant to work together. Up next, we'll look at how we go from this deployed contract to an NPM package that can be imported and used in a frontend project easily, and with full type-safety. From 611e3561c8073f30404f0654b00f17fb929b36f2 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Wed, 11 Dec 2024 14:08:11 -0700 Subject: [PATCH 2/2] editorial --- docs/build/apps/guestbook/bindings.mdx | 4 ++-- docs/build/apps/guestbook/frontend.mdx | 6 +++--- docs/build/apps/guestbook/passkeys-prerequisites.mdx | 8 ++++---- docs/build/apps/guestbook/setup-passkeys.mdx | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/build/apps/guestbook/bindings.mdx b/docs/build/apps/guestbook/bindings.mdx index e98f0f7fe..cb4d946a2 100644 --- a/docs/build/apps/guestbook/bindings.mdx +++ b/docs/build/apps/guestbook/bindings.mdx @@ -115,7 +115,7 @@ node initialize.js :::info -For a more comprehensive overview of process of creating, customizing, and using initialization scripts like this, check out the [frontend template guide](https://developers.stellar.org/docs/build/guides/dapps/soroban-contract-init-template). +For a more comprehensive overview of the process of creating, customizing, and using initialization scripts like this, check out the [frontend template guide](https://developers.stellar.org/docs/build/guides/dapps/soroban-contract-init-template). ::: @@ -127,4 +127,4 @@ pnpm run setup Right, so we've now created a starter project, written a guestbook smart contract, and generated an NPM package that will help us interact with that contract on the network. Amazing! -Next up, let's take a look at how our users will connect with and interact with our dapp. It's time for passkeys! (insert air horn noises) +Next up, let's take a look at how our users will connect with and interact with our dapp. It's time for passkeys! (insert air horn noises)📢 diff --git a/docs/build/apps/guestbook/frontend.mdx b/docs/build/apps/guestbook/frontend.mdx index b9b6688bc..a12749913 100644 --- a/docs/build/apps/guestbook/frontend.mdx +++ b/docs/build/apps/guestbook/frontend.mdx @@ -17,7 +17,7 @@ We're using some pieces of [Svelte state](https://svelte.dev/docs/svelte/$state) ### Connect Buttons Setup -We have a component in `$lib/components/connectButtons.svelte` that houses all the signup, login, logout functionality. This gets put into the header component, and is available throughout the entirety of the Dapp. The basic premise of this component is that we have a collection of buttons, as well as the corresponding functions which should take place when the button is clicked. +We have a component in `$lib/components/connectButtons.svelte` that houses all the signup, login, and logout functionality. This gets put into the header component, and is available throughout the entirety of the dapp. The basic premise of this component is that we have a collection of buttons, as well as the corresponding functions that should take place when the button is clicked. The buttons themselves are simple enough: @@ -228,7 +228,7 @@ We're simplifying this function _just a bit_ for this tutorial. In the [real dap All in, that's a pretty easy invocation of the SAC's `transfer` function. We just pass the `from`, `to`, and `amount` fields. Then, we sign the transaction with our `account` instance, providing our passkey ID in the arguments. Finally, we send the transaction using our helper function, which will fire off the request to Launchtube, and we'll be good to go. In this case, we're not really stressed about the return value. We'll just catch any errors, and notify the user with a toast message. -Enough of the account and asset things, let's get to the gestbook entries! +Enough of the account and asset things, let's get to the guestbook entries! ## Sign the guestbook @@ -365,7 +365,7 @@ export const load: PageServerLoad = async ({ params }) => { }; ``` -You can see here we're using one of the contract functions, `read_message` to get the data. This is a "read-only" function, meaning that no on-chain state is modified when it's run. So, we can just simulate the invocation, which is already done for you when the bindings-generated function is called, and just take the data from the simulation response! Pretty neat, right! +You can see here we're using one of the contract functions, `read_message` to get the data. This is a "read-only" function, meaning that no on-chain state is modified when it's run. So, we can just simulate the invocation, which is already done for you when the bindings-generated function is called, and just take the data from the simulation response! Pretty neat, right?! We pass the resulting message details back to the page, where it will be displayed. diff --git a/docs/build/apps/guestbook/passkeys-prerequisites.mdx b/docs/build/apps/guestbook/passkeys-prerequisites.mdx index 45291f16f..7fb3af9d7 100644 --- a/docs/build/apps/guestbook/passkeys-prerequisites.mdx +++ b/docs/build/apps/guestbook/passkeys-prerequisites.mdx @@ -13,11 +13,11 @@ Before we get into the nitty gritty on passkeys, we have some chores to do. Firs Let's start with [Launchtube](https://launchtube.xyz). 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 3 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](https://testnet.launchtube.xyz/gen)! +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](https://testnet.launchtube.xyz/gen)! :::tip -We do have Mainnet Launchtube tokens available! You can request a token in the [`#launchtube` channel](https://discord.com/channels/897514728459468821/1293204627361108141) on our [Stellar Developers Discord server](https://discord.gg/stellardev). In particular, pinging `@kalepail`, `@ElliotFriend`, `@carsten.xlm`, or `@Chris.anatalio.xlm` should get you on your way pretty quickly. +We do have Mainnet Launchtube tokens available! You can request a token in the [`#launchtube` channel](https://discord.com/channels/897514728459468821/1293204627361108141) on our [Stellar Developer Discord server](https://discord.gg/stellardev). In particular, pinging `@kalepail`, `@ElliotFriend`, `@carsten.xlm`, or `@Chris.anatalio.xlm` should get you on your way pretty quickly. ::: @@ -46,7 +46,7 @@ The `passkey-kit` package doesn't "ship" with a Zephyr program in the published cd passkey-kit/zephyr ``` -2. Get an authentication token from the Mercury website. You can login to the [Testnet dashboard](https://test.mercurydata.app/) 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 7 days. +2. Get an authentication token from the Mercury website. You can login to the [Testnet dashboard](https://test.mercurydata.app/) 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. ![Mercury Data JWT Token](/img/tutorial/guestbook/mercury_token.png) @@ -92,4 +92,4 @@ It's possible something has gone wrong during your execution of the processes ab 2. **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. 3. **Check the [Mercury documentation](https://docs.mercurydata.app/).** 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`](https://discord.com/channels/897514728459468821/1250851135561142423) and [`#launchtube`](https://discord.com/channels/897514728459468821/1293204627361108141) channels in the Stellar Developers Discord server. There's usually somebody around who's ready and willing to help out! +In any case, feel free to ask questions or drop a chat in the [`#passkeys`](https://discord.com/channels/897514728459468821/1250851135561142423) and [`#launchtube`](https://discord.com/channels/897514728459468821/1293204627361108141) channels in the Stellar Developer Discord server. There's usually somebody around who's ready and willing to help out! diff --git a/docs/build/apps/guestbook/setup-passkeys.mdx b/docs/build/apps/guestbook/setup-passkeys.mdx index e49428b25..578a9caa1 100644 --- a/docs/build/apps/guestbook/setup-passkeys.mdx +++ b/docs/build/apps/guestbook/setup-passkeys.mdx @@ -41,7 +41,7 @@ Now, we've also added some useful "helpers" into the `$lib/passkeyClient.ts` fil export const rpc = new Server(PUBLIC_STELLAR_RPC_URL); ``` -- A SAC client to interact with the native XLM asset contract. We're making an assumption that native Lumens is a "good enough" asset interaction to get the tutorial working, and for playing on Testnet. You could easily export _another_ SAC client to interact with USDC, for example. +- A SAC client to interact with the native XLM asset contract. We're making an assumption that native lumens is a "good enough" asset interaction to get the tutorial working, and for playing on Testnet. You could easily export _another_ SAC client to interact with USDC, for example. ```js title="src/lib/passkeyClient.ts" import { SACClient } from "passkey-kit"; @@ -64,7 +64,7 @@ Now, we've also added some useful "helpers" into the `$lib/passkeyClient.ts` fil ## Passkey server -So, that's the client-facing passkey code (and some helpers) taken care of. What about the server-side, where we want to be cautious about leaking secrets and token?! +So, that's the client-facing passkey code (and some helpers) taken care of. What about the server-side, where we want to be cautious about leaking secrets and tokens?! We're setting this up in `src/lib/server/passkeyServer.ts`, for similar reasons we listed above. This gives us an importable `server` instance that can be accessed and used in other server-side logic. Svelte gives us the added benefit of [keeping the code in this directory safe](https://svelte.dev/docs/kit/server-only-modules#Your-modules). When we want to safeguard credentials and secrets, we can put any sensitive code in the `$lib/server` directory.