From a5eb2d9ed1f5ec3a671929d49d129fbebcc53718 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Mon, 17 Jul 2023 12:56:09 -0600 Subject: [PATCH 01/46] add new app example tutorial --- .../account-creation.mdx | 24 + .../anchor-integration.mdx | 91 ++ .../basic-wallet.mdx | 873 ------------------ .../connect-to-anchors/_category_.json | 7 - .../deposit-anchored-assets.mdx | 453 --------- .../connect-to-anchors/index.mdx | 14 - .../setup-for-anchored-assets.mdx | 356 ------- .../withdraw-anchored-assets.mdx | 326 ------- .../custom-assets.mdx | 457 --------- .../first-deposit.mdx | 60 -- .../manage-trust.mdx | 22 + .../example-application-tutorial/overview.mdx | 39 + .../path-payment.mdx | 18 + .../example-application-tutorial/payment.mdx | 22 + .../project-setup.mdx | 495 ---------- .../querying-data.mdx | 13 + .../setup-custodial-account.mdx | 204 ---- .../xlm-payments.mdx | 736 --------------- 18 files changed, 229 insertions(+), 3981 deletions(-) create mode 100644 docs/building-apps/example-application-tutorial/account-creation.mdx create mode 100644 docs/building-apps/example-application-tutorial/anchor-integration.mdx delete mode 100644 docs/building-apps/example-application-tutorial/basic-wallet.mdx delete mode 100644 docs/building-apps/example-application-tutorial/connect-to-anchors/_category_.json delete mode 100644 docs/building-apps/example-application-tutorial/connect-to-anchors/deposit-anchored-assets.mdx delete mode 100644 docs/building-apps/example-application-tutorial/connect-to-anchors/index.mdx delete mode 100644 docs/building-apps/example-application-tutorial/connect-to-anchors/setup-for-anchored-assets.mdx delete mode 100644 docs/building-apps/example-application-tutorial/connect-to-anchors/withdraw-anchored-assets.mdx delete mode 100644 docs/building-apps/example-application-tutorial/custom-assets.mdx delete mode 100644 docs/building-apps/example-application-tutorial/first-deposit.mdx create mode 100644 docs/building-apps/example-application-tutorial/manage-trust.mdx create mode 100644 docs/building-apps/example-application-tutorial/overview.mdx create mode 100644 docs/building-apps/example-application-tutorial/path-payment.mdx create mode 100644 docs/building-apps/example-application-tutorial/payment.mdx delete mode 100644 docs/building-apps/example-application-tutorial/project-setup.mdx create mode 100644 docs/building-apps/example-application-tutorial/querying-data.mdx delete mode 100644 docs/building-apps/example-application-tutorial/setup-custodial-account.mdx delete mode 100644 docs/building-apps/example-application-tutorial/xlm-payments.mdx diff --git a/docs/building-apps/example-application-tutorial/account-creation.mdx b/docs/building-apps/example-application-tutorial/account-creation.mdx new file mode 100644 index 000000000..35bcf58be --- /dev/null +++ b/docs/building-apps/example-application-tutorial/account-creation.mdx @@ -0,0 +1,24 @@ +--- +title: Account Creation +sidebar_position: 20 +--- + +Accounts are the central data structure in Stellar and can only exist with a valid keypair (a public and secret key) and the required minimum balance of XLM. Read more in the [Accounts section](../../fundamentals-and-concepts/stellar-data-structures/accounts). + +To start, we’ll have our user create an account. In BasicPay, the signup page will display a randomized public and secret keypair that the user can select with the option to choose a new set if preferred. + +:::info + +Since we are building a [non-custodial application](../application-design-considerations/non-custodial-service), the secret key will only ever live in the browser. It will never be shared with the server or anybody else. + +::: + +[ss1] + +Next, we’ll trigger the user to submit a pincode to encrypt their secret key before it gets saved to their browser’s `localStorage` (this is handled by the SDK). The user will need to remember their pincode for future logins and to submit transactions. + +With BasicPay, when the user clicks the “Signup” button, they will be asked to confirm their pincode. When they do, the `create_account` operation is triggered, and the user’s account is automatically funded with XLM for the minimum balance (starting with 100,000 XLM). + +[ss2] + +When you’re ready to move the application to Pubnet, accounts will need to be funded with real XLM. This is something the application can cover itself by depositing XLM into the user’s account (as we did with BasicPay on Testnet), with the use of [sponsored reserves](../../encyclopedia/sponsored-reserves), or the user can cover the required balance with their own XLM. diff --git a/docs/building-apps/example-application-tutorial/anchor-integration.mdx b/docs/building-apps/example-application-tutorial/anchor-integration.mdx new file mode 100644 index 000000000..2e68e0358 --- /dev/null +++ b/docs/building-apps/example-application-tutorial/anchor-integration.mdx @@ -0,0 +1,91 @@ +--- +title: Anchor Integration +sidebar_position: 60 +--- + +An anchor is a Stellar-specific term for the on and off-ramps that connect the Stellar network to traditional financial rails, such as financial institutions or fintech companies. When a user deposits with an anchor, that anchor will credit their Stellar account with the equivalent amount of digital tokens. The user can then hold, transfer, or trade those tokens just like any other Stellar asset. When a user withdraws those tokens, the anchor redeems them for cash in hand or money in the bank. Read more about anchors in our [Anchor Documentation](https://developers.stellar.org/docs/anchoring-assets/overview). + +When a customer downloads a wallet application that is connected to an anchor service, their Stellar account can either be created by the wallet application or the anchor service. In this example, the account has been created by the wallet application, BasicPay. Account creation strategies are described more in-depth [here](../application-design-considerations#account-creation-strategies). + +In this example, we’ll use an anchor on Stellar’s Testnet to simulate a bank transfer into and out of the user’s wallet using [SEP-6: Deposit and Withdrawal API](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md) and/or [SEP-24: Hosted Deposit and Withdrawal](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md). + +:::info + +SEPs define standards for interoperability on Stellar. Read more in our [SEPs section](../../fundamentals-and-concepts/stellar-ecosystem-proposals). + +::: + +Our integrations will also use the following SEPs: + +- [SEP-1: Stellar TOML](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md) - a file that provides a place for the Internet to find information about an organization’s Stellar integration +- [SEP-9: Standard KYC Fields](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0009.md) - defines a list of standard KYC fields for use in Stellar ecosystem protocols +- [SEP-10: Stellar Web Authentication](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md) - defines the standard way for clients to create authenticated web sessions on behalf of a user who holds a Stellar account +- [SEP-12: KYC API](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md) - defines a standard way for Stellar clients to upload KYC information to anchors + +### Setup for anchored assets + +First, we need to set up our application so it can communicate with anchors to get asset information. + +Do this by first querying an anchor’s stellar.toml file. The [stellar.toml file](https://developers.stellar.org/docs/issuing-assets/publishing-asset-info#completing-your-stellartoml) is a common place where the Internet can find information about an organization’s Stellar integration. + +For anchors, we’re interested in the `currencies` they issue, the `transfer_server` keyword that indicates if the anchor supports SEP-6, SEP-24, or both, and the `web_auth_endpoint` which allows a wallet to set up an authenticated user session. + +BasicPay is interoperating with the testing anchor located at `testanchor.stellar.org` and you can view its toml file [here](https://testanchor.stellar.org/.well-known/stellar.toml). + +### Anchor integration with SEP-6: Deposit and Withdrawal API + +SEP-6 allows wallets and other clients to interact with anchors directly without the user needing to leave the wallet to go to the anchor’s site. In this integration, a user’s KYC information is gathered and handled by the wallet. + +#### Authentication + +The user must prove they own the account before they can withdraw or deposit any assets as part of SEP-10: Stellar Web Authentication. + +To do this, the wallet makes a GET request with a public `account` param to the anchor, which sends back an unsigned Stellar transaction (called a challenge transaction) with an invalid sequence number so it doesn’t actually do anything when submitted to the network. + +In response, the user signs the transaction, and the application POSTs it back to the anchor. If the signature checks out, the success response will contain a [JSON Web Token (JWT)](https://jwt.io/), which is stored in the `webAuthStore` store to use for future interactions with the anchor. + +#### Get `/info` + +First, BasicPay requests the `/info` endpoint from the anchor to understand the supported transfer methods ([deposit, withdraw, deposit-exchange, and withdraw-exchange](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md)) and fee information. + +#### Initiate transfer + +The user then can initiate one of the transfer methods (in BasicPay, only deposits and withdraws are supported) by selecting “Deposit” or “Withdraw” from the drop-down menu and specifying the asset to be deposited or withdrawn. KYC + +BasicPay then queries the anchor’s `sep-12` endpoint for the required KYC fields and presents these fields to the user. The user inputs this information and BasicPay PUTs that information to the KYC `/customer` endpoint. BasicPay then waits for the user’s `status` with the anchor to be approved. + +#### Complete transfer + +BasicPay then prompts the user to input additional information such as transfer type, destination, and amount. + +Once approved, the user clicks “Next” and BasicPay initiates the transfer with the anchor. + +In a withdrawal transaction, BasicPay will also present the user with a pre-built transaction for them to sign with their pincode. + +:::info + +All the fields that have been collected during this process are wrapped into a URL that contains query parameters: [example](https://testanchor.stellar.org/sep6/deposit?account=GAXQIC2BSZ5HZP3BD6RZQSD3LB66TB6A2TA5W3LZX2VDFMBAKHC4B62J&asset_code=SRT&type=bank_account&amount=11) + +::: + +### Anchor integration with SEP-24: Hosted Deposit and Withdrawal + +SEP-24 provides a standard way for wallets and anchors to interact by having the user open a webview hosted by an anchor to collect and handle KYC information. + +#### Authentication + +The user must first prove they own the account before they can withdraw or deposit any assets as part of SEP-10: Stellar Web Authentication. In BasicPay, the user clicks on the “Authenticate” button, triggering a challenge transaction from the anchor to BasicPay as part of SEP-10: Stellar Web Authentication, which is then presented to the user to sign. + +Once signed, BasicPay sends the transaction back to the anchor and then receives a session auth token, which is stored in the `webAuthStore` store. + +#### Get `/info` + +Similar to SEP-6, our application will request the `/info` endpoint from the anchor to understand the supported transfer methods (deposit, withdraw, deposit-exchange, and withdraw-exchange) and fee information. + +#### Initiate and complete transfer + +The user then initiates a transfer method (in BasicPay, only deposits and withdraws are supported) by POSTing a request to either the “SEP-24 Deposit” or “SEP-24 Withdraw” endpoint. The anchor then sends an interactive URL that BasicPay opens for the user to complete and confirm the transaction. + +Once the user clicks “Submit”, they’ll be brought back to the application. + +In a withdrawal transaction, BasicPay will also present the user with a pre-built transaction for them to sign with their pincode. `callback` should be in the form of a `postMessage`. Our application listens for that `postMessage` during the withdrawal and opens up the transaction dialog when the interactive flow is completed. diff --git a/docs/building-apps/example-application-tutorial/basic-wallet.mdx b/docs/building-apps/example-application-tutorial/basic-wallet.mdx deleted file mode 100644 index 5a668d40a..000000000 --- a/docs/building-apps/example-application-tutorial/basic-wallet.mdx +++ /dev/null @@ -1,873 +0,0 @@ ---- -title: Create a Basic Wallet -sidebar_position: 40 ---- - -import { CodeExample } from "@site/src/components/CodeExample"; -import { Alert } from "@site/src/components/Alert"; - - - -In this tutorial, the goal is to get to a place where a user can create, store, and access their Stellar account using an intuitive pincode encryption method. It assumes that you have already completed the [Project Setup section](./project-setup.mdx). - - - -[View the setup boilerplate code on GitHub][1] - -## User Flow - -Because we've decided to build a non-custodial wallet, we don’t need to communicate with a server or database at all: everything can happen locally right on a user’s device. We’ll be doing all our work inside of `src/components/wallet/`, so head over there now. We’re going to use the `StellarSdk.Keypair.random()` from the StellarSdk to generate a new valid Stellar keypair. That's the easy part. The hard work will be storing that vital information in a secure yet accessible manner. - -The user flow we're building will work like this: Click “Create Account” → UI modal popup asking for a pin code → Enter pin code, click “OK” → App encrypts a new Stellar keypair secret key with pin code → App saves encrypted secret to `localStorage`. On page reload, we’ll fetch the `publicKey` to “login” the user, but for any protected action such as “Copy Secret”, the modal will pop back up asking for the original pin code. - -## Create a Popup Modal - -To start, let's look at at the popup modal. We’ll be mimicking the browser’s `prompt` functionality with our own new, more powerful component. First things first we should generate a new component: - - - -```bash -npm run generate -``` - - - -Call it `stellar-prompt`, and deselect both test files leaving only the styling. Once you have that, open `src/components/prompt/` and rename the `.css` file to `.scss`. Fill that style file with this: - - - -```scss -@import "../../global/style.scss"; - -:host { - display: block; - font-family: $font-family; - font-size: 15px; - - .prompt-wrapper { - sidebar_position: absolute; - top: 0; - left: 0; - bottom: 0; - right: 0; - display: flex; - align-items: center; - justify-content: center; - align-content: center; - min-height: 100vh; - min-width: 100vw; - background-color: rgba(black, 0.2); - z-index: 1; - } - .prompt { - background-color: white; - padding: 20px; - max-width: 350px; - width: 100%; - sidebar_position: relative; - - p { - margin-bottom: 10px; - } - input { - width: 100%; - margin: 0; - padding: 5px; - outline: none; - bsidebar_position: 1px solid black; - text-transform: uppercase; - - &:focus { - border-color: blue; - } - } - } - .select-wrapper { - sidebar_position: relative; - display: inline-flex; - - select { - border-color: blue; - padding: 0 10px; - min-width: 100px; - } - - &:after, - &:before { - font-size: 12px; - sidebar_position: absolute; - right: 10px; - color: blue; - } - &:after { - content: "◀"; - top: calc(50% - 5px); - transform: translate(0, -50%) rotate(90deg); - } - &:before { - content: "▶"; - top: calc(50% + 5px); - transform: translate(0, -50%) rotate(90deg); - } - } - .actions { - display: flex; - justify-content: flex-end; - margin-top: 10px; - - button { - margin: 0; - min-width: 50px; - } - .cancel { - background: none; - bsidebar_position: 1px solid blue; - color: blue; - } - .submit { - margin-left: 10px; - } - } -} -``` - - - -Replace the `prompt.tsx` contents with this. - - - -```tsx -import { Component, Prop, Element, Watch, h, State } from "@stencil/core"; -import { defer as loDefer } from "lodash-es"; - -export interface Prompter { - show: boolean; - message?: string; - placeholder?: string; - options?: Array; - resolve?: Function; - reject?: Function; -} - -@Component({ - tag: "stellar-prompt", - styleUrl: "prompt.scss", - shadow: true, -}) -export class Prompt { - @Element() private element: HTMLElement; - - @Prop({ mutable: true }) prompter: Prompter; - - @State() private input: string; - - @Watch("prompter") - watchHandler(newValue: Prompter, oldValue: Prompter) { - if (newValue.show === oldValue.show) return; - - if (newValue.show) { - this.input = null; - - if (newValue.options) - this.input = - this.input || - `${newValue.options[0].code}:${newValue.options[0].issuer}`; - else - loDefer(() => this.element.shadowRoot.querySelector("input").focus()); - } else { - this.prompter.message = null; - this.prompter.placeholder = null; - this.prompter.options = null; - } - } - - componentDidLoad() { - addEventListener("keyup", (e: KeyboardEvent) => { - if (this.prompter.show) - e.keyCode === 13 - ? this.submit(e) - : e.keyCode === 27 - ? this.cancel(e) - : null; - }); - } - - cancel(e: Event) { - e.preventDefault(); - - this.prompter = { - ...this.prompter, - show: false, - }; - this.prompter.reject(null); - } - - submit(e: Event) { - e.preventDefault(); - - this.prompter = { - ...this.prompter, - show: false, - }; - this.prompter.resolve(this.input); - } - - update(e) { - this.input = e.target.value.toUpperCase(); - } - - render() { - return this.prompter.show ? ( -
-
- {this.prompter.message ?

{this.prompter.message}

: null} - - {this.prompter.options ? ( -
- -
- ) : ( - this.update(e)} - > - )} - -
- - -
-
-
- ) : null; - } -} -``` - -
- -One of the first things you’ll notice is the use of `lodash-es`. Let’s make sure we’ve got that imported before moving forward: - - - -```bash -npm i -D lodash-es -``` - - - -There’s a lot going on in this file, but since this isn’t a Stencil tutorial we’ll skip the details. What this allows us to do it to use a `` component elsewhere in our project. It's worth noting the variables available to us in the `prompter` property. - - - -```ts -export interface Prompter { - show: boolean; - message?: string; - placeholder?: string; - options?: Array; - resolve?: Function; - reject?: Function; -} -``` - - - -The values we’ll be making most use of are those first three: `show`, `message` and `placeholder`. The last two—`resolve` and `reject`—are for promisifying the prompt so we can await a response before continuing with further logic. Don't worry: that statement will make more sense in a moment once we include this component in `src/components/wallet/`. Speaking of, let’s swing over to that component now. - -We’ve got a lot of work to do in here so I’ll just paste the code in all its glory and we’ll walk through it block by block: - - - -```ts -import { Component, State } from "@stencil/core"; - -import componentWillLoad from "./events/componentWillLoad"; -import render from "./events/render"; - -import createAccount from "./methods/createAccount"; -import copyAddress from "./methods/copyAddress"; -import copySecret from "./methods/copySecret"; -import signOut from "./methods/signOut"; -import setPrompt from "./methods/setPrompt"; - -import { Prompter } from "@prompt/prompt"; - -interface StellarAccount { - publicKey: string; - keystore: string; -} - -@Component({ - tag: "stellar-wallet", - styleUrl: "wallet.scss", - shadow: true, -}) -export class Wallet { - @State() account: StellarAccount; - @State() prompter: Prompter = { show: false }; - @State() error: any = null; - - // Component events - componentWillLoad() {} - render() {} - - // Stellar methods - createAccount = createAccount; - copyAddress = copyAddress; - copySecret = copySecret; - signOut = signOut; - - // Misc methods - setPrompt = setPrompt; -} - -Wallet.prototype.componentWillLoad = componentWillLoad; -Wallet.prototype.render = render; -``` - - - -They say the beginning is a good place to start. Let’s do that: - - - -```js -import { Component, State } from "@stencil/core"; - -import componentWillLoad from "./events/componentWillLoad"; -import render from "./events/render"; - -import createAccount from "./methods/createAccount"; -import copyAddress from "./methods/copyAddress"; -import copySecret from "./methods/copySecret"; -import signOut from "./methods/signOut"; -import setPrompt from "./methods/setPrompt"; - -import { Prompter } from "@prompt/prompt"; -``` - - - -Just one import from a library we should already have installed. - -The other relative path imports are all the _events_ and _methods_ we’ll create here in a moment. For now, just generate all those files in their appropriate directories. Ensure your console is at the root of the `stellar-wallet` project before running this string of commands: - - - -```bash -mkdir -p src/components/wallet/{events,methods} -touch src/components/wallet/events/{componentWillLoad.ts,render.tsx} -touch src/components/wallet/methods/{createAccount,copyAddress,copySecret,signOut,setPrompt}.ts -``` - - - -Next we have this funky line which may seem like an npm team import, but is actually a fancy typescript module alias path. - - - -```ts -import { Prompter } from "@prompt/prompt"; -``` - - - -This allows us to avoid long error prone `../../../` paths and just use `@{alias}/{path?}/{module}`. In order to get this past both the linter and compiler we’ll need to modify a couple files. - -First, modify the `tsconfig.json` file to include these values in the `compilerOptions` object. - - - -```JSON -{ - "compilerOptions": { - "baseUrl": "./src", - "paths": { - "@prompt/*": ["components/prompt/*"], - "@services/*": ["services/*"] - }, - // ... - }, - // ... -} -``` - - - -Next,modify the `package.json` file to include a `_moduleAliases` key at the root of the object. - - - -```JSON -{ - // ... - "_moduleAliases": { - "@prompt": "dist/collection/components/prompt", - "@services": "dist/collection/services" - } -} -``` - - - -Finally, install the `module-alias` package and add it to the top of the `src/index.ts` file. - - - -```bash -npm i -D module-alias -``` - - - - - -```ts -import "module-alias/register"; -export * from "./components"; -``` - - - -Cool! With any luck we should be able to use these slick alias imports for the prompt and services directories now. - -## Create Stellar Account Class - - - -```ts -interface StellarAccount { - publicKey: string; - keystore: string; -} -``` - - - -`interface` is just the TypeScript way of setting up a tidy typed class. `StellarAccount` will be our account class. It includes the `publicKey` for easy reference later in Horizon or Astrograph calls and the Top Secret `keystore` key containing the encrypted account secret cipher. - - - -```js -@Component({ - tag: 'stellar-wallet', - styleUrl: 'wallet.scss', - shadow: true -}) -export class Wallet { - @State() account: StellarAccount - @State() prompter: Prompter = {show: false} - @State() error: any = null - - ... -} -``` - - - -Pretty standard boring bits, setting up the `@Component` with its defining values and initializing with some `@State` and `@Prop` data. You can see we’re setting up an `account` state with our `StellarAccount` class as well as a `prompter` state with that `Prompter` class from the `stellar-prompt` we imported earlier. We’re initializing that `prompter` state with a `show` value of `false` so the prompt modal rendereth not initially. - -Everything after this is the assignment of our imported events and methods from up above. Let’s begin with the `./events/componentWillLoad.ts` - - - -```js -import { handleError } from "@services/error"; -import { get } from "@services/storage"; - -export default async function componentWillLoad() { - try { - let keystore = await get("keyStore"); - - this.error = null; - - if (keystore) { - keystore = atob(keystore); - - const { publicKey } = JSON.parse(atob(JSON.parse(keystore).adata)); - - this.account = { - publicKey, - keystore, - }; - } - } catch (err) { - this.error = handleError(err); - } -} -``` - - - -`componentWillLoad` is the Stencil way of pre-filling the state and prop values before actually rendering the component. In our case we’ll use this method to populate the `account` `@State` with the saved storage `keyStore` value if there is one. At first there won’t be, so we’ll come back to this once we’ve actually gone over how to create and save accounts. For now just know it’s here, and since you’re smart, I imagine you can already kind of see how it works. - -“But wait!” you say, “What are the `@services/error` and `@services/storage` packages?” Fine, yes, we should go over those. Remember the module alias stuff from earlier? Well one was for `@prompt` and the other was for `@services`. Go ahead and create these two files and add them to the `src/services` directory. - - - -```bash -mkdir -p src/services -touch src/services/{error,storage}.ts -``` - - - -`error.ts` will look like this. - - - -```ts -import { get as loGet } from "lodash-es"; - -export function handleError(err: any) { - return loGet(err, "response.data", loGet(err, "message", err)); -} -``` - - - -Nothing fancy, just a clean little error handler we’ll make use of later when processing API requests. - -## Set Up Key Storage - -Next is `storage.ts`. - - - -```js -import { Plugins } from "@capacitor/core"; - -const { Storage } = Plugins; - -export async function set(key: string, value: any): Promise { - await Storage.set({ - key, - value, - }); -} - -export async function get(key: string): Promise { - const item = await Storage.get({ key }); - return item.value; -} - -export async function remove(key: string): Promise { - await Storage.remove({ key }); -} -``` - - - -You’ll notice a new package `@capacitor/core`. Let’s install and set that up. - - - -```bash -# Install dependencies -npm i -D @capacitor/core@2 @capacitor/cli@2 - -# Initialize Capacitor -npx cap init -``` - - - - - -```bash -? App name Stellar Wallet -? App Package ID (in Java package format, no dashes) com.wallet.stellar -? Which npm client would you like to use? npm -✔ Initializing Capacitor project in /Users/user/Stellar/docs-wallet in 1.91ms - - -🎉 Your Capacitor project is ready to go! 🎉 - -Add platforms using "npx cap add": - - npx cap add android - npx cap add ios - npx cap add electron - -Follow the Developer Workflow guide to get building: -https://capacitor.ionicframework.com/docs/basics/workflow -``` - - - -We’re not really making full use of [ Capacitor ][2], but it is an amazing service so be sure and check it out! For now we just need it to make storing and retrieving our data a bit more stable. - -This storage service is simply a key setter and getter helper for storing and retrieving data. We’ll use this for any persistent data we want to store. For now, that's our Stellar account data. - -## Set Up Event Handling - -That’s everything we need for the `componentWillLoad` event. On to the `./events/render.tsx` file. - - - -```tsx -import { h } from "@stencil/core"; - -export default function render() { - return [ - , - this.account ? ( - [ - , - ] - ) : ( - - ), - - this.error ? ( -
{JSON.stringify(this.error, null, 2)}
- ) : null, - this.account ? ( - - ) : null, - ]; -} -``` - -
- -It looks messy, but it’s actually a pretty simple `.tsx` file rendering out our DOM based off a series of conditional values. You can see we’re including the `stellar-prompt` component, and setting the prompter prop to our `this.prompter` state. We then have a ternary operation toggling between a Create Account button and a basic account UI. If `this.account` has a truthy value, we’ll print out the account’s `publicKey` along with some interaction buttons. If `this.account` is falsey, we’ll print out a singular Create Account button connected to, you guessed it, the `createAccount` method. After that logic, we print out an error if there is one, and finally a Sign Out button if there’s an account to sign out of. Those are the two `Wallet` `@Component` events. - -## Create Methods - -Let’s look at the methods now beginning with the `./methods/createAccount.ts` file. - - - -```ts -import sjcl from "@tinyanvil/sjcl"; -import { Keypair } from "stellar-sdk"; - -import { handleError } from "@services/error"; -import { set } from "@services/storage"; - -export default async function createAccount(e: Event) { - try { - e.preventDefault(); - - const pincode_1 = await this.setPrompt("Enter a keystore pincode"); - const pincode_2 = await this.setPrompt("Enter keystore pincode again"); - - if (!pincode_1 || !pincode_2 || pincode_1 !== pincode_2) - throw "Invalid pincode"; - - this.error = null; - - const keypair = Keypair.random(); - - this.account = { - publicKey: keypair.publicKey(), - keystore: sjcl.encrypt(pincode_1, keypair.secret(), { - adata: JSON.stringify({ - publicKey: keypair.publicKey(), - }), - }), - }; - - await set("keyStore", btoa(this.account.keystore)); - } catch (err) { - this.error = handleError(err); - } -} -``` - - - -Aha! Finally something interesting. This method forms the meat of our component. Before we dive into it, though let’s install the missing `@tinyanvil/sjcl` package. - - - -```bash -npm i -D @tinyanvil/sjcl -``` - - - -## Create an Account - -Essentially all we’re doing is making a request to create an account, which triggers the Prompt modal to ask for a pincode. That pincode will be used in the `sjcl.encrypt` method to encrypt the secret key from the `Keypair.random()` method. We set the `this.account` with the `publicKey`, which encrypted the `keystore` cipher, and now we're storing that cipher in base64 format in `localStorage` via our `set('keyStore')` method for easy retrieval when the browser reloads. We could also encode that cipher into a QR code or a link to share with other devices. Since it requires the pincode that encrypted cipher, it's as secure as the pincode you encrypt it with. - -## Copy Address - -Now that we’ve created an account, there are three more actions we'll enable: `copyAddress`, `copySecret`, and `signOut`. - -First `./methods/copyAddress.ts` - - - -```ts -import copy from "copy-to-clipboard"; - -export default async function copyAddress(e: Event) { - e.preventDefault(); - copy(this.account.publicKey); -} -``` - - - -Well there you go, the easiest code you’ll see all day. Just `copy` the `publicKey` from the `this.account` object to the clipboard. Before we jump though don’t forget to install that `copy-to-clipboard` package. - - - -```bash -npm i -D copy-to-clipboard -``` - - - -## Copy Secret - -Next `./methods/copySecret.ts` - - - -```ts -import sjcl from "@tinyanvil/sjcl"; -import copy from "copy-to-clipboard"; - -import { handleError } from "@services/error"; - -export default async function copySecret(e: Event) { - try { - e.preventDefault(); - - const pincode = await this.setPrompt("Enter your keystore pincode"); - - if (!pincode) return; - - this.error = null; - - const secret = sjcl.decrypt(pincode, this.account.keystore); - copy(secret); - } catch (err) { - this.error = handleError(err); - } -} -``` - - - -You may not actually include this in your production wallet, but for now it's a simple demonstration of how to programmatically gain access to the secret key at a later date for making payments, creating trustlines, etc. It’s essentially the `createAccount` in reverse: it asks for the pincode to decrypt the keystore which, once decrypted, we `copy` into the clipboard. - -## Sign Out - -Finally `./methods/signOut.ts` - - - -```ts -import { remove } from "@services/storage"; -import { handleError } from "@services/error"; - -export default async function signOut(e: Event) { - try { - e.preventDefault(); - - const confirmNuke = await this.setPrompt( - "Are you sure? This will nuke your account", - "Enter NUKE to confirm", - ); - - if (!confirm || !/nuke/gi.test(confirmNuke)) return; - - this.error = null; - - await remove("keyStore"); - location.reload(); - } catch (err) { - this.error = handleError(err); - } -} -``` - - - -It’s important to allow users to nuke their account, but we need to be careful to confirm that action with our faithful `setPrompt`. Once they opt to “NUKE” the account we can remove the `keyStore` and reload the app. - -## Set Prompt - -Speaking of `setPrompt` the last method in our `wallet.ts` file is `./methods/setPrompt.ts`. - - - -```ts -export default function setPrompt( - message: string, - placeholder?: string, - options?: Array, -): Promise { - this.prompter = { - ...this.prompter, - show: true, - message, - placeholder, - options, - }; - - return new Promise((resolve, reject) => { - this.prompter.resolve = resolve; - this.prompter.reject = reject; - }); -} -``` - - - -In `setPrompt`, we see how the prompt state is set, and how the Promise is set up to allow us to wait on the prompt whenever we call this method. It’s actually pretty slick, and it might be worth looking back at the `src/components/prompt/prompt.tsx` to see how the `resolve` and `reject` functions get called. It’s not central to our wallet creation, but it’s a pretty handy little component that will serve us well in the future as we continue to request input from the user. - -That’s it folks! Restart the server with `npm start` and you’ve got a perfectly legitimate, minimal Stellar wallet key creation and storage Web Component! It's a solid foundation for a non-custodial wallet that relies on a simple pincode. - -[1]: https://github.com/stellar/docs-wallet/tree/setup -[2]: https://capacitor.ionicframework.com/ "Capacitor" diff --git a/docs/building-apps/example-application-tutorial/connect-to-anchors/_category_.json b/docs/building-apps/example-application-tutorial/connect-to-anchors/_category_.json deleted file mode 100644 index 26c36affb..000000000 --- a/docs/building-apps/example-application-tutorial/connect-to-anchors/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "position": 70, - "label": "Deposit and Withdraw From Anchors", - "link": { - "type": "generated-index" - } -} \ No newline at end of file diff --git a/docs/building-apps/example-application-tutorial/connect-to-anchors/deposit-anchored-assets.mdx b/docs/building-apps/example-application-tutorial/connect-to-anchors/deposit-anchored-assets.mdx deleted file mode 100644 index 734a4bd3b..000000000 --- a/docs/building-apps/example-application-tutorial/connect-to-anchors/deposit-anchored-assets.mdx +++ /dev/null @@ -1,453 +0,0 @@ ---- -title: Deposit Anchored Assets -sidebar_position: 20 ---- - -import { CodeExample } from "@site/src/components/CodeExample"; -import { Alert } from "@site/src/components/Alert"; - - - -This section of the tutorial takes the [basic wallet](../basic-wallet.mdx) with [trustlines](../custom-assets.mdx) and [anchor connections](./setup-for-anchored-assets.mdx) enabled and adds the ability to initiate in-app deposits with an Anchor. If you have all that ready, and the stellar.toml file is loaded into a `@Prop` on your component, you’re ready to begin the initial deposit of their asset into our wallet. - - - -## Create Deposit Method - -Let’s create `./methods/depositAsset.ts`. - - - -```ts -import sjcl from "@tinyanvil/sjcl"; -import { Transaction, Keypair } from "stellar-sdk"; -import axios from "axios"; -import { - get as loGet, - each as loEach, - findIndex as loFindIndex, -} from "lodash-es"; - -import { handleError } from "@services/error"; - -export default async function depositAsset(e: Event) { - try { - e.preventDefault(); - - let currency = await this.setPrompt( - "Select the currency you'd like to deposit", - null, - this.toml.CURRENCIES, - ); - currency = currency.split(":"); - - const pincode = await this.setPrompt("Enter your keystore pincode"); - - if (!pincode) return; - - const balances = loGet(this.account, "state.balances"); - const hasCurrency = loFindIndex(balances, { - asset_code: currency[0], - asset_issuer: currency[1], - }); - - if (hasCurrency === -1) - await this.trustAsset(null, currency[0], currency[1], pincode); - - const info = await axios - .get(`${this.toml.TRANSFER_SERVER}/info`) - .then(({ data }) => data); - - console.log(info); - - const auth = await axios - .get(`${this.toml.WEB_AUTH_ENDPOINT}`, { - params: { - account: this.account.publicKey, - }, - }) - .then(async ({ data }) => { - const transaction: any = new Transaction( - data.transaction, - data.network_passphrase, - ); - - this.error = null; - this.loading = { ...this.loading, deposit: true }; - - const keypair = Keypair.fromSecret( - sjcl.decrypt(pincode, this.account.keystore), - ); - - transaction.sign(keypair); - return transaction.toXDR(); - }) - .then((transaction) => - axios.post( - `${this.toml.WEB_AUTH_ENDPOINT}`, - { transaction }, - { headers: { "Content-Type": "application/json" } }, - ), - ) - .then(({ data: { token } }) => token); - - console.log(auth); - - const formData = new FormData(); - - loEach( - { - asset_code: currency[0], - account: this.account.publicKey, - lang: "en", - }, - (value, key) => formData.append(key, value), - ); - - const interactive = await axios - .post( - `${this.toml.TRANSFER_SERVER}/transactions/deposit/interactive`, - formData, - { - headers: { - Authorization: `Bearer ${auth}`, - "Content-Type": "multipart/form-data", - }, - }, - ) - .then(({ data }) => data); - - console.log(interactive); - - const transactions = await axios - .get(`${this.toml.TRANSFER_SERVER}/transactions`, { - params: { - asset_code: currency[0], - limit: 1, - kind: "deposit", - }, - headers: { - Authorization: `Bearer ${auth}`, - }, - }) - .then(({ data: { transactions } }) => transactions); - - console.log(transactions); - - const urlBuilder = new URL(interactive.url); - urlBuilder.searchParams.set("callback", "postMessage"); - const popup = open(urlBuilder.toString(), "popup", "width=500,height=800"); - - if (!popup) { - this.loading = { ...this.loading, deposit: false }; - throw "Popups are blocked. You'll need to enable popups for this demo to work"; - } - - window.onmessage = ({ data: { transaction } }) => { - console.log(transaction.status, transaction); - - if (transaction.status === "completed") { - this.updateAccount(); - this.loading = { ...this.loading, deposit: false }; - } else { - setTimeout(() => { - const urlBuilder = new URL(transaction.more_info_url); - urlBuilder.searchParams.set("callback", "postMessage"); - - popup.location.replace(urlBuilder.toString()); - }, 1000); - } - }; - } catch (err) { - this.loading = { ...this.loading, deposit: false }; - this.error = handleError(err); - } -} -``` - - - -It’s a lot of code, but keep in mind this is everything we need to completely interoperate with financial infrastructure foreign to the Stellar ecosystem, which is a big ask and in ~130 lines of code. It’s a modern day miracle! - -## Currency Code and Issuer Prompt - -First things first install the missing `axios` package. - - - -```bash -npm i -D axios -``` - - - -We’ll skip the rest of the top import stuff as you’re well aware of what that is, and we’ve installed and walked through anything noteworthy here already. - - - -```ts -export default async function depositAsset(e: Event) { - try { - e.preventDefault() - - let currency = await this.setPrompt('Select the currency you\'d like to deposit', null, this.toml.CURRENCIES) - currency = currency.split(':') - - const pincode = await this.setPrompt('Enter your keystore pincode') - - if (!pincode) - return - - const keypair = Keypair.fromSecret( - sjcl.decrypt(pincode, this.account.keystore) - ) -``` - - - -Only thing here we haven’t seen before is the prompt selection of the currency code and issuer we’d like to deposit. To get this, we send the `this.setPrompt` a final options array argument, in this case the values from `this.toml.CURRENCIES`. This will open the prompt with a select<\>options input field rather than a text input field. - -That selection will come back as a string in the form of `{code}:{issuer}` so we split that by the `:` so we’ll have a nice tidy array of `[{code}, {issuer}]` to use later. - -## Check Trustline - - - -```ts -const balances = loGet(this.account, "state.balances"); -const hasCurrency = loFindIndex(balances, { - asset_code: currency[0], - asset_issuer: currency[1], -}); - -if (hasCurrency === -1) - await this.trustAsset(null, currency[0], currency[1], pincode); -``` - - - -Once we’ve got the currency we’re dealing with we need to check if we have a trustline for that asset setup for our account. The anchor won’t be able to deposit their token into our account if we don’t have a trustline set for it first. So we get the balance from the `this.account.state` and then inspect the `balances` to see if that currency exists. If it doesn’t we trigger the `this.trustAsset` method with the arguments set to automatically add that trustline to our account. - -## Get Info - - - -```ts -const info = await axios - .get(`${this.toml.TRANSFER_SERVER}/info`) - .then(({ data }) => data); - -console.log(info); -``` - - - -Once our account is setup, it’s time to start asking the Anchor some questions about itself and the features it supports. We get at that info by calling a GET on the `TRANSFER_SERVER/info` url from the anchor’s TOML file. We won’t make use of any of this data right now, but this is where you'd find fee and feature information which to display in you UI for your wallet user to review. - -## Create Authenticated User Session - - - -```ts -const auth = await axios - .get(`${this.toml.WEB_AUTH_ENDPOINT}`, { - params: { - account: this.account.publicKey, - }, - }) - .then(async ({ data: { transaction, network_passphrase } }) => { - const txn: any = new Transaction(transaction, network_passphrase); - - this.error = null; - this.loading = { ...this.loading, withdraw: true }; - - txn.sign(keypair); - return txn.toXDR(); - }) - .then((transaction) => - axios.post( - `${this.toml.WEB_AUTH_ENDPOINT}`, - { transaction }, - { headers: { "Content-Type": "application/json" } }, - ), - ) - .then(({ data: { token } }) => token); - -console.log(auth); -``` - - - -This call is actually a part of [SEP-0010](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md), which allows us to verify ownership of a user's public key so the Anchor knows the deposit request is coming from a valid entity. You don’t want someone else issuing deposit requests on your account, so to prove you control the Stellar account request the deposit, you sign a dummy authentication transaction and send it to the Anchor's web auth server. The server responds with a JWT token, which will be used to verify all further API calls to the anchor. - -The endpoint for creating an authenticated user session is specified the `WEB_AUTH_ENDPOINT` on an Anchor's stellar.toml file. The first thing our wallet does is make a GET request with a public `account` param which will send back an unsigned Stellar transaction for that account that has an invalid sequence number, so it doesn't actually _do_ anything when submitted to the network. In response you’ll sign that transaction on behalf of the user and POST it back. If the signature checks out, the success response will contain an Authorization Bearer header JWT which you’ll want to store and use for all future interactions with the Anchor. - -## Initiate Deposit - - - -```ts -const formData = new FormData(); - -loEach( - { - asset_code: currency[0], - account: this.account.publicKey, - lang: "en", - }, - (value, key) => formData.append(key, value), -); - -const interactive = await axios - .post( - `${this.toml.TRANSFER_SERVER}/transactions/withdraw/interactive`, - formData, - { - headers: { - Authorization: `Bearer ${auth}`, - "Content-Type": "multipart/form-data", - }, - }, - ) - .then(({ data }) => data); - -console.log(interactive); -``` - - - -This call is our first little bit of magic. Once we setup our `multipart/form-data` entry values we can POST them to the `${this.toml.TRANSFER_SERVER}/transactions/withdraw/interactive` endpoint along with our `auth` Authorization Bearer `auth` token we acquired earlier. The response to this call will contain a special url that allows a user to interact directly with the Anchor to provide the data required for a deposit. - - - -```json -{ - "type": "interactive_customer_info_needed", - "url": "https://testanchor.stellar.org/transactions/deposit/webapp?asset_code=SRT&transaction_id=3dcf204e-e3e8-4831-a840-8e36c0695a07&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3N0ZWxsYXItYW5jaG9yLXNlcnZlci5oZXJva3VhcHAuY29tL3RyYW5zYWN0aW9ucy9kZXBvc2l0L2ludGVyYWN0aXZlIiwiaWF0IjoxNTgxNDUyMjI0Ljk4NzcyNjcsImV4cCI6MTU4MTQ1MjI1NC45ODc3MjY3LCJzdWIiOiJHQjM0QVU2NlRTR1Q1RlMzRVVMSk9UUjMyTVdLQU9NRlpLNk1QV003VjRTSUJOTE41UDVURlJKRyIsImp0aSI6IjNkY2YyMDRlLWUzZTgtNDgzMS1hODQwLThlMzZjMDY5NWEwNyJ9.N4N_vIUGu6y7-Hd5IlvevX4DLg9PjisuYEl98ejvhf8", - "id": "3dcf204e-e3e8-4831-a840-8e36c0695a07" -} -``` - - - -In a moment we’ll open that `url` in an iframe, popup, or new tab. Once we’ve sent that request, there will be a pending transaction request we can inspect at the `${this.toml.TRANSFER_SERVER}/transactions` route. - -## Check Transaction Status - - - -```ts -const transactions = await axios - .get(`${this.toml.TRANSFER_SERVER}/transactions`, { - params: { - asset_code: currency[0], - limit: 1, - kind: "deposit", - }, - headers: { - Authorization: `Bearer ${auth}`, - }, - }) - .then(({ data: { transactions } }) => transactions); - -console.log(transactions); -``` - - - -This request should return the deposit status for the request we just made. - - - -```json -{ - "transactions": [ - { - "id": "3dcf204e-e3e8-4831-a840-8e36c0695a07", - "kind": "deposit", - "status": "incomplete", - "status_eta": 3600, - "amount_in": null, - "amount_out": null, - "amount_fee": null, - "started_at": "2020-02-11T20:17:04.984590Z", - "completed_at": null, - "stellar_transaction_id": null, - "external_transaction_id": null, - "external_extra": null, - "external_extra_text": null, - "deposit_memo": null, - "deposit_memo_type": "text", - "more_info_url": "https://testanchor.stellar.org/transaction/more_info?id=3dcf204e-e3e8-4831-a840-8e36c0695a07", - "to": "GB34AU66TSGT5FS3EULJOTR32MWKAOMFZK6MPWM7V4SIBNLN5P5TFRJG", - "from": null - } - ] -} -``` - - - -Once we’re certain we’ve got a `"status": "incomplete",` which is the correct response since we haven't served the user the URL that allows them to initiate a deposit, we know everything's working, so we can go back to the `interactive.url` route and open that to begin filling out the deposit requirements. - -## Serve the Anchor Webapp - - - -```ts -const urlBuilder = new URL(interactive.url); -urlBuilder.searchParams.set("callback", "postMessage"); -const popup = open(urlBuilder.toString(), "popup", "width=500,height=800"); - -if (!popup) { - this.loading = { ...this.loading, deposit: false }; - throw "Popups are blocked. You'll need to enable popups for this demo to work"; -} -``` - - - -We’ll opt for a popup. When you first open that url, it’s likely the anchor will ask for some level of KYC data from the user: name, email, address, verification docs like bank statements, passport, or license, etc. The SDF demo server we're using — which is hooked up to the testnet — will ask for name and email. - -After passing that screen your user enters the amount of an asset they'd like to deposit on the next screen. If, for instance, a user enters $500, once that deposit clears — and on this demo it clears automatically — the Anchor will credit the user's wallet with 500 of the token **less any fees**. In our case, the user ends up with 498.95: 1.05 is taken out in fees for a $500 deposit. - -If popups are disabled, we should kill the loader and show that error in the UI. - - - -```ts - window.onmessage = ({data: {transaction}}) => { - console.log(transaction.status, transaction) - - if (transaction.status === 'completed') { - this.updateAccount() - this.loading = {...this.loading, deposit: false} - } - - else { - setTimeout(() => { - const urlBuilder = new URL(transaction.more_info_url) - urlBuilder.searchParams.set('callback', 'postMessage') - - popup.location.replace(urlBuilder.toString()) - }, 1000) - } - } - } - - catch (err) { - this.loading = {...this.loading, deposit: false} - this.error = handleError(err) - } -} -``` - - - -## Check Deposit Status - -SEP-0024 allows specifies two methods for further communication between the anchor window and the wallet: a POST JSON for when you have a server, message and postMessage for when you have a client-side service. We don’t have a server, so we opt for the `urlBuilder.searchParams.set('callback', 'postMessage')`. With that set, we can setup a window `'message'` event listener which will fire whenever the anchor popup window sends a `postMessage` to our popup `window`. From there we just listen to the popup message until `transaction.status` equals `'completed'`. At that point our deposit has succeeded, and we can `this.updateAccount()` and kill the loader. If the transaction is still in a pending status we’ll wait 1 second before reloading the anchor popup window and checking again. - -If at any point during this flow there’s an error we should catch that, kill the loader, and display the error to the user. - -Whew! \*wipes sweat from brow then hands on sleeves Nice work! “Just like that” we’ve deposited an anchored asset into our wallet! We can now make payments with that asset to anyone else who has a trustline enabled for this asset. diff --git a/docs/building-apps/example-application-tutorial/connect-to-anchors/index.mdx b/docs/building-apps/example-application-tutorial/connect-to-anchors/index.mdx deleted file mode 100644 index ee496b8f7..000000000 --- a/docs/building-apps/example-application-tutorial/connect-to-anchors/index.mdx +++ /dev/null @@ -1,14 +0,0 @@ ---- -title: Interoperability Basics -sidebar_position: 0 ---- - -Stellar makes it easy to issue assets and to connect them to existing banking rails so that users can move value onto — and off of — the network. The services that create those connections are called **anchors**. - -Most Anchors set up infrastructure to enable wallets to offer in-app deposits and withdrawals by following best practices specified in Stellar Ecosystem Proposals. SEPs are publicly created, open-source documents that live in a [Github repository](https://github.com/stellar/stellar-protocol/tree/master/ecosystem#stellar-ecosystem-proposals-seps). They define how different institutions (such as asset issuers, wallets, exchanges, and service providers) should interact and interoperate. If you're building an app, you can implement the client side of some key SEPs and immediately give your users access to a whole world of local fiat currencies - -This part of the tutorial will focus on the Interactive Anchor/Wallet Asset Transfer Server SEP (aka SEP-24), which defines the specs for deposit and withdrawal implementations. It's focused on the client side of interactive user flows — meaning flows where users interact with an Anchor-hosted interface rendered inside a wallet — and by the end, you should have an implementation which can be re-purposed to work with any SEP-supporting Anchor. - -When you implement SEP-0024, users can tokenize their grocery-buying dollars, pesos, or naira, use them on the Stellar network and, when they're ready, redeem them for cash in hand or money in the bank — and they can do it all from the comfort of your app. - -Most Anchors offer fiat-backed assets, and SEP-24 is set up to allow them to handle various KYC and AML requirements. But SEP-24 allows for the deposit and withdraw of cryptocurrencies like BTC, ETH, and ERC20 tokens like USDT. If the financial landscape is a bunch of lakes, SEP-0024 is a series of rivers by which you move your currency canoe in and out of the Stellar lake. diff --git a/docs/building-apps/example-application-tutorial/connect-to-anchors/setup-for-anchored-assets.mdx b/docs/building-apps/example-application-tutorial/connect-to-anchors/setup-for-anchored-assets.mdx deleted file mode 100644 index bbf10b5a9..000000000 --- a/docs/building-apps/example-application-tutorial/connect-to-anchors/setup-for-anchored-assets.mdx +++ /dev/null @@ -1,356 +0,0 @@ ---- -title: Setup for Anchored Assets -sidebar_position: 10 ---- - -import { CodeExample } from "@site/src/components/CodeExample"; - -So how do we make use of SEP-0024 to allow deposits and withdrawals of anchored assets? First let’s boot up our project: - -[View trustline boilerplate code on GitHub][1] - -Next, let's think about our goals. What we’re trying to do is communicate with Anchors to get information about the assets they honor, and about the requirements and steps necessary to initiate a deposit or withdrawal on behalf of a user. When a user deposits with an Anchor — by sending dollars to their bank account via ACH, for example — the Anchor will credit their Stellar account with the equivalent amount of tokens. The user can then hold, transfer, or trade those tokens just like any other Stellar asset. When a user withdraws those tokens — generally by making a payment back to the Anchor's Stellar account — the Anchor redeems them for cash in hand or money in the bank. If you’re still a little lost it will all hopefully become clear as we get coding. - -This tutorial will consist of a few minor `./events/` updates and two new `./methods/`. Let’s start with the updates first. We actually need to update the core `wallet.ts` component. - -## Update Wallet Component - - - -```ts -import { Component, State, Prop } from "@stencil/core"; -import { Server, ServerApi } from "stellar-sdk"; - -import componentWillLoad from "./events/componentWillLoad"; // UPDATE -import render from "./events/render"; // UPDATE - -import createAccount from "./methods/createAccount"; -import updateAccount from "./methods/updateAccount"; -import depositAsset from "./methods/depositAsset"; // NEW -import withdrawAsset from "./methods/withdrawAsset"; // NEW -import trustAsset from "./methods/trustAsset"; -import makePayment from "./methods/makePayment"; -import copyAddress from "./methods/copyAddress"; -import copySecret from "./methods/copySecret"; -import signOut from "./methods/signOut"; -import setPrompt from "./methods/setPrompt"; - -import { Prompter } from "@prompt/prompt"; - -interface StellarAccount { - publicKey: string; - keystore: string; - state?: ServerApi.AccountRecord; -} - -interface Loading { - fund?: boolean; - pay?: boolean; - trust?: boolean; - update?: boolean; - deposit?: boolean; // NEW - withdraw?: boolean; // NEW -} - -@Component({ - tag: "stellar-wallet", - styleUrl: "wallet.scss", - shadow: true, -}) -export class Wallet { - @State() account: StellarAccount; - @State() prompter: Prompter = { show: false }; - @State() loading: Loading = {}; - @State() error: any = null; - - @Prop() server: Server; - @Prop() homeDomain: String; // NEW - @Prop() toml: Object; // NEW - - // Component events - componentWillLoad() {} - render() {} - - // Stellar methods - createAccount = createAccount; - updateAccount = updateAccount; - depositAsset = depositAsset; // NEW - withdrawAsset = withdrawAsset; // NEW - trustAsset = trustAsset; - makePayment = makePayment; - copyAddress = copyAddress; - copySecret = copySecret; - signOut = signOut; - - // Misc methods - setPrompt = setPrompt; -} - -Wallet.prototype.componentWillLoad = componentWillLoad; -Wallet.prototype.render = render; -``` - - - -You can see from the `// NEW` and `// UPDATE` comments what we are adding and updating. Nothing worth noting here other than near the bottom two new `@Prop`’s. - - - -```ts -@Prop() homeDomain: String // NEW -@Prop() toml: Object // NEW -``` - - - -We’ll talk more about home domain’s and stellar.toml files in a moment, but take special note of these as they will play a critical roll in connecting tp the world outside of Stellar. - -## Add Deposit and Withdraw Buttons - -Next let’s add a couple buttons for deposit and withdraw to the `./events/render.tsx`. - - - -```tsx -import { h } from "@stencil/core"; -import { has as loHas } from "lodash-es"; - -export default function render() { - return [ - , - - this.account ? ( - [ - , - - , - , - - , - , - ] - ) : ( - - ), - - this.error ? ( -
{JSON.stringify(this.error, null, 2)}
- ) : null, - - loHas(this.account, "state") ? ( - - ) : null, - - this.account - ? [ - , - , - ] - : null, - ]; -} -``` - -
- -This is the same as what we did in the previous tutorial except that we're adding two buttons. - - - -```tsx -, -, -``` - - - -“Deposit Asset” and “Withdraw Asset” connect to the `this.depositAsset` and `this.withdrawAsset` methods respectively. We’ll create those methods momentarily. - -Before that though let’s make a change to the `./events/componentWillLoad.ts` file. - -## Update Components - - - -```ts -import { Server, StellarTomlResolver } from "stellar-sdk"; -import { handleError } from "@services/error"; -import { get } from "@services/storage"; - -export default async function componentWillLoad() { - try { - let keystore = await get("keyStore"); - - this.error = null; - this.server = new Server("https://horizon-testnet.stellar.org"); - this.homeDomain = "testanchor.stellar.org"; - this.toml = await StellarTomlResolver.resolve(this.homeDomain); - - if (keystore) { - keystore = atob(keystore); - - const { publicKey } = JSON.parse(atob(JSON.parse(keystore).adata)); - - this.account = { - publicKey, - keystore, - }; - - this.updateAccount(); - } - } catch (err) { - this.error = handleError(err); - } -} -``` - - - -Here, the only changes we're making are to include of the `StellarTomlResolver` from the `stellar-sdk` package and to set the values for `this.homeDomain` and `this.toml`. - - - -```ts -this.homeDomain = "testanchor.stellar.org"; -this.toml = await StellarTomlResolver.resolve(this.homeDomain); -``` - - - -## About stellar.toml Files - -You know what, let’s just go ahead and cover stellar.toml files. A `stellar.toml` file is a static resource that organizations building on Stellar publish on their home domain at `https://{homeDomain}/.well-known/stellar.toml`. By linking their home domain to a Stellar account using a `set_options` operation, they create a verifiable connection from that account to the information published there. To find out everything you'd ever want to know about stellar.toml files, check out [SEP-1], which is the complete stellar.toml specification. - -Stellar.toml files contain all sorts of information about an organization, the assets they offer, and the integrations they support. Wallets can look at an account, find the home domain, and crawl a stellar.toml to find out pretty much everything they need to know about an Anchor, and that's exactly what the Stellar SDK `StellarTomlResolver.resolve` method does: it pulls in a stellar.toml and parses it. - -Let's look at some concrete examples: here’s [StellarX.com’s stellar.toml file][2]. - - - -```toml -# StellarX -VERSION="2.2.0" -FEDERATION_SERVER="https://federation.stellarx.com/federation" -ACCOUNTS=[ -"GDM4UWTGHCWSTM7Z46PNF4BLH35GS6IUZYBWNNI4VU5KVIHYSIVQ55Y6" -] -[DOCUMENTATION] -ORG_NAME="Ultra Stellar LLC" -ORG_DBA="StellarX" -ORG_URL="https://www.stellarx.com" -ORG_LOGO="https://www.stellarx.com/emailAssets/stellarx.png" -ORG_DESCRIPTION="The first full-featured trading app for Stellar's universal marketplace" -ORG_PHYSICAL_ADDRESS="Tallinn, Estonia" -ORG_OFFICIAL_EMAIL="support@stellarx.com" -``` - - - -And here's [AnchorUSD]'s[3]. - - - -```toml -# ----- AnchorUSD Stellar Anchor ----- - -NETWORK_PASSPHRASE="Public Global Stellar Network ; September 2015" - -ACCOUNTS=["GDUKMGUGDZQK6YHYA5Z6AY2G4XDSZPSZ3SW5UN3ARVMO6QSRDWP5YLEX", "GASWJWFRYE55KC7MGANZMMRBK5NPXT3HMPDQ6SEXZN6ZPWYXVVYBFRTE"] -TRANSFER_SERVER="https://api.anchorusd.com/transfer/" -TRANSFER_SERVER_SEP0024="https://api.anchorusd.com/transfer/" -WEB_AUTH_ENDPOINT="https://api.anchorusd.com/api/webauth" -SIGNING_KEY="GASWJWFRYE55KC7MGANZMMRBK5NPXT3HMPDQ6SEXZN6ZPWYXVVYBFRTE" - -[DOCUMENTATION] -ORG_NAME="AnchorCoin LLC" -ORG_DBA="AnchorUSD" -ORG_URL="https://www.anchorusd.com" -ORG_LOGO="https://stablecoin.anchorusd.com/img/anchorusd.png" -ORG_DESCRIPTION="AnchorUSD develops a stable cryptocurrency backed one-for-one to the US dollar." -ORG_TWITTER="AnchorUSD" -ORG_OFFICIAL_EMAIL="support@anchorusd.com" - -[[PRINCIPALS]] -name="Jim Berkley-Danz" -email="j@anchorusd.com" - -[[CURRENCIES]] -code="USD" -issuer="GDUKMGUGDZQK6YHYA5Z6AY2G4XDSZPSZ3SW5UN3ARVMO6QSRDWP5YLEX" -display_decimals=2 -status="live" -is_asset_anchored=true -anchor_asset_type="fiat" -anchor_asset="USD" -name="US Dollar" -desc="Cryptocurrency backed one-for-one to the US dollar. All dollar deposits are held in an audited, US-domiciled escrow account for the exclusive benefit of AnchorUSD token holders." -image="https://stablecoin.anchorusd.com/img/usdx.png" -``` - - - -You can see the data provided by these companies that identifies who they are, what they do, and what services they provide. In this tutorial, we’re interested in the `[[CURRENCIES]]` they issue as that’s what we’re trying to get ahold of. We’re also looking for the `TRANSFER_SERVER` keyword, which indicates that an Anchor supports SEP-24, and the `WEB_AUTH_ENDPOINT`, which allows a wallet to set up an authenticated user session. Any time you find these three fields, and you’ve found an Anchor you can interoperate with. - -Once we’ve found an Anchor that supports deposit and withdrawal, we can begin the process of connecting with them from our wallet. This tutorial builds on the testnet, so from we’ll be use an SDF testing anchor server located at `testanchor.stellar.org` You can [view the TOML file for this entity][5] here. - -[1]: https://github.com/stellar/docs-wallet/tree/trustline -[2]: https://www.stellarx.com/.well-known/stellar.toml -[3]: https://stablecoin.anchorusd.com/.well-known/stellar.toml -[4]: https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md -[5]: https://testanchor.stellar.org/.well-known/stellar.toml diff --git a/docs/building-apps/example-application-tutorial/connect-to-anchors/withdraw-anchored-assets.mdx b/docs/building-apps/example-application-tutorial/connect-to-anchors/withdraw-anchored-assets.mdx deleted file mode 100644 index 85813f156..000000000 --- a/docs/building-apps/example-application-tutorial/connect-to-anchors/withdraw-anchored-assets.mdx +++ /dev/null @@ -1,326 +0,0 @@ ---- -title: Withdraw Anchored Assets -sidebar_position: 30 ---- - -import { CodeExample } from "@site/src/components/CodeExample"; -import { Alert } from "@site/src/components/Alert"; - - - -At this point, you should have a [basic wallet](../basic-wallet.mdx) that can handle [custom assets](../custom-assets.mdx), and you should have [enabled deposits](./deposit-anchored-assets.mdx) and used the SDF-maintained testnet [Anchor Reference Implementation](https://testanchor.stellar.org/.well-known/stellar.toml) to get some test tokens into your wallet. After you’ve had some fun with your new asset, it's time to learn to perform this process in reverse, and that's what we'll do here: set your wallet up to handle withdrawals. - - - -In a live situation, this is the step when a user takes a Stellar-based token and redeems it with an Anchor for the underlying asset it represents. It's how they'd move money off the network and back into their bank account, for instance. - -## Create Withdraw Method - -To start, create `./methods/withdrawAsset.ts` and pop this in. - - - -```ts -import sjcl from "@tinyanvil/sjcl"; -import { - Transaction, - Keypair, - Account, - TransactionBuilder, - BASE_FEE, - Networks, - Operation, - Asset, - Memo, - MemoHash, -} from "stellar-sdk"; - -import axios from "axios"; -import { - get as loGet, - each as loEach, - findIndex as loFindIndex, -} from "lodash-es"; - -import { handleError } from "@services/error"; - -export default async function withdrawAsset(e: Event) { - try { - e.preventDefault(); - - let currency = await this.setPrompt( - "Select the currency you'd like to withdraw", - null, - this.toml.CURRENCIES, - ); - currency = currency.split(":"); - - const pincode = await this.setPrompt("Enter your keystore pincode"); - - if (!pincode) return; - - const keypair = Keypair.fromSecret( - sjcl.decrypt(pincode, this.account.keystore), - ); - - const balances = loGet(this.account, "state.balances"); - const hasCurrency = loFindIndex(balances, { - asset_code: currency[0], - asset_issuer: currency[1], - }); - - if (hasCurrency === -1) - await this.trustAsset(null, currency[0], currency[1], pincode); - - const info = await axios - .get(`${this.toml.TRANSFER_SERVER}/info`) - .then(({ data }) => data); - - console.log(info); - - const auth = await axios - .get(`${this.toml.WEB_AUTH_ENDPOINT}`, { - params: { - account: this.account.publicKey, - }, - }) - .then(async ({ data: { transaction, network_passphrase } }) => { - const txn: any = new Transaction(transaction, network_passphrase); - - this.error = null; - this.loading = { ...this.loading, withdraw: true }; - - txn.sign(keypair); - return txn.toXDR(); - }) - .then((transaction) => - axios.post( - `${this.toml.WEB_AUTH_ENDPOINT}`, - { transaction }, - { headers: { "Content-Type": "application/json" } }, - ), - ) - .then(({ data: { token } }) => token); - - console.log(auth); - - const formData = new FormData(); - - loEach( - { - asset_code: currency[0], - account: this.account.publicKey, - lang: "en", - }, - (value, key) => formData.append(key, value), - ); - - const interactive = await axios - .post( - `${this.toml.TRANSFER_SERVER}/transactions/withdraw/interactive`, - formData, - { - headers: { - Authorization: `Bearer ${auth}`, - "Content-Type": "multipart/form-data", - }, - }, - ) - .then(({ data }) => data); - - console.log(interactive); - - const transactions = await axios - .get(`${this.toml.TRANSFER_SERVER}/transactions`, { - params: { - asset_code: currency[0], - limit: 1, - kind: "withdrawal", - }, - headers: { - Authorization: `Bearer ${auth}`, - }, - }) - .then(({ data: { transactions } }) => transactions); - - console.log(transactions); - - const urlBuilder = new URL(interactive.url); - urlBuilder.searchParams.set("callback", "postMessage"); - const popup = open(urlBuilder.toString(), "popup", "width=500,height=800"); - - if (!popup) { - this.loading = { ...this.loading, withdraw: false }; - throw "Popups are blocked. You'll need to enable popups for this demo to work"; - } - - await new Promise((resolve, reject) => { - let submittedTxn; - - window.onmessage = ({ data: { transaction } }) => { - console.log(transaction.status, transaction); - - if (transaction.status === "completed") { - this.updateAccount(); - this.loading = { ...this.loading, withdraw: false }; - resolve(); - } else if ( - !submittedTxn && - transaction.status === "pending_user_transfer_start" - ) { - this.server - .accounts() - .accountId(keypair.publicKey()) - .call() - .then(({ sequence }) => { - const account = new Account(keypair.publicKey(), sequence); - const txn = new TransactionBuilder(account, { - fee: BASE_FEE, - networkPassphrase: Networks.TESTNET, - }) - .addOperation( - Operation.payment({ - destination: transaction.withdraw_anchor_account, - asset: new Asset(currency[0], currency[1]), - amount: transaction.amount_in, - }), - ) - .addMemo(new Memo(MemoHash, transaction.withdraw_memo)) - .setTimeout(0) - .build(); - - txn.sign(keypair); - return this.server.submitTransaction(txn); - }) - .then((res) => { - console.log(res); - submittedTxn = res; - - const urlBuilder = new URL(transaction.more_info_url); - urlBuilder.searchParams.set("callback", "postMessage"); - - popup.location.replace(urlBuilder.toString()); - }) - .catch((err) => reject(err)); - } else { - setTimeout(() => { - const urlBuilder = new URL(transaction.more_info_url); - urlBuilder.searchParams.set("callback", "postMessage"); - - popup.location.replace(urlBuilder.toString()); - }, 1000); - } - }; - }); - } catch (err) { - this.loading = { ...this.loading, withdraw: false }; - this.error = handleError(err); - } -} -``` - - - -We’ll actually skip everything except the stuff that is significantly different than the [deposit flow](./deposit-anchored-assets.mdx). The main difference between the two is who submits the Stellar transaction: in the deposit flow the anchor is sends the wallet a Stellar asset; in the withdraw flow the wallet sends the asset to the anchor. So for the withdraw flow, we’ll need to build and submit a payment transaction. - -## Create and Submit Payment Transaction - - - -```ts - await new Promise((resolve, reject) => { - let submittedTxn - - window.onmessage = ({data: {transaction}}) => { - console.log(transaction.status, transaction) - - if (transaction.status === 'completed') { - this.updateAccount() - this.loading = {...this.loading, withdraw: false} - resolve() - } -``` - - - -First thing we’ll see is the use of a Promise. This allows us to respond to any errors in the transaction we’re about to build and submit. Inside the promise we have three if statement blocks. The first `if` statement is a response to a status of success, which is where we'll end up once the withdraw has registered and everything is hunky dory. - - - -```ts - else if ( - !submittedTxn - && transaction.status === 'pending_user_transfer_start' - ) { - this.server - .accounts() - .accountId(keypair.publicKey()) - .call() - .then(({sequence}) => { - const account = new Account(keypair.publicKey(), sequence) - const txn = new TransactionBuilder(account, { - fee: BASE_FEE, - networkPassphrase: Networks.TESTNET - }) - .addOperation(Operation.payment({ - destination: transaction.withdraw_anchor_account, - asset: new Asset(currency[0], currency[1]), - amount: transaction.amount_in - })) - .addMemo(new Memo(MemoHash, transaction.withdraw_memo)) - .setTimeout(0) - .build() - - txn.sign(keypair) - return this.server.submitTransaction(txn) - }) - .then((res) => { - console.log(res) - submittedTxn = res - - const urlBuilder = new URL(transaction.more_info_url) - urlBuilder.searchParams.set('callback', 'postMessage') - - popup.location.replace(urlBuilder.toString()) - }) - .catch((err) => reject(err)) - } -``` - - - -Otherwise if the transaction status is `pending_user_transfer_start` and we haven’t yet submitted a transaction to the Anchor, we attempt that. We load up the user's account to get the next valid sequence number, and build a Stellar [transaction](../../../fundamentals-and-concepts/stellar-data-structures/operations-and-transactions.mdx#transactions) consisting of a [payment operation](../../../fundamentals-and-concepts/stellar-data-structures/operations-and-transactions.mdx#operations) with all the details from the transaction object that the anchor is expecting. Once we have a valid transaction built, we’ll sign it with the keypair, submit the transaction to the network, and wait for a response. If the transaction is successful, we save that value to `submittedTxn` and reload the anchor popup to observe the pending status. Make sure to set the `submittedTxn` to a truthy value or else you run the risk of submitting the transaction multiple times, as the anchor may take a moment to realize you’ve successfully submitted a transaction to them. - - - -```ts - else { - setTimeout(() => { - const urlBuilder = new URL(transaction.more_info_url) - urlBuilder.searchParams.set('callback', 'postMessage') - - popup.location.replace(urlBuilder.toString()) - }, 1000) - } - } - }) - } - - catch (err) { - this.loading = {...this.loading, withdraw: false} - this.error = handleError(err) - } -} -``` - - - -The last if block is that if all else fails just keep reloading the anchor popup every second until we get a `'completed'` status. - -Finally catch and respond to any errors. - -With this method saved and the server reloaded we have a fully functional SEP-0024 compliant wallet! Noice! - -[View this code on GitHub][1] - -[1]: https://github.com/stellar/docs-wallet/tree/sep24 diff --git a/docs/building-apps/example-application-tutorial/custom-assets.mdx b/docs/building-apps/example-application-tutorial/custom-assets.mdx deleted file mode 100644 index c10a5115c..000000000 --- a/docs/building-apps/example-application-tutorial/custom-assets.mdx +++ /dev/null @@ -1,457 +0,0 @@ ---- -title: Handle Custom Assets -sidebar_position: 60 ---- - -import { CodeExample } from "@site/src/components/CodeExample"; -import { Alert } from "@site/src/components/Alert"; - - - -In this section of the tutorial, we'll add the ability to hold and transfer custom assets to the basic wallet we built in previous sections. It assumes that you've already completed [Build a Basic Wallet](./basic-wallet.mdx) and [Make XLM Payments](./xlm-payments.mdx). - - - -[View pay boilerplate code on GitHub][1] - -## What's a Custom Asset? - -Stellar allows anyone to easily issue an asset, and all assets can be held, transferred, and traded just like XLM, the network token. Every asset _other_ than XLM exists on the network in the form of trustlines: an asset holder explicitly agrees to allow a balance of a specific token issued by a specific issuing account by creating a persistent ledger entry tied to the holding account. You can find out more in the guide to [creating custom assets](../../issuing-assets/anatomy-of-an-asset.mdx). - -Each trustline increases the user's [base reserve](../../fundamentals-and-concepts/lumens#base-reserves) by 0.5 XLM, and in this tutorial, we'll go over how to set up your wallet to create trustlines and manage the base reserve on behalf of a user. - -## Add Trustlines Button - -To enable custom asset handling, we need to modify three files and create one new one. Let’s start with our modifications. First up the `./events/render.tsx` file. We need to add a button for creating these new trustlines! - - - -```tsx -import { h } from "@stencil/core"; -import { has as loHas } from "lodash-es"; - -export default function render() { - return [ - , - - this.account ? ( - [ - , - - , - , - ] - ) : ( - - ), - - this.error ? ( -
{JSON.stringify(this.error, null, 2)}
- ) : null, - - loHas(this.account, "state") ? ( - - ) : null, - - this.account - ? [ - , - , - ] - : null, - ]; -} -``` - -
- -If you look closely you’ll spot the Trust Asset button right below our `account-key` div. Nothing funky here, just a button that triggers `this.trustAsset` method which we’ll add in a moment. - -Next up, let’s update the `./methods/makePayment.ts` file. - - - -```ts -import sjcl from "@tinyanvil/sjcl"; -import { - Keypair, - Account, - TransactionBuilder, - BASE_FEE, - Networks, - Operation, - Asset, -} from "stellar-sdk"; -import { has as loHas } from "lodash-es"; - -import { handleError } from "@services/error"; - -export default async function makePayment(e: Event) { - try { - e.preventDefault(); - - let instructions = await this.setPrompt("{Amount} {Asset} {Destination}"); - instructions = instructions.split(" "); - - if (!/xlm/gi.test(instructions[1])) - instructions[3] = await this.setPrompt( - `Who issues the ${instructions[1]} asset?`, - "Enter ME to refer to yourself", - ); - - const pincode = await this.setPrompt("Enter your keystore pincode"); - - if (!instructions || !pincode) return; - - const keypair = Keypair.fromSecret( - sjcl.decrypt(pincode, this.account.keystore), - ); - - if (/me/gi.test(instructions[3])) instructions[3] = keypair.publicKey(); - - this.error = null; - this.loading = { ...this.loading, pay: true }; - - await this.server - .accounts() - .accountId(keypair.publicKey()) - .call() - .then(({ sequence }) => { - const account = new Account(keypair.publicKey(), sequence); - const transaction = new TransactionBuilder(account, { - fee: BASE_FEE, - networkPassphrase: Networks.TESTNET, - }) - .addOperation( - Operation.payment({ - destination: instructions[2], - asset: instructions[3] - ? new Asset(instructions[1], instructions[3]) - : Asset.native(), - amount: instructions[0], - }), - ) - .setTimeout(0) - .build(); - - transaction.sign(keypair); - return this.server.submitTransaction(transaction).catch((err) => { - if ( - // Paying an account which doesn't exist, create it instead - loHas(err, "response.data.extras.result_codes.operations") && - err.response.data.status === 400 && - err.response.data.extras.result_codes.operations.indexOf( - "op_no_destination", - ) !== -1 && - !instructions[3] - ) { - const transaction = new TransactionBuilder(account, { - fee: BASE_FEE, - networkPassphrase: Networks.TESTNET, - }) - .addOperation( - Operation.createAccount({ - destination: instructions[2], - startingBalance: instructions[0], - }), - ) - .setTimeout(0) - .build(); - - transaction.sign(keypair); - return this.server.submitTransaction(transaction); - } else throw err; - }); - }) - .then((res) => console.log(res)) - .finally(() => { - this.loading = { ...this.loading, pay: false }; - this.updateAccount(); - }); - } catch (err) { - this.error = handleError(err); - } -} -``` - - - -This is a big file that was covered in great detail in the [Make XLM Payments](./xlm-payments.mdx) tutorial, so we’ll just focus on the changes we need to make to support custom asset payments. - - - -```ts -let instructions = await this.setPrompt("{Amount} {Asset} {Destination}"); -instructions = instructions.split(" "); - -if (!/xlm/gi.test(instructions[1])) - instructions[3] = await this.setPrompt( - `Who issues the ${instructions[1]} asset?`, - "Enter ME to refer to yourself", - ); -``` - - - -This change allows us to indicate a specific asset code we’d like use to make a payment and triggers an additional prompt to set the issuer for that asset if it’s not the native XLM. - - - -```ts -if (/me/gi.test(instructions[3])) instructions[3] = keypair.publicKey(); -``` - - - -This is just a nifty little helper shortcut to allow us to use the `ME` “issuer” to swap with our actual account publicKey. Niceties make the world go ‘round. - - - -```ts -asset: instructions[3] ? new Asset(instructions[1], instructions[3]) : Asset.native(), -``` - - - -The final noteworthy change is a ternary operation that switches our payment asset between the native XLM and a custom asset based off of responses to our prompt. Essentially, if `instructions[3]` exists — meaning there is an issuer — use that issuer and custom token as the asset for the payment. Otherwise, just use the native `Asset`. - -The final changes are in the `wallet.ts` itself and tie together all the other updates as well as pull in the new `trustAsset` method. - - - -```ts -import { Component, State, Prop } from "@stencil/core"; -import { Server, ServerApi } from "stellar-sdk"; - -import componentWillLoad from "./events/componentWillLoad"; -import render from "./events/render"; - -import createAccount from "./methods/createAccount"; -import updateAccount from "./methods/updateAccount"; -import trustAsset from "./methods/trustAsset"; // NEW -import makePayment from "./methods/makePayment"; // UPDATE -import copyAddress from "./methods/copyAddress"; -import copySecret from "./methods/copySecret"; -import signOut from "./methods/signOut"; -import setPrompt from "./methods/setPrompt"; - -import { Prompter } from "@prompt/prompt"; - -interface StellarAccount { - publicKey: string; - keystore: string; - state?: ServerApi.AccountRecord; -} - -interface Loading { - // UPDATE - fund?: boolean; - pay?: boolean; - trust?: boolean; // NEW - update?: boolean; -} - -@Component({ - tag: "stellar-wallet", - styleUrl: "wallet.scss", - shadow: true, -}) -export class Wallet { - @State() account: StellarAccount; - @State() prompter: Prompter = { show: false }; - @State() loading: Loading = {}; - @State() error: any = null; - - @Prop() server: Server; - - // Component events - componentWillLoad() {} - render() {} - - // Stellar methods - createAccount = createAccount; - updateAccount = updateAccount; - trustAsset = trustAsset; // NEW - makePayment = makePayment; // UPDATE - copyAddress = copyAddress; - copySecret = copySecret; - signOut = signOut; - - // Misc methods - setPrompt = setPrompt; -} - -Wallet.prototype.componentWillLoad = componentWillLoad; -Wallet.prototype.render = render; -``` - - - -Only thing worth seeing here besides the inclusion of the new `trustAsset` method is the addition of the `trust?: boolean,` in the `Loading` class. - -## Add Trustlines - -Alright so, finally we get to the `./methods/trustAsset.ts` file! - - - -```ts -import sjcl from "@tinyanvil/sjcl"; -import { - Keypair, - Account, - TransactionBuilder, - BASE_FEE, - Networks, - Operation, - Asset, -} from "stellar-sdk"; - -import { handleError } from "@services/error"; - -export default async function trustAsset( - e?: Event, - asset?: string, - issuer?: string, - pincode?: string, -) { - try { - if (e) e.preventDefault(); - - let instructions; - - if (asset && issuer) instructions = [asset, issuer]; - else { - instructions = await this.setPrompt("{Asset} {Issuer}"); - instructions = instructions.split(" "); - } - - pincode = pincode || (await this.setPrompt("Enter your keystore pincode")); - - if (!instructions || !pincode) return; - - const keypair = Keypair.fromSecret( - sjcl.decrypt(pincode, this.account.keystore), - ); - - this.error = null; - this.loading = { ...this.loading, trust: true }; - - await this.server - .accounts() - .accountId(keypair.publicKey()) - .call() - .then(({ sequence }) => { - const account = new Account(keypair.publicKey(), sequence); - const transaction = new TransactionBuilder(account, { - fee: BASE_FEE, - networkPassphrase: Networks.TESTNET, - }) - .addOperation( - Operation.changeTrust({ - asset: new Asset(instructions[0], instructions[1]), - }), - ) - .setTimeout(0) - .build(); - - transaction.sign(keypair); - return this.server.submitTransaction(transaction); - }) - .then((res) => console.log(res)) - .finally(() => { - this.loading = { ...this.loading, trust: false }; - this.updateAccount(); - }); - } catch (err) { - this.error = handleError(err); - } -} -``` - - - -This is similar to the `makePayment` method but there are a couple tiny tweaks worth noting: - - - -```ts -export default async function trustAsset( - e?: Event, - asset?: string, - issuer?: string, - pincode?: string -) { - try { - if (e) - e.preventDefault() - - let instructions - - if ( - asset - && issuer - ) instructions = [asset, issuer] - - else { - instructions = await this.setPrompt('{Asset} {Issuer}') - instructions = instructions.split(' ') - } - - pincode = pincode || await this.setPrompt('Enter your keystore pincode') -``` - - - -We’re allowing the inclusion of several arguments in this function, namely `asset`, `issuer`, and `pincode`. We won’t be making use of them here, but transparently creating trustlines from within other functions will prove useful later. - -If we have any of those variables set, we can “preload” our interface a bit, and even bypass user input altogether if a pincode is provided. Again, not something we’ll make use of quite yet, but once we look into depositing and withdrawing assets from an Anchor or accepting incoming payments for which we don’t yet have a trustline this functionality will prove useful. - -So there we have it! The ability to accept and pay with custom assets on Stellar! - -[1]: https://github.com/stellar/docs-wallet/tree/pay -[3]: https://github.com/stellar/docs-wallet/tree/trustline diff --git a/docs/building-apps/example-application-tutorial/first-deposit.mdx b/docs/building-apps/example-application-tutorial/first-deposit.mdx deleted file mode 100644 index 39878e530..000000000 --- a/docs/building-apps/example-application-tutorial/first-deposit.mdx +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: Fund the Account and make the First Deposit -sidebar_position: 65 ---- - -In this section, we will go over the new user account creation flow between non-custodial wallets and anchors with SEP-24 and/or SEP-6 implementations. Before we dive into the flow, it’s important to understand how Stellar accounts are created in the first place. - -The first step in creating a Stellar account is to generate a keypair. This keypair includes public and private keys. However, an account does not exist and does not warrant space on the ledger until it’s funded with the minimum balance of 1XLM by a [Create Account](../../fundamentals-and-concepts/list-of-operations.mdx#create-account) operation. This requirement was created to minimize unused accounts from bloating the ledger. For a more in-depth look at this topic, check out this [page](../../tutorials/create-account.mdx). - -## Who creates the new user accounts? - -When a new customer downloads the wallet application and goes through the deposit flow for the first time, their Stellar account can be created by either the user’s wallet application or the anchor facilitating the first deposit. This section describes the possible strategies and flows for you to consider. - -### Option 1: The anchor creates and funds the Stellar account - -For this option, the wallet needs to allow users to initiate their first deposit without having to add an asset/establish a trustline. The wallet then prompts the user to add the trustline once funds are received by the anchor. The flow looks like this: - -1. The wallet registers a new user and issues a keypair. -1. The wallet initiates the first deposit on behalf of the user without requiring the user to add the asset/create the trustline. -1. The anchor provides deposit instructions to the customer. -1. The user transfers money from a bank account to the anchor’s bank account. -1. Once the anchor receives the transfer, the anchor creates and funds the Stellar account for the customer. -1. The wallet detects that the account has been created and a trustline must be established. -1. The wallet prompts the user to add the asset/create the trustline. -1. Finally, the anchor sends the deposit funds to the user’s Stellar account. - -**Note**: An anchor should always maintain a healthy amount of XLM in its distribution account to support new account creations. If doing so becomes unsustainable, it’s recommended that the anchor collaborates with wallets to determine a strategy based on the number of account creation requests. The recommended amount is 2XLM per user account creation (1XLM to meet the minimum balance requirement, and 1XLM for establishing trustlines and covering transaction fees). - -![anchor creates account flow](/assets/first-deposit-anchor-flow.png) - -With the flow described above, the wallet and the anchor have to facilitate listening for and responding to the trustline status, which can create user experience frictions when waiting for the trustline to be established. To address this issue, Protocol 15 introduced [Claimable Balances](../../encyclopedia/claimable-balances.mdx), which enhance the flow by allowing users to start using the wallet without having to secure XLM wait to create the trustline after they made their first deposit. Both the wallet and the anchor have to implement Claimable Balance support in order to make this flow work. - -The flow with Claimable Balances looks like this: - -1. The wallet registers a new user, and generates a keypair. -1. The wallet initiates a deposit on behalf of a user. -1. The anchor provides deposit instructions to the wallet. -1. The user transfers money from a bank account to the anchor’s account. -1. The anchor creates and funds the user's Stellar account plus the amount required for trustlines and transaction fees. Again, we suggest 2 XLM to start. -1. The anchor creates a Claimable Balance. -1. The wallet detects the Claimable Balance for the account, claims the funds, and posts it in the wallet. - -![anchor creates account claimable balance flow](/assets/first-deposit-claimable-balance-flow.png) - -### Option 2: The wallet creates and funds the Stellar account upon user sign-up - -For this option, the wallet creates and funds the Stellar account upon every new user sign-up with the minimum requirement of 1XLM, plus the .5XLM reserve for establishing the first trustline, plus a bit more to cover transaction fees. For more information on minimum balances, check out the [Lumens section](../../fundamentals-and-concepts/lumens.mdx#minimum-balance). - -The flow looks like this: - -1. Upon a new user signup, the wallet issues a keypair, then creates and funds the user's Stellar account with 2XLM. -1. Then the wallet creates a trustline, and initiates the first deposit. -1. Once the deposit request is sent to the anchor, the anchor provides instructions for the deposit. -1. The customer transfer funds from a personal bank account to the anchor’s account. -1. The anchor receives the funds, then sends them to the user’s Stellar account. -1. The wallet detects that funds were sent and notifies the user. - -![wallet creates account flow](/assets/first-deposit-wallet-flow.png) - -**Note**: In the examples above, we suggest having the anchor or wallet cover minimum balance and trustline XLM requirements by depositing funds directly into a user's account. We made that suggestion for the sake of simplicity, but in all cases, the anchor or wallet could instead use [Sponsored Reserves](../../encyclopedia/sponsored-reserves.mdx) to ensure that when a user closes a trustline or merges their account, the reserve reverts to the sponsoring account rather than to the user's account. diff --git a/docs/building-apps/example-application-tutorial/manage-trust.mdx b/docs/building-apps/example-application-tutorial/manage-trust.mdx new file mode 100644 index 000000000..08ad3ad2e --- /dev/null +++ b/docs/building-apps/example-application-tutorial/manage-trust.mdx @@ -0,0 +1,22 @@ +--- +title: Manage Trust +sidebar_position: 30 +--- + +For an account to hold and trade assets other than XLM, it must establish a [trustline](../../fundamentals-and-concepts/stellar-data-structures/accounts#trustlines) with the issuing account of that particular asset. Each trustline increases the account’s [base reserve](../../fundamentals-and-concepts/stellar-data-structures/accounts#base-reserves-and-subentries) by 0.5 XLM, which means the account will have to hold more XLM in its minimum balance. In BasicPay, we’ve already funded the account on Testnet. When moving your application to Pubnet, you can either cover an account’s minimum balance using sponsored reserves, or the user will have to supply their own XLM. + +First, we’ll have the user create a trustline for an asset by navigating to the Assets page, selecting an asset, and clicking the “Add Asset” button. This triggers a modal form for them to confirm the transaction with their pincode. Once confirmed, a transaction containing the `changeTrust` operation is signed and submitted to the network, and a trustline is established with the issuing account for the asset. + +:::info + +Every transaction must contain a sequence number that is used to identify and verify the order of transactions with the account. A transaction’s sequence number must always increase by one. In BasicPay, fetching and incrementing the sequence number is handled automatically by the transaction builder. + +::: + +[ss3] + +The `changeTrust` operation can also be used to modify or remove trustlines. + +Trustlines hold the balances for all of their associated assets (except XLM, which are held at the account level), and you can display the user’s various balances in your application. + +[ss4] diff --git a/docs/building-apps/example-application-tutorial/overview.mdx b/docs/building-apps/example-application-tutorial/overview.mdx new file mode 100644 index 000000000..3697ee95e --- /dev/null +++ b/docs/building-apps/example-application-tutorial/overview.mdx @@ -0,0 +1,39 @@ +--- +title: Overview +sidebar_position: 10 +--- + +In this tutorial, we’ll walk through the steps needed to build a basic payment application on Stellar’s Testnet. After this tutorial, you should have a good understanding of the fundamental Stellar concepts and a solid base for iterative development. + +For this tutorial, we’ll walk through the steps as we build a sample application we’ve called [BasicPay](https://basicpay.pages.dev), which will be used to showcase various features. + +:::caution + +**Although BasicPay is a full-fledged application on Stellar’s Testnet, it has been built solely to showcase Stellar functionality for the educational purposes of this tutorial, not to be copied, pasted, and used on Mainnet.** + +::: + +## Project setup + +### Project requirements + +To build a basic Stellar application, you’ll need: + +- Application framework (for BasicPay, we use SvelteKit opting for JavaScript with JSDoc typing, and we used [svelte-add](https://github.com/svelte-add/svelte-add) to get our project started) +- Frontend framework (for BasicPay, we’re using Daisy UI to simplify the use of Tailwind CSS) +- A way to interact with the Stellar network (for BasicPay, we use the [js-stellar-sdk](https://github.com/stellar/js-stellar-sdk), but you could use traditional fetch requests) +- A way to interact with the user’s keypair (for BasicPay, we are using the [js-stellar-wallets SDK](https://github.com/stellar/js-stellar-wallets), but you can opt to use an existing wallet) + +While we are using the above components to construct our application, we have done our best to build it in such a way that dependency on any one of these things is minimized. Ideally, you should be able to use the JavaScript code we’ve written and plug it into any other framework you’d like with minimal effort. + +We’ve made the following choices during the development of this application that you may need to consider as you follow this project: + +- We’ve designed this app with a desktop in mind. +- We’re using a dark mode theme. No light mode is available, so deal with it. +- This is written as a client-side application. No server-side actions actually take place. +- We’re deploying this as a static site with Cloudflare pages. + +### Dev helpers + +- [Friendbot](https://friendbot.stellar.org/): a bot that funds accounts with 10,000 fake XLM on Stellar’s Testnet +- [Testnet toml file](https://testanchor.stellar.org/.well-known/stellar.toml) diff --git a/docs/building-apps/example-application-tutorial/path-payment.mdx b/docs/building-apps/example-application-tutorial/path-payment.mdx new file mode 100644 index 000000000..d1c3d28bf --- /dev/null +++ b/docs/building-apps/example-application-tutorial/path-payment.mdx @@ -0,0 +1,18 @@ +--- +title: Path Payment +sidebar_position: 50 +--- + +A path payment is where the asset sent can be different from the asset received. There are two possible path payment operations: 1) `path_payment_strict_send`, which allows the user to specify the amount of the asset to send, and 2) `path_payment_strict_receive`, which allows the user to specify the amount of the asset received. + +With BasicPay, the user will input the public key of the destination address, specify the asset sent and the asset received, and the amount of asset either sent or received. + +[ss] + +The user will then sign and submit the transaction to the network. + +:::tip + +BasicPay also contains a swap feature, which allows the user to send themselves an asset in exchange for another asset. For example, receive USDC in exchange for your own XLM. + +::: diff --git a/docs/building-apps/example-application-tutorial/payment.mdx b/docs/building-apps/example-application-tutorial/payment.mdx new file mode 100644 index 000000000..e63b54764 --- /dev/null +++ b/docs/building-apps/example-application-tutorial/payment.mdx @@ -0,0 +1,22 @@ +--- +title: Payment +sidebar_position: 40 +--- + +A payment operation sends an amount in a specific asset (XLM or non-XLM) to a destination account. With a basic payment operation, the asset sent is the same as the asset received. BasicPay also allows for path payments (where the asset sent is different than the asset received), which we’ll talk about in the next section. + +In our BasicPay application, we’ll add a “Send Payment” button that allows the user to input the public key of a destination address with a specified asset they’d like to send along with the amount of the asset. The application will first verify that the destination account exists and is properly funded with XLM. + +:::info + +An asset is displayed as an asset code and issuer address. Learn more in our [Assets section](https://developers.stellar.org/docs/fundamentals-and-concepts/stellar-data-structures/assets). + +::: + +All Stellar transactions require a small fee to make it to the ledger. Read more in our [Fees, Surge Pricing, and Fee Strategies section](../../encyclopedia/fees-surge-pricing-fee-strategies). + +In BasicPay, we’ve set it up so that the user always pays a static fee of 100,000 [stroops](../../fundamentals-and-concepts/stellar-data-structures/assets#amount-precision) (one stroop equals 0.0000001 XLM) per operation. Alternatively, you can add a feature to your application that allows the user to set their own fee. + +[ss5] + +Finally, the user will click the “Send” button, which triggers a modal with the transaction preview where the user will input their pincode and click “Confirm” which signs and submits the transaction to the ledger. diff --git a/docs/building-apps/example-application-tutorial/project-setup.mdx b/docs/building-apps/example-application-tutorial/project-setup.mdx deleted file mode 100644 index fb7181d44..000000000 --- a/docs/building-apps/example-application-tutorial/project-setup.mdx +++ /dev/null @@ -1,495 +0,0 @@ ---- -title: Project Setup -sidebar_position: 20 ---- - -import { CodeExample } from "@site/src/components/CodeExample"; - -Throughout this tutorial we'll be making use of a little toolchain called StencilJs. It takes the best of modern frontend frameworks and pares everything back to small, blazing fast, 100% standards-based Web Components that run in every browser. Don’t worry if you've never heard of it: it's just TS (JS), SCSS (CSS) and JSX (HTML). You should be able to follow along just fine if you've ever built something with modern web dev tools. - -We chose Stencil so you can learn by doing: it’s an easy way to create a web-based application, which means you can see the ins and outs of building a Stellar wallet start to finish. Stellar also has a [suite of SDKs][1] in various programming languages, so if Javascript isn’t your thing, you can follow along, and recreate the steps below using one of them. - -To start the setup, open your terminal and initialize a new project. - - - -```bash -npm init stencil -``` - - - -After running `init` you will be provided with a prompt to choose the type of project to start. While Stencil can be used to create entire apps, we’ll choose the component as we’ll just be dealing with modular components rather than building an entire application - - - -```bash -? Pick a starter › - Use arrow-keys. Return to submit. - - ionic-pwa Everything you need to build fast, production ready PWAs - app Minimal starter for building a Stencil app or website -❯ component Collection of web components that can be used anywhere -``` - - - -We’ll walk through the prompt, `cd` into the project and run `npm i ; npm start` - - - -```bash -✔ Pick a starter › component -✔ Project name › stellar-wallet - -✔ All setup in 9 ms - - $ npm start - Starts the development server. - - $ npm run build - Builds your components/app in production mode. - - $ npm test - Starts the test runner. - - We suggest that you begin by typing: - - $ cd stellar-wallet - $ npm i - $ npm start - - Further reading: - - - https://github.com/ionic-team/stencil-component-starter - - Happy coding! -``` - - - -Now that our project is initialized, let’s take a look at the directory structure and familiarize ourselves with where things are and what roles they play. - -We’re mostly interested in the `src/` directory. The `dist/` and `www/` directories are outputs for compiled code. In the `src/components/` directory you’ll see a `my-component/` folder. We’re about to generate our own component, so go ahead and delete that folder. You can also nuke the `utils/` directory as we won’t be covering tests in this tutorial. Now run: - - - -```bash -$ npm run generate -``` - - - -This will initialize a component generation script. Enter a name of `stellar-wallet`. Disable Spec Test and E2E Test as we’re not interested in those Stencil features today. Press Return and your component will generate and wire up. - - - -```bash -% npm run generate - -> stellar-wallet generate -> stencil generate - -✔ Component tag name (dash-case): … stellar-wallet -✔ Which additional files do you want to generate? › Stylesheet - -$ stencil generate stellar-wallet - -The following files have been generated: - - src/components/wallet/wallet.tsx - - src/components/wallet/wallet.css -``` - - - -Amazing! Just a few more setup bits and we can get coding. I don’t know about you but I prefer to style in SCSS rather than CSS so let’s get some modern CSS dev tools setup. - - - -```bash -npm i -D @stencil/postcss@2 @stencil/sass@1 autoprefixer@9 @types/autoprefixer@9 rollup-plugin-node-polyfills -``` - - - -Once those packages have successfully installed, hop over to the `stencil.config.ts` file at the root of the project and modify it to this: - - - -```ts -import { Config } from "@stencil/core"; -import { sass } from "@stencil/sass"; -import { postcss } from "@stencil/postcss"; -import autoprefixer from "autoprefixer"; -import nodePolyfills from "rollup-plugin-node-polyfills"; - -export const config: Config = { - namespace: "stellar-wallet", - outputTargets: [ - { - type: "dist", - esmLoaderPath: "../loader", - }, - { - type: "docs-readme", - }, - { - type: "www", - serviceWorker: null, // disable service workers - }, - ], - globalStyle: "src/global/style.scss", - commonjs: { - namedExports: { - "stellar-sdk": [ - "StrKey", - "xdr", - "Transaction", - "Keypair", - "Networks", - "Account", - "TransactionBuilder", - "BASE_FEE", - "Operation", - "Asset", - "Memo", - "MemoHash", - ], - "@stellar/wallet-sdk": ["KeyManager", "KeyManagerPlugins", "KeyType"], - }, - }, - plugins: [ - nodePolyfills(), - sass(), - postcss({ - plugins: [autoprefixer()], - }), - ], - nodeResolve: { - browser: true, - preferBuiltins: true, - }, -}; -``` - - - -With that file saved, pop over to the `src/components/wallet/` and rename the `wallet.css` to `wallet.scss`. While we’re here let’s go ahead and modify this new style file with some basic styling to put our project in a pretty place. - - - -```scss -@import "../../global/style.scss"; - -:host { - display: block; - font-family: $font-family; - font-size: 15px; - - p { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - display: block; - } - button { - margin-bottom: 10px; - } - - .account-key { - display: flex; - align-items: center; - width: 100%; - margin-bottom: 10px; - - .small { - margin: 0 0 0 10px; - flex-shrink: 0; - } - } - .account-state, - .error { - overflow: scroll; - padding: 10px; - font-size: 12px; - line-height: 1.2; - font-family: $font-mono; - margin-bottom: 10px; - width: 100%; - } - .account-state { - background-color: whitesmoke; - } - .error { - background-color: orangered; - color: white; - } - - stellar-loader { - sidebar_position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - } -} -``` - - - -Before we update our `wallet.tsx` with this new stylesheet, note that we’re also importing a global stylesheet. Go ahead and create that file at the root of the `src/` directory. So `src/global/style.scss`. - - - -```scss -$font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, - Apple Color Emoji, Segoe UI Emoji; -$font-mono: monospace; -html, -body, -div, -span, -applet, -object, -iframe, -h1, -h2, -h3, -h4, -h5, -h6, -p, -blockquote, -pre, -a, -abbr, -acronym, -address, -big, -cite, -code, -del, -dfn, -em, -img, -ins, -kbd, -q, -s, -samp, -small, -strike, -strong, -sub, -sup, -tt, -var, -b, -u, -i, -center, -dl, -dt, -dd, -ol, -ul, -li, -fieldset, -form, -label, -legend, -table, -caption, -tbody, -tfoot, -thead, -tr, -th, -td, -article, -aside, -canvas, -details, -embed, -figure, -figcaption, -footer, -header, -hgroup, -menu, -nav, -output, -ruby, -section, -summary, -time, -mark, -audio, -video { - margin: 0; - padding: 0; - bsidebar_position: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} -/* HTML5 display-role reset for older browsers */ -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -menu, -nav, -section { - display: block; -} -body { - line-height: 1; -} -ol, -ul { - list-style: none; -} -blockquote, -q { - quotes: none; -} -blockquote:before, -blockquote:after, -q:before, -q:after { - content: ""; - content: none; -} -table { - border-collapse: collapse; - border-spacing: 0; -} - -* { - box-sizing: border-box; -} -input, -button, -select, -textarea { - font-family: $font-family; - font-size: 15px; - outline: none; - appearance: none; - border-radius: 0; -} -input, -select, -button { - height: 30px; -} -button { - bsidebar_position: none; - appearance: none; - sidebar_position: relative; - background-color: blue; - color: white; - margin: 0; - display: flex; - align-items: center; - align-content: center; - justify-content: center; - justify-items: center; - padding: 0 10px; - cursor: pointer; - - &.loading { - color: transparent; - pointer-events: none; - } - &.small { - font-size: 12px; - height: 20px; - } -} -``` - - - -Save those style files and update the `wallet.tsx` to point to our new styles like so: - - - -```tsx -import { Component, h } from "@stencil/core"; -import * as StellarSdk from "stellar-sdk"; - -@Component({ - tag: "stellar-wallet", - styleUrl: "wallet.scss", - shadow: true, -}) -export class Wallet { - render() { - return [ -

- {!!StellarSdk - ? "The StellarSdk is ready to rock 🤘" - : "Uh oh, the StellarSdk is missing 😱"} -

, - ]; - } -} -``` - -
- -You’ll notice we also include a few extra setup lines to get the StellarSdk loaded in and ready to use. Let’s ensure all those dependencies are loaded and ready to rock. - - - -```bash -npm i -D stellar-sdk js-xdr -``` - - - -The last mod: point the `src/index.html` file to use this brand new component. Modify that file to match this. - - - -```html - - - - - - Stellar Wallet - - - - - - - - -``` - - - -You should be all set up now. Restart the server and let’s get coding. - - - -```bash -# Stop any current server and rerun -$ npm start -``` - - - -[View the full setup code on GitHub][2] - -[1]: ../../tools-and-sdks.mdx#sdk-library -[2]: https://github.com/stellar/docs-wallet/tree/setup diff --git a/docs/building-apps/example-application-tutorial/querying-data.mdx b/docs/building-apps/example-application-tutorial/querying-data.mdx new file mode 100644 index 000000000..021db5855 --- /dev/null +++ b/docs/building-apps/example-application-tutorial/querying-data.mdx @@ -0,0 +1,13 @@ +--- +title: Querying Data +sidebar_position: 70 +--- + +Throughout the application’s functionality, it will be querying data from Horizon, Stellar’s API. Information such as account balances, transaction history, sequence numbers for transactions, asset availability, and more are stored in Horizon’s database. + +Functions to query: + +- loadAccount: gives the account sequence number, asset balances, trustlines, and an account object that can be used in a transaction +- fetchAccount: gives all the same information as loadAccount, but doesn’t have the account object +- getAccountBalances +- submitTransaction diff --git a/docs/building-apps/example-application-tutorial/setup-custodial-account.mdx b/docs/building-apps/example-application-tutorial/setup-custodial-account.mdx deleted file mode 100644 index b5561b28a..000000000 --- a/docs/building-apps/example-application-tutorial/setup-custodial-account.mdx +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: Set Up a Custodial Account -sidebar_position: 45 ---- - -import { CodeExample } from "@site/src/components/CodeExample"; -import { Alert } from "@site/src/components/Alert"; - -This guide describes how to add assets from the Stellar network to your custodial service. First, we walk through adding Stellar's native asset: lumens (XLM). Following that, we describe how to add other assets. This example uses Node.js and the [JS Stellar SDK](https://github.com/stellar/js-stellar-sdk), but it should be easy to adapt to other languages. - -## Account Setup - -### Pooled account - -Most custodial services, including cryptocurrency exchanges, choose to use a single pooled Stellar account to handle transactions on behalf of their users instead of creating a new Stellar account for each customer. Generally, they keep track of their customers in a separate, internal database and use the memo field of a Stellar transaction to map an incoming payment to the corresponding internal customer. - -The benefits of using a pooled account are _lower costs_ – no base reserves are needed for each account – and _lower key complexity_ – you only need to manage one account keypair. However, with a single pooled account, it is now your responsibility to manage all individual customer balances and payments. You can no longer rely on the Stellar ledger to accumulate value, handle errors and atomicity, or manage transactions on an account-by-account basis. - -## Code Framework - -You can use this code framework to integrate Stellar into your custodial service. For this guide, we use abstract placeholder functions for reading/writing to your internal customer database, since each organization will architect their infrastructure differently. Here are the functions we'll assume exist (along with their expected behavior): - - - -```js -// We assume that these to correspond to your custodial account details. -CUSTODIAL_KEY = StellarSdk.Keypair.fromSecret("..."); -custodialAcc = await server.loadAccount(CUSTODIAL_KEY.publicKey()); - -/** - * Credits a customer (`to`) with `amount` of a particular `asset`. - * - * @param {string} from The public key of the Stellar account that - * submitted this deposit. - * @param {any} to A string representing the customer that's part of - * this pooled account. This could be a key, a database index, an object, - * or some other abstraction. The main point is that this is *NOT* a - * Stellar account. This value either directly comes from or somehow - * resolves from the transaction memo field on the payment. - * @param {Asset} asset The asset deposited into the customer's account. - * @param {string} amount The quantity (as a string, conforming to the way - * payments are submitted on the Stellar network) of `asset` being - * credited. - **/ -function depositIntoPool(from, to, asset, amount) {} - -/** - * Withdraws an `amount` of `asset` from a customer (`from`). - * - * For simplicity, we assume that this function always works. However, you - * should obviously be managing balances appropriately and ensuring that - * a particular customer can in fact fulfill a requested withdrawal. - * - * Note that this should probably be executed *after* the requisite transaction - * (see `createPayment()`) succeeds to ensure accounts aren't debited - * unnecessarily. - * - * @param {any} from As in `depositIntoPool()`, this is some - * representation of a customer that's part of a pooled account but not - * on the Stellar network. - * @param {Asset} asset The asset being debited from the customer. - * @param {string} amount The quantity of `asset` to withdraw. - **/ -function withdrawFromPool(from, asset, amount) {} - -/** - * Creates a PaymentOp corresponding to a withdrawal. - * - * This is just a convenience method for submitting payments on behalf of - * customers in a transaction. You may want to just do one operation per - * transaction (for example to include the source customer's ID in the memo), - * or you can batch many operations together; it's up to you. - * - * @param {string} to The Stellar account address of the recipient - * @param {Asset} asset The asset to debit from the source customer - * @param {string} amount The amount of `asset` to debit - * - * @return {xdr.paymentOp} - */ -function createPayment(to, asset, amount) { - return sdk.Operation.payment({ - source: custodialAcc.accountId(), - destination: to, - asset: asset, - amount: amount, - }); -} -``` - - - -## Integration points for listing XLM - - - -In the following code samples, proper error checking is omitted for brevity. However, you should _always_ validate your results, as there are many ways that requests can fail. You should refer to the guide on [Error Handling](../../encyclopedia/error-handling.mdx) for tips on error management strategies. - - - -### Setting the memo required flag on your account - -Before we get into the main integration points for adding XLM support to your product or service, make sure to configure your pooled account to require memos. This step is necessary to prevent users from forgetting to attach a memo, which can increase customer support requests and lead to a less desirable user experience for new customers. [This article](https://www.stellar.org/developers-blog/fixing-memo-less-payments) explains how to set that up. - -### Listening for incoming payments from the Stellar network - -First, you need to listen for payments to the pooled account and credit any user that receives XLM there. For every payment received by the pooled account: - -- check the memo field to determine which user should receive the payment, and -- credit the user’s account with the amount of XLM they received. - -This is the role of `depositIntoPool`, described above. You pass this function as the `onmessage` option when you [stream payments](https://developers.stellar.org/docs/tutorials/follow-received-payments/): - - - -```js -const stream = server - .payments() - .forAccount(custodialAcc) - .join("transactions") - .cursor("now") - .stream({ - onmessage: (payment) => { - const from = payment.source_account; - const customerId = payment.transaction.memo; - const amount = payment.amount; - - let asset = sdk.Asset.native(); - if (payment.asset_issuer) { - asset = new sdk.Asset(payment.asset_code, payment.asset_issuer); - } - - depositIntoPool(from, customerId, asset, amount); - }, - }); -``` - - - -When someone **outside** of your customer base wants to send XLM to one of your customers, instruct them to make an XLM payment to your pooled account address with the customer ID in the memo field of the transaction. Assuming you have set the `memo_required` configuration on your account (see [above](#setting-the-memo-required-flag-on-your-account)), [well-behaved](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0029.md) wallets should enforce it and prevent users from forgetting to attach memos to incoming payments. To be on the safe side, however, you should make it incredibly clear to senders that their payment will end up in limbo if they fail to attach a valid one. You can learn more about the transaction memo field [here](https://developers.stellar.org/docs/encyclopedia/transactions/#memo). - -When someone **inside** of your customer base wants to send XLM to _another_ one of your customers, you have two choices: you can send a memo'd payment exactly as above — this lets you maintain an audit trail, ensures the balance exists in the custodial account, etc. — or you can do the exchange "off-chain", i.e. by exclusively adjusting balances within your database. - -### Submitting outgoing payments to the Stellar network - -When one of your customers wants to make an outgoing XLM payment, you must generate a Stellar transaction to send XLM. See [building transactions](https://stellar.github.io/js-stellar-sdk/TransactionBuilder.html) or the [payments tutorial](https://developers.stellar.org/docs/tutorials/send-and-receive-payments/#send-a-payment) for more information. - -The aforementioned `createPayment` function will prepare the corresponding operation whenever a withdrawal is requested (while `withdrawFromPool` should manage your balance sheet). You can use these to queue up transactions (for periodic or batched submission) or submit them immediately. It's up to you how to architect this portion; we adopt the (simpler) latter approach here: - - - -```js -/** - * Submit a payment requested from an internal customer. - * - * Here, `customerId` is your internal representation of a customer in the - * pool, passed in here as the outgoing transaction's memo purely for - * clarity. The required `destination` parameter, however, is the actual - * Stellar address for the payment. - */ -function onPooledPayment(customerId, destination, amount, asset) { - let tx = new sdk.TransactionBuilder(custodialAcc, { - fee: 100, - networkPassphrase: sdk.Networks.TESTNET, - memo: customerId, - }) - .addOperation(createPayment(destination, amount, asset)) - .setTimeout(30) - .build(); - - tx.sign(CUSTODIAL_KEY); - withdrawFromPool(customerId, asset, amount); - return server.submitTransaction(tx).catch((err) => { - return reverseWithdrawal(customerId, asset, amount, error); - }); -} -``` - - - -This code would be called whenever one of your customers submitted a payment through your platform. Note that the balances are adjusted _before_ the transaction is confirmed, so you should take care to adjust them back if there's a failure (e.g. implement `reverseWithdrawal` for your architecture). - -## Listing Other Stellar Assets - -All of the code above is asset-agnostic, so accepting other (non-native/lumen) assets into your custodial account can be achieved after fulfilling a few prerequisites. - -### Account Setup - -First, you must [open a trustline](https://developers.stellar.org/docs/start/list-of-operations/#change-trust) with the issuing account of the asset you’d like to list – without this, you cannot begin accepting the asset. The [Issue an Asset](https://developers.stellar.org/docs/issuing-assets/how-to-issue-an-asset/) tutorial covers the code for this one-time process. - -Next, if the asset issuer has the `authorization_required` flag on their account set, you will need to wait for them to authorize the trustline before you can begin accepting the asset. Read more about trustline authorization [here](https://developers.stellar.org/docs/issuing-assets/control-asset-access/). - - - -_Note_: Users cannot send a non-native asset to your pooled account (nor receive one from your customers) unless they have opted into that asset by opening a trustline to its issuer. - - - -### Managing Supply - -Custodians usually hold a float of the assets they list on their platform. Unlike Stellar’s native asset (XLM), which can only be sourced from the Stellar Decentralized Exchange (SDEX), non-native assets can also be sourced directly from the asset’s issuer. For example, custodians can establish a [Circle Account](https://www.circle.com/blog/circle-account-and-api-services-now-support-stellar-usdc) to source Stellar USDC. - -Regardless of the strategies used to purchase the asset, you’ll need to adapt your balance sheet management (e.g. the internals of `depositIntoPool` and `withdrawFromPool`, [above](#code-framework)) to track things per-asset for each customer. Since this is backend-specific, we won’t provide example code here. - -For more information about non-native assets, check out the [asset issuing guide](../../issuing-assets/anatomy-of-an-asset.mdx). diff --git a/docs/building-apps/example-application-tutorial/xlm-payments.mdx b/docs/building-apps/example-application-tutorial/xlm-payments.mdx deleted file mode 100644 index 694b4fd70..000000000 --- a/docs/building-apps/example-application-tutorial/xlm-payments.mdx +++ /dev/null @@ -1,736 +0,0 @@ ---- -title: Make XLM Payments -sidebar_position: 50 ---- - -import { CodeExample } from "@site/src/components/CodeExample"; -import { Alert } from "@site/src/components/Alert"; - - - -In this tutorial we’re going to modify our [base wallet app](./basic-wallet.mdx) to include functionality to send XLM to other Stellar accounts. - - - -[View keystore boilerplate code on GitHub][1] - -In the [Build a Basic Wallet section](./basic-wallet.mdx), we did the hard work of wiring up a secure client and rock-solid key creation and storage structure with a clear plan for key use and management. Now that we have a method for creating an account — and for storing that account's secrets so they're safe and easy to use — we're ready to start making payments. We'll start with XLM payments since they're a little simpler; in the [next section](./custom-assets.mdx), we'll look at how to support payments for other assets. - -There isn’t too much that's new or complicated here: we'll be building on what we already have. Again, most of the work will be in `src/components/wallet/`; however, before we dive into that file let’s clean up our project just a touch and add some helpful polish. Namely a loader component. - -## Add Loader Component - -Hopefully by now you’re familiar with how to generate new Stencil components. - - - -```bash -npm run generate -``` - - - -We'll call the component `stellar-loader`, and deselect both test files leaving only the styling. Once you've done that, open `src/components/loader/` and rename the `.css` file to `.scss`. Then replace the `loader.tsx` contents with this: - - - -```tsx -import { BaseN } from "js-combinatorics"; -import { Component, h, State, Prop } from "@stencil/core"; -import { isEqual as loIsEqual, sample as loSample } from "lodash-es"; - -@Component({ - tag: "stellar-loader", - styleUrl: "loader.scss", - shadow: true, -}) -export class Loader { - @State() chances: any = []; - @State() chance: any = null; - @Prop() interval: any; - - componentWillLoad() { - return new Promise((resolve) => { - if (!this.chances.length) this.generateChances(9); - - if (!this.interval) - this.interval = setInterval(() => this.getChance(), 100); - - resolve(); - }); - } - - generateChances(int: number) { - const baseN = new BaseN([0, 1], int); - - this.chances = baseN.toArray(); - this.getChance(); - } - getChance() { - const chance = loSample(this.chances); - - if (loIsEqual(chance, this.chance)) this.getChance(); - else this.chance = chance; - } - - render() { - return ( -
- {this.chance.map((int, i) => ( -
- ))} -
- ); - } -} -``` - -
- -Don’t forget to install new packages! - - - -```bash -npm i -D js-combinatorics -``` - - - -It’s a fancy wackadoodle little component which at the end of the day just produces a little loader for use in our action buttons. - -## Import Methods - -We’re now ready to tackle the `src/components/wallet/wallet.ts` file. - - - -```ts -import { Component, State, Prop } from "@stencil/core"; -import { Server, ServerApi } from "stellar-sdk"; - -import componentWillLoad from "./events/componentWillLoad"; -import render from "./events/render"; - -import createAccount from "./methods/createAccount"; -import updateAccount from "./methods/updateAccount"; -import makePayment from "./methods/makePayment"; -import copyAddress from "./methods/copyAddress"; -import copySecret from "./methods/copySecret"; -import signOut from "./methods/signOut"; -import setPrompt from "./methods/setPrompt"; - -import { Prompter } from "@prompt/prompt"; - -interface StellarAccount { - publicKey: string; - keystore: string; - state?: ServerApi.AccountRecord; -} - -interface Loading { - fund?: boolean; - pay?: boolean; - update?: boolean; -} - -@Component({ - tag: "stellar-wallet", - styleUrl: "wallet.scss", - shadow: true, -}) -export class Wallet { - @State() account: StellarAccount; - @State() prompter: Prompter = { show: false }; - @State() loading: Loading = {}; - @State() error: any = null; - - @Prop() server: Server; - - // Component events - componentWillLoad() {} - render() {} - - // Stellar methods - createAccount = createAccount; - updateAccount = updateAccount; - makePayment = makePayment; - copyAddress = copyAddress; - copySecret = copySecret; - signOut = signOut; - - // Misc methods - setPrompt = setPrompt; -} - -Wallet.prototype.componentWillLoad = componentWillLoad; -Wallet.prototype.render = render; -``` - - - -If you’ve followed other tutorials in this series much of this may be review, but we’ll just walk along this file and see exactly what’s going on. - - - -```ts -import { Component, State, Prop } from "@stencil/core"; -import { Server, ServerApi } from "stellar-sdk"; - -import componentWillLoad from "./events/componentWillLoad"; // UPDATE -import render from "./events/render"; // UPDATE - -import createAccount from "./methods/createAccount"; // UPDATE -import updateAccount from "./methods/updateAccount"; // NEW -import makePayment from "./methods/makePayment"; // NEW -import copyAddress from "./methods/copyAddress"; -import copySecret from "./methods/copySecret"; -import signOut from "./methods/signOut"; -import setPrompt from "./methods/setPrompt"; - -import { Prompter } from "@prompt/prompt"; -``` - - - -Imports galore! Nothing really noteworthy here other than you’ll notice we’re importing `./methods/updateAccount` and `./methods/makePayment` methods which we’ll be creating soon. There are a number of updates in the other methods from previous tutorials, and we’ll walk through all of those in a moment as well. - - - -```ts -interface StellarAccount { - // UPDATE - publicKey: string; - keystore: string; - state?: ServerApi.AccountRecord; -} - -interface Loading { - // NEW - fund?: boolean; - pay?: boolean; - update?: boolean; -} -``` - - - -Here we’re setting up two TypeScript classes: one for our account and the other for our loading states. - - - -```ts -@Component({ - tag: 'stellar-wallet', - styleUrl: 'wallet.scss', - shadow: true -}) -export class Wallet { - @State() account: StellarAccount - @State() prompter: Prompter = {show: false} - @State() loading: Loading = {} // NEW - @State() error: any = null - - @Prop() server: Server // NEW - - ... -} -``` - - - -Here we set up our `@State`’s, those dynamic properties with values that will change and alter the DOM of the component, and our `@Prop`, which in this case will hold a static reference to our Stellar server instance. - -## Update Component Events - -Next let’s update our two component events `./events/componentWillLoad.ts` and `./events/render.tsx`: - - - -```ts -import { Server } from "stellar-sdk"; -import { handleError } from "@services/error"; -import { get } from "@services/storage"; - -export default async function componentWillLoad() { - try { - let keystore = await get("keyStore"); - - this.error = null; - this.server = new Server("https://horizon-testnet.stellar.org"); - - if (keystore) { - keystore = atob(keystore); - - const { publicKey } = JSON.parse(atob(JSON.parse(keystore).adata)); - - this.account = { - publicKey, - keystore, - }; - - this.updateAccount(); - } - } catch (err) { - this.error = handleError(err); - } -} -``` - - - -In Stencil’s `componentWillLoad` method, we set up default values for the States and Props we initialized earlier. Most notably, we’re setting our server and account. You’ll notice we’re using the public `horizon-testnet` for now — we're just learning, and not ready to send live XLM — but in production you’d want to change this to the public `horizon` endpoint or, if you're running your own Horizon, to one of your own Horizon API endpoints. - -For the account we’re simply checking to see if a `keyStore` value has been stored, and if so we’re grabbing the public key and keystore from it and adding those to the account `@State`. The `state` value, which is optional, is not set here as we’ll need to run the method `updateAccount()` to find if the account exists, and if so what the state of that account looks like. We’ll get to that method shortly. For now let’s update our `render.tsx` method: - - - -```tsx -import { h } from "@stencil/core"; -import { has as loHas } from "lodash-es"; - -export default function render() { - return [ - , - - this.account ? ( - [ - , - - , - ] - ) : ( - - ), - - this.error ? ( -
{JSON.stringify(this.error, null, 2)}
- ) : null, - - loHas(this.account, "state") ? ( - - ) : null, - - this.account - ? [ - , - , - ] - : null, - ]; -} -``` - -
- -Yikers amirite!? Don’t worry though: it’s actually quite simple if you’ve spent any time with HTML in JS before. What we're looking at are a few ternary operators toggling the UI between different states based on the account status. Basically just a bunch of buttons wired up to their subsequent actions. Turns out creating those buttons is next on our to-do list! - -## Create Buttons - -`updateAccount` and `makePayment` are new; `createAccount` will just need a few tweaks. Let’s start with that one. - - - -```ts -import sjcl from "@tinyanvil/sjcl"; -import axios from "axios"; -import { Keypair } from "stellar-sdk"; - -import { handleError } from "@services/error"; -import { set } from "@services/storage"; - -export default async function createAccount(e: Event) { - try { - e.preventDefault(); - - const pincode_1 = await this.setPrompt("Enter a keystore pincode"); - const pincode_2 = await this.setPrompt("Enter keystore pincode again"); - - if (!pincode_1 || !pincode_2 || pincode_1 !== pincode_2) - throw "Invalid pincode"; - - this.error = null; - this.loading = { ...this.loading, fund: true }; - - const keypair = Keypair.random(); - - await axios( - `https://friendbot.stellar.org?addr=${keypair.publicKey()}`, - ).finally(() => (this.loading = { ...this.loading, fund: false })); - - this.account = { - publicKey: keypair.publicKey(), - keystore: sjcl.encrypt(pincode_1, keypair.secret(), { - adata: JSON.stringify({ - publicKey: keypair.publicKey(), - }), - }), - }; - - await set("keyStore", btoa(this.account.keystore)); - - this.updateAccount(); - } catch (err) { - this.error = handleError(err); - } -} -``` - - - -## Fund Account Using Friendbot - -The only new thing we’re adding here — other than a loading state and an initial `this.updateAccount()` call at the end — is the call to [friendbot.stellar.org][2], which is a testnet tool that we can use to automatically fund our new testnet account with 10,000 XLM. Nice little shortcut to kickstart our development. - - - -```ts -await axios( - `https://friendbot.stellar.org?addr=${keypair.publicKey()}`, -).finally(() => (this.loading = { ...this.loading, fund: false })); -``` - - - -In production, you would have to find an actual source for funding the account. Some wallets fund users' accounts for them; some require the user to supply the funds. - -So that’s the updated `./methods/createAccount.ts` file. - -## Update Account Method - -Now let’s create two new files for updating the account and making XLM payments. - - - -```bash -touch src/components/wallet/methods/{updateAccount,makePayment}.ts -``` - - - -Let’s start with the simpler one, `./methods/updateAccount.ts` - - - -```ts -import { omit as loOmit, map as loMap } from "lodash-es"; - -import { handleError } from "@services/error"; - -export default async function updateAccount(e?: Event) { - try { - if (e) e.preventDefault(); - - this.error = null; - this.loading = { ...this.loading, update: true }; - - await this.server - .accounts() - .accountId(this.account.publicKey) - .call() - .then((account) => { - account.balances = loMap(account.balances, (balance) => - loOmit(balance, [ - "limit", - "buying_liabilities", - "selling_liabilities", - "is_authorized", - "last_modified_ledger", - balance.asset_type !== "native" ? "asset_type" : null, - ]), - ); - - this.account = { - ...this.account, - state: loOmit(account, [ - "id", - "_links", - "sequence", - "subentry_count", - "last_modified_ledger", - "flags", - "thresholds", - "account_id", - "signers", - "paging_token", - "data_attr", - ]), - }; - }) - .finally(() => (this.loading = { ...this.loading, update: false })); - } catch (err) { - this.error = handleError(err); - } -} -``` - - - -All we’re doing here is looking up the state of the Stellar account on the ledger and saving it to the `this.account.state`. You’ll also notice we’re omitting several fields from the account and balances for easier readability. You may choose to save these and selectively display the values you care about, but in our example we’re just displaying the raw JSON, so cleaning things up a little is the right move. - -`this.account = {...this.account, state: loOmit(account, ['id', ...])}` may feel odd, but it’s just the Stencil way of updating a state’s object key to trigger a re-render of the DOM. You’ll notice `this.loading` follows the same pattern. We’ll make use of this data further down in the `render` method, but for now just know this is how we would grab ahold of the account to get the latest state. - -## Make Payment Method - -Next let’s break down the main subject method for this tutorial, `./methods/makePayment.ts`: - - - -```ts -import sjcl from "@tinyanvil/sjcl"; -import { - Keypair, - Account, - TransactionBuilder, - BASE_FEE, - Networks, - Operation, - Asset, -} from "stellar-sdk"; -import { has as loHas } from "lodash-es"; - -import { handleError } from "@services/error"; - -export default async function makePayment(e: Event) { - try { - e.preventDefault(); - - let instructions = await this.setPrompt("{Amount} {Destination}"); - instructions = instructions.split(" "); - - const pincode = await this.setPrompt("Enter your keystore pincode"); - - if (!instructions || !pincode) return; - - const keypair = Keypair.fromSecret( - sjcl.decrypt(pincode, this.account.keystore), - ); - - this.error = null; - this.loading = { ...this.loading, pay: true }; - - await this.server - .accounts() - .accountId(keypair.publicKey()) - .call() - .then(({ sequence }) => { - const account = new Account(keypair.publicKey(), sequence); - const transaction = new TransactionBuilder(account, { - fee: BASE_FEE, - networkPassphrase: Networks.TESTNET, - }) - .addOperation( - Operation.payment({ - destination: instructions[1], - asset: Asset.native(), - amount: instructions[0], - }), - ) - .setTimeout(0) - .build(); - - transaction.sign(keypair); - return this.server.submitTransaction(transaction).catch((err) => { - if ( - // Paying an account which doesn't exist, create it instead - loHas(err, "response.data.extras.result_codes.operations") && - err.response.data.status === 400 && - err.response.data.extras.result_codes.operations.indexOf( - "op_no_destination", - ) !== -1 - ) { - const transaction = new TransactionBuilder(account, { - fee: BASE_FEE, - networkPassphrase: Networks.TESTNET, - }) - .addOperation( - Operation.createAccount({ - destination: instructions[1], - startingBalance: instructions[0], - }), - ) - .setTimeout(0) - .build(); - - transaction.sign(keypair); - return this.server.submitTransaction(transaction); - } else throw err; - }); - }) - .then((res) => console.log(res)) - .finally(() => { - this.loading = { ...this.loading, pay: false }; - this.updateAccount(); - }); - } catch (err) { - this.error = handleError(err); - } -} -``` - - - -This method is quite massive, so let’s break it down further so it's easier to understand exactly what is going on. - - - -```ts -export default async function makePayment(e: Event) { - try { - e.preventDefault() - - let instructions = await this.setPrompt('{Amount} {Destination}') - instructions = instructions.split(' ') - - const pincode = await this.setPrompt('Enter your keystore pincode') - - if ( - !instructions - || !pincode - ) return -``` - - - -We’re going to need a couple pieces of info from the user: the amount of XLM to send, what address to send it to, and the pincode for unlocking the keystore file. We request those asynchronously and cancel out of the method if they aren’t provided. - - - -```ts -const keypair = Keypair.fromSecret( - sjcl.decrypt(pincode, this.account.keystore), -); - -this.error = null; -this.loading = { ...this.loading, pay: true }; -``` - - - -Next we unpack the keystore with the pincode, reset any existing errors, and trigger the `pay` loading boolean: - - - -```ts - await this.server - .accounts() - .accountId(keypair.publicKey()) - .call() - .then(({sequence}) => { - const account = new Account(keypair.publicKey(), sequence) - const transaction = new TransactionBuilder(account, { - fee: BASE_FEE, - networkPassphrase: Networks.TESTNET - }) - .addOperation(Operation.payment({ - destination: instructions[1], - asset: Asset.native(), - amount: instructions[0] - })) - .setTimeout(0) - .build() - - transaction.sign(keypair) - return this.server.submitTransaction(transaction) -``` - - - -From there we call the keypair account to retrieve its current sequence number so we can prepare a transaction with a payment operation. We set the destination and amount using the instructions from the prompt we collected and split earlier. Finally, we build, sign, and submit that transaction to the Stellar Horizon API server. - - - -```ts - .catch((err) => { - if ( // Paying an account which doesn't exist, create it instead - loHas(err, 'response.data.extras.result_codes.operations') - && err.response.data.status === 400 - && err.response.data.extras.result_codes.operations.indexOf('op_no_destination') !== -1 - ) { - const transaction = new TransactionBuilder(account, { - fee: BASE_FEE, - networkPassphrase: Networks.TESTNET - }) - .addOperation(Operation.createAccount({ - destination: instructions[1], - startingBalance: instructions[0] - })) - .setTimeout(0) - .build() - - transaction.sign(keypair) - return this.server.submitTransaction(transaction) - } - - else throw err - }) -``` - - - -If the account we want to send XLM is unfunded (and therefore doesn't yet exist on the ledger), we'll get back `op_no_destination`. This `catch` handles that issue by trying again with a `createAccount` operation. For any other issues we just pass the error on unmodified. - - - -```ts - }) - .then((res) => console.log(res)) - .finally(() => { - this.loading = {...this.loading, pay: false} - this.updateAccount() - }) - } - - catch (err) { - this.error = handleError(err) - } -} -``` - - - -Finally, we log any success transaction, kill the loader, and `updateAccount` to reflect the new balance in our account after successfully sending XLM. We also have our `catch` block that passes to the `handleError` service. We will render that in a nice error block in the UI. - -There we go! That wasn’t so bad right? Pretty simple, and yet from this tutorial we have the power to hold and observe balances, and to make payments using the power of the Stellar ledger. Amazing! - -[1]: https://github.com/stellar/docs-wallet/tree/keystore -[2]: https://friendbot.stellar.org/ -[3]: https://github.com/stellar/docs-wallet/tree/pay From e7238faa53d43679e3e6ed2c20e8d0d7bc7e9857 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Mon, 17 Jul 2023 13:15:06 -0600 Subject: [PATCH 02/46] fix links --- docs/anchoring-assets/overview.mdx | 2 +- .../example-application-tutorial/account-creation.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/anchoring-assets/overview.mdx b/docs/anchoring-assets/overview.mdx index b9ee74e84..a3913f72d 100644 --- a/docs/anchoring-assets/overview.mdx +++ b/docs/anchoring-assets/overview.mdx @@ -13,7 +13,7 @@ Stellar has anchor services operating worldwide. View the [Anchor Directory](htt Anchors can issue their own assets on the Stellar network, or they can honor assets that already exist. To learn about issuing assets, check out the [Issue Assets section](https://developers.stellar.org/docs/category/issue-assets). -This documentation will instruct you on how to become an anchor. To understand how to integrate anchor services into your blockchain-based application, check out the [Build Apps section](/docs/category/deposit-and-withdraw-from-anchors) and [Connect to Anchors section][/docs/category]. If you’re looking specifically for MoneyGram Access, see the [Integrate with MoneyGram Access tutorial](https://developers.stellar.org/docs/tutorials/moneygram-access-integration-guide). +This documentation will instruct you on how to become an anchor. To understand how to integrate anchor services into your blockchain-based application, check out the [Build Apps section](/docs/build-an-application/example-application-tutorial/anchor-integration) and [Connect to Anchors section][/docs/category]. If you’re looking specifically for MoneyGram Access, see the [Integrate with MoneyGram Access tutorial](https://developers.stellar.org/docs/tutorials/moneygram-access-integration-guide). ## Stellar Ecosystem Proposals (SEPs) and interoperability diff --git a/docs/building-apps/example-application-tutorial/account-creation.mdx b/docs/building-apps/example-application-tutorial/account-creation.mdx index 35bcf58be..28f6e96a3 100644 --- a/docs/building-apps/example-application-tutorial/account-creation.mdx +++ b/docs/building-apps/example-application-tutorial/account-creation.mdx @@ -9,7 +9,7 @@ To start, we’ll have our user create an account. In BasicPay, the signup page :::info -Since we are building a [non-custodial application](../application-design-considerations/non-custodial-service), the secret key will only ever live in the browser. It will never be shared with the server or anybody else. +Since we are building a [non-custodial application](../application-design-considerations#non-custodial-service), the secret key will only ever live in the browser. It will never be shared with the server or anybody else. ::: From 4e7a8ef8fa9959d7686bfa5d264d68bdd3fd3824 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Mon, 17 Jul 2023 17:01:04 -0600 Subject: [PATCH 03/46] fix link --- docs/anchoring-assets/overview.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/anchoring-assets/overview.mdx b/docs/anchoring-assets/overview.mdx index a3913f72d..00442658d 100644 --- a/docs/anchoring-assets/overview.mdx +++ b/docs/anchoring-assets/overview.mdx @@ -13,7 +13,7 @@ Stellar has anchor services operating worldwide. View the [Anchor Directory](htt Anchors can issue their own assets on the Stellar network, or they can honor assets that already exist. To learn about issuing assets, check out the [Issue Assets section](https://developers.stellar.org/docs/category/issue-assets). -This documentation will instruct you on how to become an anchor. To understand how to integrate anchor services into your blockchain-based application, check out the [Build Apps section](/docs/build-an-application/example-application-tutorial/anchor-integration) and [Connect to Anchors section][/docs/category]. If you’re looking specifically for MoneyGram Access, see the [Integrate with MoneyGram Access tutorial](https://developers.stellar.org/docs/tutorials/moneygram-access-integration-guide). +This documentation will instruct you on how to become an anchor. To understand how to integrate anchor services into your blockchain-based application, check out the [Build Apps section](../building-apps/example-application-tutorial/anchor-integration) and [Connect to Anchors section][/docs/category]. If you’re looking specifically for MoneyGram Access, see the [Integrate with MoneyGram Access tutorial](https://developers.stellar.org/docs/tutorials/moneygram-access-integration-guide). ## Stellar Ecosystem Proposals (SEPs) and interoperability From a40a71c78194e7cd0b4906418750375b68777c51 Mon Sep 17 00:00:00 2001 From: Bri Wylde <92327786+briwylde08@users.noreply.github.com> Date: Tue, 18 Jul 2023 09:47:10 -0600 Subject: [PATCH 04/46] testing image --- .../example-application-tutorial/account-creation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-apps/example-application-tutorial/account-creation.mdx b/docs/building-apps/example-application-tutorial/account-creation.mdx index 28f6e96a3..b1e09f013 100644 --- a/docs/building-apps/example-application-tutorial/account-creation.mdx +++ b/docs/building-apps/example-application-tutorial/account-creation.mdx @@ -13,7 +13,7 @@ Since we are building a [non-custodial application](../application-design-consid ::: -[ss1] +[![public and private keys](/assets/ss1-public-and-private-keys.jpg)](/assets/ss1-public-and-private-keys.jpg) Next, we’ll trigger the user to submit a pincode to encrypt their secret key before it gets saved to their browser’s `localStorage` (this is handled by the SDK). The user will need to remember their pincode for future logins and to submit transactions. From ba584381d386055a0d6d6c48a286387829ca4e90 Mon Sep 17 00:00:00 2001 From: Bri Wylde <92327786+briwylde08@users.noreply.github.com> Date: Tue, 18 Jul 2023 09:56:45 -0600 Subject: [PATCH 05/46] testing image 2 --- .../example-application-tutorial/account-creation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-apps/example-application-tutorial/account-creation.mdx b/docs/building-apps/example-application-tutorial/account-creation.mdx index b1e09f013..83353ba04 100644 --- a/docs/building-apps/example-application-tutorial/account-creation.mdx +++ b/docs/building-apps/example-application-tutorial/account-creation.mdx @@ -13,7 +13,7 @@ Since we are building a [non-custodial application](../application-design-consid ::: -[![public and private keys](/assets/ss1-public-and-private-keys.jpg)](/assets/ss1-public-and-private-keys.jpg) +![public and private keys](./assets/ss1 public and private keys.jpg) Next, we’ll trigger the user to submit a pincode to encrypt their secret key before it gets saved to their browser’s `localStorage` (this is handled by the SDK). The user will need to remember their pincode for future logins and to submit transactions. From cf22fed444bdf5fb5d864e1cccdde9cdedb7f3a0 Mon Sep 17 00:00:00 2001 From: Bri Wylde <92327786+briwylde08@users.noreply.github.com> Date: Tue, 18 Jul 2023 10:06:36 -0600 Subject: [PATCH 06/46] testing image 3 --- .../example-application-tutorial/account-creation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-apps/example-application-tutorial/account-creation.mdx b/docs/building-apps/example-application-tutorial/account-creation.mdx index 83353ba04..cea978325 100644 --- a/docs/building-apps/example-application-tutorial/account-creation.mdx +++ b/docs/building-apps/example-application-tutorial/account-creation.mdx @@ -13,7 +13,7 @@ Since we are building a [non-custodial application](../application-design-consid ::: -![public and private keys](./assets/ss1 public and private keys.jpg) +![public and private keys](/assets/ss1 public and private keys.jpg) Next, we’ll trigger the user to submit a pincode to encrypt their secret key before it gets saved to their browser’s `localStorage` (this is handled by the SDK). The user will need to remember their pincode for future logins and to submit transactions. From 9cd9725de1cb72b944edc41357936e88fb2be9e2 Mon Sep 17 00:00:00 2001 From: Bri Wylde <92327786+briwylde08@users.noreply.github.com> Date: Thu, 20 Jul 2023 08:32:48 -0600 Subject: [PATCH 07/46] add image --- .../example-application-tutorial/account-creation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-apps/example-application-tutorial/account-creation.mdx b/docs/building-apps/example-application-tutorial/account-creation.mdx index cea978325..07f9aadf5 100644 --- a/docs/building-apps/example-application-tutorial/account-creation.mdx +++ b/docs/building-apps/example-application-tutorial/account-creation.mdx @@ -13,7 +13,7 @@ Since we are building a [non-custodial application](../application-design-consid ::: -![public and private keys](/assets/ss1 public and private keys.jpg) +![public and private keys](/assets/public-and-private-keys.png) Next, we’ll trigger the user to submit a pincode to encrypt their secret key before it gets saved to their browser’s `localStorage` (this is handled by the SDK). The user will need to remember their pincode for future logins and to submit transactions. From 7792448f20e1e7dac39f57178dfbafb2b9bb9495 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Thu, 20 Jul 2023 10:09:17 -0600 Subject: [PATCH 08/46] screenshots that actually work! --- .../account-creation.mdx | 4 ++-- .../manage-trust.mdx | 4 ++-- .../example-application-tutorial/payment.mdx | 2 +- static/assets/add-asset.png | Bin 0 -> 95070 bytes static/assets/display-assets.png | Bin 0 -> 26077 bytes static/assets/funded-account.png | Bin 0 -> 61699 bytes static/assets/public-and-private-keys.png | Bin 0 -> 36041 bytes static/assets/send-payment.png | Bin 0 -> 195797 bytes 8 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 static/assets/add-asset.png create mode 100644 static/assets/display-assets.png create mode 100644 static/assets/funded-account.png create mode 100644 static/assets/public-and-private-keys.png create mode 100644 static/assets/send-payment.png diff --git a/docs/building-apps/example-application-tutorial/account-creation.mdx b/docs/building-apps/example-application-tutorial/account-creation.mdx index 07f9aadf5..a79797a89 100644 --- a/docs/building-apps/example-application-tutorial/account-creation.mdx +++ b/docs/building-apps/example-application-tutorial/account-creation.mdx @@ -17,8 +17,8 @@ Since we are building a [non-custodial application](../application-design-consid Next, we’ll trigger the user to submit a pincode to encrypt their secret key before it gets saved to their browser’s `localStorage` (this is handled by the SDK). The user will need to remember their pincode for future logins and to submit transactions. -With BasicPay, when the user clicks the “Signup” button, they will be asked to confirm their pincode. When they do, the `create_account` operation is triggered, and the user’s account is automatically funded with XLM for the minimum balance (starting with 100,000 XLM). +With BasicPay, when the user clicks the “Signup” button, they will be asked to confirm their pincode. When they do, the `create_account` operation is triggered, and the user’s account is automatically funded with XLM for the minimum balance (starting with 10,000 XLM). -[ss2] +![funded account](/assets/funded-account.png) When you’re ready to move the application to Pubnet, accounts will need to be funded with real XLM. This is something the application can cover itself by depositing XLM into the user’s account (as we did with BasicPay on Testnet), with the use of [sponsored reserves](../../encyclopedia/sponsored-reserves), or the user can cover the required balance with their own XLM. diff --git a/docs/building-apps/example-application-tutorial/manage-trust.mdx b/docs/building-apps/example-application-tutorial/manage-trust.mdx index 08ad3ad2e..db1c49cbb 100644 --- a/docs/building-apps/example-application-tutorial/manage-trust.mdx +++ b/docs/building-apps/example-application-tutorial/manage-trust.mdx @@ -13,10 +13,10 @@ Every transaction must contain a sequence number that is used to identify and ve ::: -[ss3] +![add asset](/assets/add-asset.png) The `changeTrust` operation can also be used to modify or remove trustlines. Trustlines hold the balances for all of their associated assets (except XLM, which are held at the account level), and you can display the user’s various balances in your application. -[ss4] +![display assets](/assets/display-assets.png) diff --git a/docs/building-apps/example-application-tutorial/payment.mdx b/docs/building-apps/example-application-tutorial/payment.mdx index e63b54764..e49bf9f49 100644 --- a/docs/building-apps/example-application-tutorial/payment.mdx +++ b/docs/building-apps/example-application-tutorial/payment.mdx @@ -17,6 +17,6 @@ All Stellar transactions require a small fee to make it to the ledger. Read more In BasicPay, we’ve set it up so that the user always pays a static fee of 100,000 [stroops](../../fundamentals-and-concepts/stellar-data-structures/assets#amount-precision) (one stroop equals 0.0000001 XLM) per operation. Alternatively, you can add a feature to your application that allows the user to set their own fee. -[ss5] +![send payment](/assets/send-payment.png) Finally, the user will click the “Send” button, which triggers a modal with the transaction preview where the user will input their pincode and click “Confirm” which signs and submits the transaction to the ledger. diff --git a/static/assets/add-asset.png b/static/assets/add-asset.png new file mode 100644 index 0000000000000000000000000000000000000000..1643434a9be444b186f14a94f93feac38f2e0f82 GIT binary patch literal 95070 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
7%G9&& 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 literal 0 HcmV?d00001 diff --git a/static/assets/public-and-private-keys.png b/static/assets/public-and-private-keys.png new file mode 100644 index 0000000000000000000000000000000000000000..fed6d484d322f95266e1f74ab8454b92da7a3866 GIT binary patch literal 36041 zcma%iRaBfovn>|fCAho0yE_C45F7>#?hq`vyL*5ELU0=#f;$8VGPt|Db0_~f=i#3F zav#1mtE+ojs-<>S?~eMUCXa?pgbW1*g{G(=qX`8Coe24+5aA&bf9u#Y$PbdU!WTCv zC~WtCAM~0Pxi>_J;I61Di?EM?i@}7<#`3NR1w{d+C?l!uoqMwCm8h*7eExVYxL|4Z z$b`(SvKe|oA@MyFQ_Yxya($J1wZ^w}U1cf;oV6MmwVJsa2add-@~wL|?$61}513u$ zVl5Bz8$%&XBt5pC<5tlmoSod}|42adm(wwn&GrYPcCWjGk z*}{o#Hz81u=ynELNyLMQgZ`2}cw9I@x>>Mu57 zGenJY#}ygXy1Wvhn23x?MuldO9=L=JMXi05CUObY!$;O+CsGQqPDEJhUbYOR<~J!%|IGy^sd8q!IKMG{6AISl&s(` zYFz-WKi0(gQJ)YoQ*a^0;5(79DvgQPmSR&`7upWI|Cq& z&Hwb_*iNN?MgPw~rBH#PIIAE-N8RSSnT$Zur=S!0*Y22^7kxMq`aij=`+gW9?7#M_ zBatxwNun1oUfoTQDE|B@pS!>K3h6dKn>?ax=)>f(=kqhs^TFTjFZpBZANPuy_yBB> z>~&~HxEw99_nCRg$=#L37lYdFS?lwGg=|XD&RYi@1KP}r$ttAcUo%9Z{WBNq`nR_@ z6flUqKX8*~>{XuJ8NzN!$$vn0Lmb85Y;gXV!~$J8@4EcN6B^9UR}Ud1-0bcur%ee= zOnfVnbx1wSe57&sY2X5iTQ(%CN@7SWEindvar}uucEqT z>jwBbCU6;}eE%8kE2c;Jp*R<0xNKW9_r;yDP@Fi9|CSU=*2l!oza1&!A8M^5CW%{39v5W}dtWY62eFp|6{8HxwaR2pZ$lSjIrVo72XZ6N>y+*NHHKT?wkhV=PWa8|d%5AmnH-F>N*ua4k3&Kk8gA~LfExNZ0x_y%}>=egBQncsg9w2S_X5W zZa*bCBpY_1RIH+9i_%fC*3 zVNDarRZ^8Q&|acX__0hA1Ifupc{P_KcTC?fibJz-`BhDNgGXS&S8ov{PO3$gNY@$b zQ~iaHHng?E>KBtoQ-Z6xgLS_ACp?mvu46?JE&F$HCNF#ZCl$8z{F_D61&v-fC}&@K z|6;Wwk~+Ii$%%bw&KSWEn-I{LC?j_O_SHrD#Yh6q_s@KS<0=-M8!5-(iy<4-YbQ6q zLaeQBr#0tJT8Ji3X$CwU9ywv!J6!0VFBlw;?{Ym3j%8Gk$V5Xi;)qq8wdN@LEyoy^ z%m&z7k(NBR5_`Ka@|>3)_dm#35iX8o&=!>~>iym!X{l1c83rT#TNk#~ZkN5qT8=Yf z-oIa-+@Xx|baPiIciriur5|$X`h@7cisgAhzU9QUmYxfKFVs5maB$fhwO4{_{b36K zqq#h+7Wos_{Ulp4>!|g-gBt<=B3&9%(j|-)yNOg5^c47oUUt4D=ag z{0Q6}O@@c*dRV!wQVQ0_49HJti9}Gu^Li7sb-!A**UpsVN&+Rn(~@K-I9S|1y*66H zrIqEESR9CRxeZeB*)Pg3=21xfkSfq-k`-bk5OhFC*{6B9;qTs$39-gJ<6ILurJxm1 zJMZy`i??@GLI5ir51iT$ZCGHmq!zb^X@CXIw(RqdDtEz z$$uu#67k?NhiC0*EDUzeWe6*a>(kh7iwZ+uiNM6R16IOom zx82IfWvNgo{*ar@T^qW8KnYtdAo|xtMR^l_?NvFwg4ngesGY<&GC{ylGCiqd>#1b; zxaXgszKwb+*K7D6MeraU3vbsO#PI#Vs7w(;pVDCIXZ5W?>~+~7qHr@mYJY^`rYwSe zEJWMFW%Y|q;Tq>6%CO^>egLN{0G%`o_0*Q!pyFiH=7W-pBYnPv5*PFtDG{o=)qz2Q1G?ha35 zQPKYt=_{9uIjHE@SMmb>g3`Lykef*lcQM|S!tGK`A*zhntrvyIv_>n5&WNX4(OX zseg)33bR*ksa&p#+%AU17R8l@&?^qOj_{lTCWf4@HxVkp^={IRsCj}6SJzv)tm;K?CK?-db!8pXX#4?^|<$rBAI%c ztKkqKk0WmWhw5>)_9oGc;9xG?4S%E-M?mgd$%p%U^7SdKBnm#~~EJ_Cb zvc-JAr>Udaih!ByUGR|_G_xj{8PzAO_xd=b?P-&Hc8Nskye-&ogumccE_{i{F2MHgXwm)r;IXbgqIH2y}TFpsdxI- z9Zxz31p5v)^^CGIyp@d^wXN2ljI~ErV-Qxgf<5%IawKdgu1^(-(t2Ba_i;3T^wQim zrR7$NNn=hQ6QM>~(h7PU(cH!{numSZdA#*&+GR#36Pqkw(rN@!zksw(Ry$(mbD>cg zhKoBr$?eu26Qv!97O)-;<$f_GxRo-7MZ*xOf7bZo7EWPPa zU<{U^sRyvH?(Q`6YiaqUYE>zQA~;NZ&J~%C9IZR}DcV0zDqKFc!$r~k-8)`+=rH6& z&^b~KZ)m!T1}AKV%Mo{I{w>PCELoueF4~O1ACX5SiMVXsO&}BLLCZRN5pTW*N=ep8 zlxeG1sO(wzYGV^{v+zOTzJ_F>eGAI=bM&sDi!p(r)DPU4uSbHoq5U;H5^$jb*(y+V z-Y2~}h%oLFLV1+2_4o$^ERsKQXH+-7U}d?7E9hf}GgLuG;UsJ;MPX7NYQxhSZgEBo ztEV908jHl!!eJ&WmNZPo$t`kj<;P%lj%jX}rO2c!kGo+J!9glO7Kh`{522^#I^+oe zV%gLhn%5Cr{}`v8v5Lg>d3}=PCLmj8{YF)wUZcFxAz{k^f)R)smVK} zjqKpZgagGPxUCB%<9?uPJwC{=xlztm^(}H_yu*@#UZ=aija7b_#(d8L;v%WmO;p*{ za7vjXNuGl4efGvM4_jLPA>o#Echz0q+ZkS_WlO8JN{GPI$Tf6VpY$Dq>^Qo_@s**t zONRadJ}PV2ex84@F?Os(73ClBYmuUp_?KpOo&KWtS}1?q8-@bu&{G++(e8HpoY7Ep zm!ra>c-f^VLd3Q}zqyP3kYqrN@*Sj10HVHK5d&3h{+=~ zkX4r3(Gj50eH#Nctq)k{GiH&qmParnpc?rD%FavY zAwDz=xHJzwwGD*)7lOc#W<+s9t36)-OX+qo|Lv<-!1muD6aI5T5^aMZry_xF|9?aA z|M+YKy1@0yFiQxoZ<5srosUL2cXvs*{PJq9bc#_p1;q(Cg6Q|Wao*cFHph`jEg(Qr zH_-wKPKi-%A+M;gt80C=Y`gvM^Pncb1&T}sqIe3WHgc6DBFfOU^J#}$i&$wU>|7GuJ<6{rS=BLF6gA(hkx+Dr1bQTPd)iyvWB6BSb~VR@`|3+9Ck{wafo zDn)5izHPtAfRfdaJsfZ=_WQ(F9Px9Fg9yo(6r$`wnW8n1F;%>SqRfKtY{KuDfhqrL z6X`J&BlQ1J=K=#=PHx?Z`ZuguANP?JQ|qab;p4QW!$b3 zVxUlp&r?aA&p#`VC4_=G@_N`vCMzGc2=xgdMkwG3bJ>erdS4YVU9TB`1|FH#suIO3 zn91(Zalh2ITA`zb$bU^s$2{Ha*g5mE0E}vP4R+}E5!8QU(S+KUW##28u5ODw5 z{JZHoilLp1#THgF`$fPPx9+42p%9NWZir#sEiyf}H#wR^ELQNE9?NcZEZx6MGWUH` z6D~kzGI3-CSD` zA>ST)sd~KI!I*<~Q)3E}D}gWo8b^LW5VVVOS8xV&zCryMPcFMMV{}duWXVXRPGYM2 z$mxd?{OOY>U(O+pBh@Bikv4V2-O1+SAs@-q2dWo$na#*3m3)ryqL#RM%Br&XPhIx{ zc}%|OZsDpHYyEY&gRDi`DDwCAy9)luV<0SjEScz{>4r?s00AUjY&zod#qJbp-aNf( z)wR&&R^Jm-8mw%4w6spk@2Up7@O-4ooaRqdR;Y>_@AnJwRDmPe|VCniG(2U#))f6Lqz(}hwT2=o1F=GY5?wp|o--Uq!5!(nY4Tg9FOVLd+mdZ&BzUqpSzJ;hNls>X-j zXPKf=B2rXo{@r@%acT>7fbEY&os#2SZXcy_e$<~rbDiFju&v8lYQYbAuuUJj6Y>Vl zr>3Hs&Hx$xTFpq?$GkS(tC|shq(aQaS)i#Px7FHczG(Y}KlxZa+hyfKLzknCZ%C7b zHo+F|dar+i$ashCHp2x=C=?|RJ%7zstM2-yo>uNmQnSnZHghJoqky2=o$+t8U*Sa; z3--2I{jki|*Jj%q=-PZ%urhY3GpQ3_dh53mkCYO!lpU7hUjqFg{-CErkwVfiXHNU60@$Bi#I?0R|ohs)}17JC2x;)<9O`_Es;w$ zveyxH#!8PDGS*F}M(9%0OviJdeY_vB2T_^&v3}5oo|X~590l$+-QJ?+b*17llUrTY z`jIdu!R6+QrHgkyU<)7nHO{1}7!4+n8%_38J|gl+$@7qrPE}MGZ&qyQp%RHF?2cKR zAKIhH+J*H}(iei?w%F!Lbx{l4*b^q%N@f$<)+C5nFz73{`}Ug~=mT-bbS5bvfg>Lu zXat9CwJL0ZwUQbPn9%pbyclfxbx6x*%zKQv#EXdtDbPt#zQ~HEa3vG zq41ySZJx4Sr1U{_d1{ov5KDs{{p`uMS9@U+j*IxAEU~)C32XgnkxZ#Exm{1Rsdd0+N0oZNt4 ztlROlW$L?vRh{0lr_|*HKr)D`iATWMrbvw3zUW;qZbOp&IFs(d$*%>M*BRFbuwGZg zqVxin5eXX7*4GEK%#1N=wN`T|_G^L39Ab&K&8!p)F10eDci0Ev{vB_3@+Z~vDuyot z39NZzq;Aa(uM-o)TdgdCHiFxLxsKbM1+adW#lwxI$lIbhS!-FiR-j+PtX=+o0jOH) z$FzometPXjU4fhRB$?QX4jN-m_2>7nK=0X6Ps*c2?L^bHXmRV279RQpP<`_*byucH zzE8}#<2{ow!yczTJd_b?AlM|5JxIeTNsMHh5x?3f`n2|Tp z%m^;hXvh*)+wN~`Qw_n*BSj|^4`Cx1+e*XG)Vycx_Sqzj2T6>#b~tS?DNKV2vE}wX zpsAeAKdPo3KkmQVF{ks!Mg+X^(B2w&-!?V53;bEz1f)qMj(nMQm`8$O4@9Q(UVCGEAm4S?cZg=*!03(<_S)^8g2*v;@rIkb}bHlp>~6=%kd$|$xGB!b4$bBDM%W#bf1 z4!o@Tl$Nnbvtx);BxOh5cuSy9I-J*MUq)n}5uG|cQhfrOP<7Opvj%77$Kmi+!PAM ziClGne(K68&`=eyVTu%mqnsF7;4p22hxHT2(ddZ)C7kE7%%poL=_yffh4$+3$uqC8 zt}Qq^n&NqaC<!Q(r)K?kqf@V$)vD59 zpuPLuOKkC5D!RCoTkduQXnW8#YQW8gpKJ~s*V){GaguC{3FQLk7PjAU z!ocif8(lE+rxGnaOE0c^d(1fDd~2_Uux;|)m?=K4-LjZ3EzU3qx~C;4Jz*-Nw!5=a z-5VBinu*j&*h>bJ&My~|`mWJYXjQbNsFblVshAsOF3P1Y@BS!}=#{%EowOp~#uoEk z@ugDEY)X0YHiWm4rh!XDf}gcQCRI1|V5WJ~F-w=r#r?yz{wDba^0<|;7gIEUZ<*I? zmE8d=-jS?MRli1P7^BC<-R3S@Qp$uL59eQ#{F2&Z@l6(nU$`FZ?ogMN4#n>l0zgSg z9C&>SY{PPB1@=X9tg0C~pgCL$=m4W)>|=x#_%wCBq9=cbwH<9YF8jQkfXY=e9|(Q< z@_OQoI+-flJvjXbRR-fa2{A*>BIN)E;NPE^wtffslZdpeqgJ}Xeo!E=9ZX;;{C#9P zyLYQi8uJ>C)}UzxDQgZ=d)5(;ZahWEvj(Uk0d2$ za_8d(J{DYns<#%{?fcwVUfdP-%c-?><~b~nXz0+q6FkabSAui0g!;Gt79z*zLE94u z9UGtJY}Ory>4Lxba(fBfwI=<*3mP@MDvG!mTn{o3O6HX2IbI8h38_*9roDQu@XG>S z2{iPhapqhso;7MoMGPR}nV-we8Qk}*<~A$^MM2GbOc_y|ri(p$Cqh^$lT$HRyHOV}HOdVvs)V zVPEv9EM^w?FymRHPsO#=k3BACkAsDt zT%9L)yQmj+a#&F0YS?hevuph6wP~@=`wq_@0bk++4NgcVw-Zvz7X4#i#`B2GhBvy$ zuHB>iJF3p4;c!QatV$+d`jco)?V$upyj@5&%= zH9pGdaJrov^jPd;PIbLzMUmrh z8JyU$)=?b(A1*)zZq@1S1GZ3wS6xj2-F1d&R2p~Ygn^eUuq_HIqX8|({(j;Q_@2u} zjm)I;&KE@HB(g7Jf+nRW5RZ}`f(t{*3h~HY>_5GMPl0jUZ7oS5@tP!yfvNGW&01W} z0xq9pdb^nL8xE@tWL5IH;_xuU<)n>7%iXcTb}AZ-vH<~PTBR!680;c_o6-nQ4?(y8 zFiE&KNu<8buNz7xvzycpECvE32K$LZmE{7pd6~r2DUK9*_Pro%(LnZ48RS122wk8{ zmWYSQq#cx;{y&na%yB^<;mi~ccJn1Y<3NJ`$Y4LA;4R zF%dJ3$Es`3M~Jq<2?TA{?2VcmJKT35UxH#u1qAl5rmDxDT`R{)894GEc!4<%p(qrI zTr`o%7E(a~yrdlBKi__)S%grCedBSH$%C{&F~}wE1voVemmRTBRuV`Qv!m z&*EIKu3r){K|3w23LfEVl$b_y`H9FS%Oe{})`E*fe!DnFnjcp?b2kq=MXoPBmn>oz zTN%{|z9NUKo3Fia{zUpYT#6NY(cZA*e83&! zvz@`Tg#r0uNLIJIK-{v)cIN~hFwbr38bg{QRAvG6r<8Kjo8}Kq_XM|RSR(}9QUh-o zhwe73-ZLnRW3G30-WTr?=X_PAFwHJg5Bd*!#36FYVC>K9b_PT>Egu~Bi zb3sta(67!50JBx?M*Q?QWs{auFOpf{f)GS3+QMIbb1-o^&d+=a3v9NwrOOz}d{7=g z3W3!rb>B)1)dJPt8@B0-~(|=?O z8W$1>ef{W0f4(&cV&SsMxQTB0VYe-N2?OAZC8ZYURClC^Ho`n-+)zEJ?c*F6P2V! z#lK~wDCckW&k3Rt;;5t88z z0j$Ct<;zH}=odOQV8wxbXcQn^OYg{~qZDs7iSqMee&-tSm{v+Wj)8D2B;hr-1i;mC zKi*I&?2f$II{Y*2PMcWAo`YJ6)|bhjg%YuDn4B-Zw>F78%TqImiq8W5evLa~uZsQh zuuCZP)Uxb4x&coMNM$Zv>ULjANwRv&grLp`Xty>fMMNP4+LnvR0fr>vb@{dkIk(Yt+=-9tyx9_V^EWk8|*%>G>CJF&P-ualg!^Vv|f}gDu z`r^2N)ES$zXQpSYA%D!W_dvKlmRf|yK*6@o^k39fsCi=9MKB5=UP_=$%H~EqHJo5b zR;xXFG;*nUwW^NH(EWI$5Y_1rj5Zqf{!d{8*P_|!W%5nT|p6p2K z>8}p}_nbV?0hoEZOPx$YRSkfTMQN}R%$M8LncX{LgC8ZioHIF`kYXIk6~}^BNq$ys zO89&*U$j5#e8-~07>i&K{%&gk?(rji@(yt{drWvs9_U;4-d+#rJ2Fax1BJ!&%p3u? zY-mZ%8JflYFt(#fGzljz4r5x*gQ6PASClO+S(%zsh0pvWu}%%VuU{t`tt867Qy@kb zo#pBNWS9ho#SoBvZrHA<`pb;*{KB3ub)yoHsOehAUP=__dBsQ^$jpxszE{d~s`~us zJm=Q&FodsnJGB4M*T7!?6tm61KTFe@IAxCoFnA!9+-3E*a)71d*6PYA3K=gQpPql{1Kw@pStBO+I#*;A!KrId z!>GK=cDB29cu{>;rT39yY1$wofkFyBXNJRFHc?f>`2q#1hQ9TBx6zQ7TAxN3To;BT5_g73&vvu=kL$mZcjpzN=e^TT za!N7UOe16L??Iiuo+&9Q%eSq(Jr}Ag0<4(J12wCI@^(X)vv^*$SJr`jFSBvLRN0k~m3<>kwB z*7YA$p2M(u$HqrpS($w>FWL}M~orIk>QX-eGG@RLjSEO)B86Vl&r%oMWT34i#kgV7iL0&HI5Nko@?L zWphNBZ2Np@P0jZ}lgoxdZIy0qNlTi^)x{p4J-t&&%-;{kspA_?;Hx#pRf>Gh<7&>a zt^Je^s_~{m`pXGj@Z^Ev44e6Or zu&KXIya&~jz`=}x%E5OCYcCza7DQXy_%2i9o4HIT1L**V{ye>cb9PFHj?4)Eo<_}} zk4S?P29xUv`Vtntxab5bMIQX@=R$Hu@}gz)xhKE6sb@wAnpebf5oi z2!7v$B{<*brHmwT!Ve-d_-&NM8s!#MZ!xd=o#GIc{Pq-G`8`-~X#aT%lrYbA9_Sz4 zewIDtMO`jInFl8e3%@n*uvbM|rWmd^<#Q(z@i!^1 zu^lUcYDGi|0i*w`C}bCQtIOtuZ3nco(J<1^eg6DcTbD9a1~JHCmE-f)XBXJC^!_?7 zk}u8CCJUt2hk0%UI;jxCgFbqV^+IW0uB|ermsV@Dl>P=jmVu)qHZ!InV?TP)p%3 z2%bM(`u+v2gla`E`6!wis6Ru4eDz6lgI-<3<$@thbE{tj(SXt9nzEp3Sw+=46tH|y zo414`&wzAY%YyI+>~owRmikd`@pm|XKJDxaB&3xyvZI*%t8>}g<29mkH2~M-n|A

HtHG@n0YzUz8|I%XSoCBPJ>R<3mYc8Q?I4C6hPFApD7By*1nmLdVP4 zwf-GdXn=mb=Jr0GC5+GMrAg?*9|e6lE!tp-6T5THgeS0?gsOSYiV#FTtihfA~^BEQlvmLIyaZ3Loc^auQrN7(e-2Oh_+@1T*3xS(e(=v3ONn!Wl?SO zX;P#1?}q~k$sFTs8q=NHGM?gWhK$;XQF9GspBC(L8~%QWrGpbDhO9LarlY1v z%^C+_+G=;hv#Vp4#dGcR(!!a;!MD8p7!yS5Ikz+R(r5oP*6X!p#-dMoUI9>)wZJ)R zuZ(#tjm%g0wO2#%m2PKztFKC7`-{h&ABFFv{JEQjhtYwLW7f@5M)kcF$k1I~Fh4NA zeI22qxXO?|(dV}$1! z|Fp+f43Yj+##x`&rqAx4AQO&AV|}5-vivu0v6l^_`5J?mS&yF0xmA2wk$j4Lg+GhV zKDT-QFU#s8`dCSlz~U3r&WYd=Z{g45cc&j871A-myrFCaaL2qY^r2x61tw8>d3W?B zX`~D%tuxA0tdi#@9-`kZzla`789h1B)m5I{qIKTSwV7@Txb)Z!$5c+ucIKt>U1qA! zjZo+QG#Q;CfBo=5>nj6+2g>EP)AjPgFGVH{gM8ts(t8AHg(%u@qy@ugPWQE)2jJ2g z{uA(iQo1tB{74dYgsq`7^H|^|b2#}|vx|ouMJNC8b^lKZiDWwDoztR2)GYn7YpvGm zQDLlXE+YQvr(w^_{^;G+$p>WKozCqizQr}C>~DtHV`mjF?4JoOnCIOBJ?==5zKf0S zy!byZU9a4F-(AmiR(*F1=!(4$J_zVGu|S!=wcNmd{>E#GFo^eje-2n`%zAlL4^*Se z6WfQaYNAV0__MY)SO>tfqWj2i`rZBc2`4Z>)_;=R1QQ+#1*1y`rqVapRZCu2E&w!j4a}yn9-+J7_Boiu&xdcXc2d zlPTI9+vZX$JYWT7D}(tsZpCZQqnlc+Jt}@)uoL$Z#mAaeI3UJiYW= z^*MWe7=YYfJU^q6buY1um0tC`Vg@{W7BzxO=7Sm5FeS3%TSm3*0YCzSF>-U3gDVr+bnmO7y5e#~$Qj~O<(#G0pbpMPC!~Cgm%Yttfzir%%APVncxUDP zuT&CHy&OSbCBe#fv+8sC3|t1IXC=&q2F8Cclp zh9BU9)Cu5z1|%**sAsG8%Y!b4h6}QKA018|fGHyZSY&^uVBjXh6_mAbs`s(3&HHf# zUrT>OD1hH=RDa@@yGOeV#T_AV*L*wnf`+ly9T^ACzMB6Sf$-flC)ZLs1LrJXxg^?d zn|t{nFHMvKtHz!tSXll&WLYwY5WxTO691co`2UxDeUj>B2`f;;`E}+|3ztqj)bP9? zCMe#4C{9X|OHiHGiDQutg_n3K%`(;ZhR)_UV;0^>ZgnokXk?x*E#BER%HfFkDj)&J zP~bjTXukwA3cqJz*G{20QJ0td69aSW+0hi~6XjuS!tS>g&-WHqOa3a}879+{9m{A+9-(TeTYEV%2Ldj+-^4q9=}s|~)WNU!2D|WMrDWgDB7luth)P(2NLYO> zbhqnlENPUMX|Btn;(JlgR+@%-62=fO!kTS6-={cHzmOMlnKo0ewI64l3+Y1?m-7MIoL zNb=Qz9Oa?QZY-;oi$+~4_dYegJ)E*wL}*GyB!xJ| z*iErNr-`NT`b6l4&$bt7BJHv5(ul0lOUd62H8f)(BwXKPZjk$G?y%W{{u5C+KcWIw zvmBjksaF#VnosbtwVwr1^VHpf%AP&GOzMThx5j%RuFwN=r&dcMqKx^0Qk1iZSF?@g z3R^%bMbRU1QpQx0KuUz4d}{tXWWQm_e2+&=lcwTNcrWODMy^7(bih2|5$JW#n+B?on-!p2a+W4wL-DjLK+odwbQ7B0B9zJNaZ;E2}PP9BC zzkZc*241pk^>C~@$b)^TwkDs?%v7dy-rk%{`Z6zh-&Rwa-K1x~Ooo2M*_$lf++W`> z6Mtvr57-U_oT63O+6ew$YCorHKHY!GxWD7}nQQjBT2m#ldqgVL?R{WuI(ck=A58~z zMvi{S6@EdkIbVt4y(fF~zLulo^)FZme8$EZJui8TEA#Q!Wp0>X?>luH^*KX$kMj4Y zU3rgK-%f8&pT1l97#>Fek4(!tIv8)=VY6NEcII?Y?VA~RePP7n)1H6YMC@%NOX&N4 z_`cnw6N9GyhSXeR(C6ftSL}X@TB^zc-c&ED2E{wukTj+DH6r2E7L(pEdYEDA_hW~K z40&%B1juQb2(CZOiti7mahI<FZ**av9k@-uzQ1pc*RU5WkBoxijD6j59G@mLl)t$v zdaBUZ_qU8Z+f$XP7fOS{o}@iF6UW7j;5P>cYDgQg69DX<&<9qdQ_GW(U7#ZKcNHo$ zQ2pY=d;L}UfRKwoti5104(;Yxp9JCgjzS@5u~NGFvJlP7xx~@SmY(SQTCEhg}r@!VZ&`_JT9QhbXBP$vB&dy^DK@i3^34wvkD6fvp}>Z1f@YxML#l1 zNh1_7&~duWgm8|(at41Ec{?SJG~Z^ZVF4&HlAMR65ug94d8NHOc}g_gzrYWqLfHjyIxTPO+1i|6v&7zJ-b`HL8f_kbo=QoShBKhHg!YzEb*o z=!WXSd-+u3IgPF3dM*%U{iQ`mW`Bh4$N+(pRN!S3Q?zQ8rmS_C1BI)<5mjZZ7lc*` zjKeCmaS)R7r>X6i^mIBdY52_P3!*^f(hH{=mmU9d4@JDdUi3bZ0VX9c{Wh)=N{J~& z@reRz_IKJZDpq(g3! zD)HgkSn4B;>v;+MvZK@dT{qrGvM40uq>dmR_pY!WuDWv9Ur_h+5iQ_pi_Q4` z5ksJL&yi2`R@BO2ee$@bV=7CA(Tb|*)q*}m5Ti`yl93yoN3~rJcbA1_mW$x4_+(c@ zt>fyqz0U}!Weo~&QUn5=8HH;B-)6q7XydnwdB-%bgD0}?#GYWov>%s^xX?Z$S{N`h zG7gt!gWv89>|agEPhTOnE{KvK>mvzP81HyyXY9_Q?gQAa#_hqIJ;{M8Rf+(<6aaXD z?%ALyza#5yDQdD6cIv)FM<7z0DbRrv6yp@Vov|H)4<`WHwUC;8yCGTc^L6SRoE+S~ zL9^!23c1NYC^8>$Elt0>+`Lqa&l{=CN z4#7ikcelpfJ$N7lhv4oSXo9=DyH0=a)znnIsi~14^Q)`--oAGqx%;lO_TKBL3k4AU zt2X<=Uee(pqJ_t{-G{~&%yE4o@3%n{E^=6 zzYj3as5(f0qTTeYeIxit>;5=$psVi4T5?rVKcZ4~^p068Z@Wy!_j3Vem02$&0!3h< z(Mb3Y%`S4L)tZl-$zS>f5VK#9fuY%g|86P7A`bO8;x#F69`+-YF^!+YP;d$&Dss$<7LmP|*< z3hdi)V=A6`0NX!sXNF{uD89?*+zCe`6@Ts(Y82Bw&Y%Bi{*Bi&F;{okq@Qnntv&`! zhQ4caZZ*-mfqmQjcgZ>a%AJ?gyEMG;OVF0rlRUq4n{bXmPG_D$_m#Y|7=Qdf_kXv! z&7mP_4 zR0Bb$$9xx^Ky+l;ES%ifzao0M3e_KKrC*v|93L|%pz%FLI?84&$@Xxi@@ zc)!qsv;tS0SjkmY=@f?Ib0*)6iEtdc3feDhv-DsXgelVf{@;irnaS(T4UKo`DUq$2 zLma~ir)8zT3lvHZZG;Dx?j>O?i~692RtyAII7hO~%MVd$@~x=f0ijHs&u5ujfU4KRL7Xa>_h!#&C%bp17THxn^N4pTce{NVF!q!-PiDTI5KyRwC znG>L(%v{n?8h-vIzT|{bhC&|mboYxdJ<$>NCxMZ7oKvq0(PQCy21~3M-$z*brRQ^e z)mw$_YRSy=(zgjleP0kV=WW_y_ProH3Lm|>vb#O8EA(_Zmlu3sFr0=Q18s0j`)~HQ zjGuV|D*hb>dj4bGPrTHHN0kZp3l^W3Gv@TJ6#$m;iLmJ9`CxlEWl1#DzY-9zp|DUPN#clcTL{ znU~bC4;Ek<^N){9R~g(=r2q(mC1_7Z&>Fc$x&#ayb{#EmN8SAcSK9&^uewyq8M-Wi zIerA`o?9Qi12OcEi$=9}m?wSTaFI~?zikEh{i5jp4FmRwS|QlD-pR7x_PP3Wzj9|r zolwrf5|QaX+8|Nkw{tSEO(4o1qr3WiXv(%!)Z=32cWQe5fWue!*&97g18JPr!T(h+ zgxLE%!{G#MjKiP4Icw#(J%F9j!LG!3O?83QAijtEJ=r1)?eTRI)&;0*!FcD~sV+1k9RgL;1$z?YIrj+f&BYfn;o{&0l zKwkU>6j z2vbu>xcNqTJS5o%3m!{odW62cliop|tHVD$lCClWExK_ZH~s!QgI;~JcQ%bz0xJV< zticzTn8=OI7AEsJjhI)h{XNdTPDLw&U1!0z+J(XCEkc7s;cgDy$8l{%FWUL@4gKdv zSE$boY>PYIw(W@;dpE2;Y#_?X) zk^`$pPXL8ds=Q!jz7P5|P%dWLUS!-a&aOA4FKPV-D?e%|oX4YI#gv}*E_N*M(~tnA zbFzU@RBGyw0%p48=$fgLR(1s>i$v;_QEdNFO#dt2AJ#hI8YWqht>7PjDBO>gyG*+b zSE7LfW3-VG=RwI9Vk|||kKZbis;el&!W%fryD7$!e?E9h>M<%87^dz}%92qkDHd^1 zCSz$RS>R&HQ56D>dGVn6e)BW zrHd4Rr8Ln}A!_(Lo|4QSNfQaubFq?V!pRgDErwvXek8hh`PD#!0HIn6zpfWWL2RHa zz;h!RvkmqxlJ@5M#lXTicl*Rm_%l;#seKaKS2TRV%GK z@khGB!IIfSzdzr6^+y2nbdRLWG){kJwP{dF~1t z_SOi2sk0!rc?tL_j&bvidT8OtRI@aezhiWRmKN61h~@f__-2Lhx4*CFHQwhs-J1)J z=VijoPNXbS{qGS|_82 zVj@2#nvA=ssX!<+l4*AU6HU$?rxE5b7ZwvRV-jG7b3=+oh4jV}fRumm)g_(fOIX49 z)~9eaN@WuMeKRIS+-Hk7r`>eA_yaSdCt+s1Evp6@>UJRHTAWv|Vwng`(TRNn?xM<6 zR}Dl`S>3vdy5#xh01M49khEeSbq=I<6&>3dbH~%KM_T+7TjFAMge}R)U-}$Wbp~97 z_!BdtWV@kZ7ZK7G2}Wq9foV(i87O%%uRI1c#~*82?FaSXnRYYC;s(9#2L;$ui};er}cnfd!B8t1L%pB3LgjDAQ61K|u_ZXWF$+ zYxY&SsWiCJh2T58KwtXbNK9o_d%e63QA8mokGL1zZQ=L1QUG8Tu|vRjYRxf2+(etT z>0gLKtye>XaAeY7J{QPYx`ECdyGO66a%f4qr?#W^2&MiSeHeTdo}0d1$=^NC*$1%m zdY@u;OTYAro-PI?1}r?ua95}HO_yYKx!|1a$CX=t*meZ|KyUws{IKQ%tL2Ou;?UfA zjc;EWuYx&I>OB0ylY2DWfG6ln%Iu&gzt`j2(O#3HK!^nXw)MP66VYxhE*5D`aDZH` z9hN#);7)_{bQLw;!K$v8-kmNJ5R4$6963uf=5Atww6DzGmZdBEgieqS`$oU`e7{n% zFW&R;-tVcaWe~-Rs}3lHqJ_11LOa(JPS|`5Xy$!TYd_}f3OK>7`W|WcPvrb%ilQ#S zW@O8MWoc<~a&a%=T0UV_nL(tIz+u;xU$sZm`qcvOX2E`YUD&a33ftn1bE5T1HC+{< zh!k5w?om5L&{Jfp^9DP2wLM&#UNwnOQ$DJo-@pm+vzP}WZNKkQT?3Zm@}%ASv(X%( zHIOr}z57nSs=#P0s#AC|ur?vN(k8baWuK)xV)B7qx`|?MGwEAf1720v$BIa;576G% zv$lb?KSa2@zn_`uNVu+Gf1dnRSsWb^)9KcZKydtZH>ZjwfNyd)hwmy*{-Tu0JvW_u zEmCoO>2=^w=3bu3!hI*&;QsXp4x|Qc!g69eZdJ?^JBouc=dL2JIa2sSKk5KAgpx9q zwkqHr?P7z3?eEjVTD2OICP}^dstK1 z5dIhe*Ibk_8w@_@EO34z-E_t~KWzEoMi13Ms&?a&|J-{U? z)KYJv;#V;p-S+}#RLq675H+fQnw5%l5Qzl^Jvt?dOrmpjW@Ff+nmVk`bGMNWBTPF zR5s94$n9DFU8#ZHjaH9VPzpQ3{sR=cf6eaJyrg*F)YeuBj5*_yK@PSiehP)70`x)2 zvGILDp&F3YG{RFt3WEak9NCEuxBiH}vmN5*=`Y>ud|1@U-|Sto)dP-Qw#7TOl@nNc zQztlXG8Dw0O<#!%=jaJpvDu#cMw8f%JuW4&1TaK}kS^KbgX??5du~2^I(N`o9MOa- zw_!3$3vArR8v+=m3aE&%k%HBp3hjBh)CwjQ?Z72>{TbG$C;KJXb3`z~+YMr~QWAh? zH}t13^YP_XMZt5ec3p=#8Y3h08I#yq7-a&3E9|6&e}3on&WjPp-*E@_+R=^Mlx6+y zm~#%PI@`+n>#~WL@4!uT$!d4Q^&n}xTpk5HJPcm0d+KJ_Nk}x6xPYqMV<~bGd%7jw zJ8HJ>yW}{2B$A-4Wd51RO)+?j={nS*pf-<`xFR_tf}PQOofxI?fBrr2^%~2d!uFS3}dLXK@YItA9e9yI4SIMBPrjpUSoVw%oDaKe*u(xG?89 zR7#`d)HU!qU9^qfo(2YQoSsU^gjz7|yPQt90Nc(f-_NA zspb?iyYi#&sOo+!IK%%mjLcj;rf)hLo1&ly#(5MlEl1G*fZe<(tPp5Hgx@&Mxc@H8 z^w(*YNR!+Yt?4kFdhwdu4s({(V>|xH^8D(Xx5F5r>`Q$|CTL?@##L6CJWJC^y4)89 z9i`wo>+}VSSF(=UaR z&ka@&$Qlx5wn0?lMQ*dYt8U_FR_!C%6q5tkAj#&M(D{1@gf`Wg)#XsU8oELa(v9vE zf7Z3sFRG;;%Dic5&Ta7y#f43njD~Z6t(m^DSjF1y{o`*=(Y_DAQUbdmf!`WQh2;_o z3e<~WW!j6vg6!Bf-lqz}zn_KKonO155&@0x9=&zV)?npn(y!?!e4u#xhQELXw6<*nxiF@9PH1^ z7?GmzZoObE6xed8)F|biDZ{rQTv$3Z*X`&o3`7aX5-AlR)5_ASwmoE)DHU`(YVn53 zTX;>dyF_Sa!C1#2FGOM@#3?c?!>E|3vhxXNA;y%1BJc=Tk}otcKuv{EzyZyd#B?*^mmO%rAgdgiR@0)&Qon=t z4H?o`=#R%SYmwpSL+4P^CBq=Rn4Lp5mNOf5loF|`uhA|>i*3Tj<;N~==*ZWW%1SAb zz7DcgdI9QBxOeI|-i1wgf7io(&YS$aCh|dxwJ1&I#sRPWJg8zXY7$CJ`M-Z#NGs+V zW0rVT{>r!xfmH+`v?e((O=Bc(lfp^{n{E%K6mYH3iz~1x=XkA(1=^~ifSsd+3B*Av zEbmt~dB?@wDiL15zzDxIz2GxifsdaBBJ+U7uesBeAJzh#*adYCv4DbR_RXOk>UP(w zdF55zZOwug`T)d}*>|)Q z-_0(YDVgeGIR6qL7@X;nl6g1LI1`D~4aBjTjEl@eRFke?4^#obxA38rs&)IIyYK3D z30(|aJ@sI37rRS>z&}IdequgI8_=7*E9-WXy4PaG^B8yCDX}#G(E(>l>RbcSTCV+| zh|H|hEq-zDwC8ms@IMN&Gh$0(fEB>}DimorL)?eW#+0UK=+%QVNxmhTd2w>{6 zryl!cdbR2|xW*x2x0be%0mQ(BkX-)cQYM1c@3r3tEiL@f-G5;Hn~l!o5$o39sv3<< zrtv!8>pllYU;o0vz&NNOvlfXLT0_zMxMuZmhd<(zgiu;+R6VYgX>w#XAu?#m&Q5Eu zdSiR}%s;<$`7$3INYfmI+6U71!Tv`@dWdpNzEX&XxxN`!MW261zLxw(xEatymwgB| z!*lj*iqtbVKIf+x{p&Is!eV+%{zt+6ebeWSqYHSNPv8=Sj*2xJA{~@;k za8$<)fO%A2R-b+!)RQt&rMaS|MhxCl#rb*8a(=fZy?&?Np7SuIi5$Z+e-eB!m4 zlfWIQB&a9ec8kD8d7xFd*&Na0zvab}MVF^k|9!GpVQ%}!jCWZ;X z1X=ly?7Hl7MHAVc@6E*V+P!UU+{{+*Ko&DpqkAr4>SDJn3;lfPA$ACs%PsNfN>pLM zOINt0sDou8Pe>@WGMY;wRYSldH#t+KEHKfH!6{i$go=oqaG+K>c7$Gqk(;2##7qkf z@7DEHP4p~O&~AY;1EV5WAVQCuZWBc@RZM*}>Q2q`&spw3wpfwhAI@=%)0vNw)o9}_p86qnO=l&dJ8JNM{Neldj7N<&?^Ac|Knp8roW zvRrhGO?H_P{I~k5?HciiI2Ba&O;blz#&5!Wn6x_zrH?ae*{&L91eacY0JsWCKP%E- z-Obr`$cmrekbTnn>g~|*5}ld#oK|rB{8f0fQZ2SSv{;OFr48QH+Yo+yTV@q`Uqd8x zL@0SfanR+-c<&(>nY#;CMj4Lh~RJz(12j@H7LinMrabGOz!X@W1B* z@OR-)@PH561_n4-g#*TzU)mLw4SP~HR*=xe_aZ)Cxen&M&flg2ch?=)r;Pg@Qj&A^q_;Rf3pkNFg_-~rzAP4xm;_%m6tZLTBkJKtt~ zWCRA7L!b=N#{0%cZrmUKtJRkkUH=bYnd(y_xBPP^k1rc4eVNxs8uhJ3Z`9G{Ur6|c zaSBQ@_{i+BpQrnU{WT*LN4Mo2n%sL+vGS8tz@;22&H)SMylW~IZ~mU`G19BXD^>3< zQ3KJ2XgU$CmAAtSpO0*Av{K4eF9y(%RA*+vC!2dX!kL+=g6vOnMU(@E8wQvAkx*GU zLbJHS(g0CvELkWsnR0*6-8KylBxocF4`Mv}DK1fM19Rfoo@GAm*o(;m9LwUd6x?g2 zTYeSzq`fMY8Y9VOvKq^H>$oJZ*%+TgmtgLA1K@SV@2^`U6-XTu5+hA;d+kSDo_lprK}7|1cgFJ221;SRlz3Z%JVF$ z3JFJAr}Zl=5D+2}B~O(Q;nE?%P=5`vr_E|Jp)KV$*Oe-i$rh#Hnazl=#qRDV;#ZE@ zO6Pyt%RllvD2(uC@{JGlzvIvwt25(V%^VKNndg@FA(S%R)n9D55C|3h%|mXt*A))_ zDa6&2d*rN-!2{+r*`#56L9O~9Mmq*EC=$w1qJ`Bu#Zn!AE-0bqk8w^aX=Ro5nQ;E< z^-P~jSnF(`s6kaad`sI<=mxy9fR{8tSm99Dpqfm|kVb;+sz8f8<-Yx*b?S3+@ak~^ zHJTZojDm(b9CGb~DlLH<9;P1F_r9AI3|K7tVKvPC+ED}wY(M(!MRWIYxuergczi^g zp>(ri{2DaGCOg5IsA0Ou#_2M*5I7R;eWKUuLJEFs=xF*7=sEzj&({1YvtAy?-E)UT zRyl_zEWrCU4Sx5!*rPO2$e&t#*Murx9_n{)iB$P6e*Avb=G*9w&q}HMS(!ch+jDiW z{s^zJ;62EGl6LiB6hM0gu3xDCoKZNqW83N@Aps#ZL!C4 zk+%BihTkjJDCw7v)DIlK%Mg$^RDWDuQ|B=Y$I@TY{lr2qOy;oO5@{$ein!e1m44na z3wa`#$MkfSK#?-=4e3=oAVKadUQenR0(MKgZ|v+{m)P{02s09>h$}7=y0zJss05Ha zK=d!;IHV3jLlQQLJBS8O!;_YKm8C3(wVBJh^eT4|QDbH5$@b+}ht@DFLnC*tRYyG9 zlYaB7jj64u4i*k^{ZYj)g8wdXFy!GR8C|v6Oy^5n5J=)@@Zyzsw30_uHG~~V<>W=t zf4_x|9Vq)Ve>=0=pCp=A1OMu1^9^D|O|P@NlGa+5o38q+ z$ekWf1RH1Ozbj~AS}y1cBS z3BYE)MP>^Bf?^u0Y^jC9C=IkU$wFX|rJ)AUm6=k8Ny%MHJ*1{$X#`tlBSCA#cc>`= zu`&rDdD$pYBjVKn7+PBFa4Iwjs$wKGocD9V}`2^Txqc{E^OdI|tTv>*AoHHnvBxzKhv!fmf8rui2H*16+d zPzw1~HxzET=X`$40~82}-g`QJdY!5V7IkvZnO=?NVHAUu!!(cROC>G z)y!alAWPz6*j-{eG@MVE-VhKPH#?c~e;p(*IYgXE)A;$>@a;DwkWPAy!y?O?hFy0pCgNYGDwyDgxU4;8ZhHTczGH9)<6)TV^HpSB#& zpxzO*(`l8&Zs4Cp!ONna1u%!QTswJ?2Cm5G4<+OAFOTw?Tx|q$(A&}4(T_zd&qf7J zuLlpy1**PHhfq(Mb>@|IEVgs#q2|cSu5J`O;lW&|>T3sm_Z>8SBN@T(t6`KQdy#!m zoMUpmfMWX)h$b-zA>yX=UcOGW6c?hqJM1iXC&qx*r{0xsW+ARA-8rHVaK82h#c-w1 zd19s$KIls{1Cv|P{^15<3Xh$7h6&A+8Ybv2~3gDsD2U|sEC}$RbrQE zs9`ra8=2!8Lxp4GCuOm05=kfy3QVZak74yu^8Sq|P^20-5Vyf$Q08ny6_{SQ69msj zUmy||e^&q!aW;Ff(9+Ttdr{zO=vv4>`Q&d*--A`c0xnw<_)5Q|(us~KnJEZHKR`v6 z08>!qnhFTc#m8Vt!h5iw^Ra%&x&HluyNKbXwL2{(c7Z|6Kr{;u@R*|=rLG{HbnknD z3B$@#{x*l`r^FZrs4{E?r78wtAo3)O!F#gf7hjnw~r4jMb`34A{Tk0euH3mSNE%`86MhcxlhKZKId zJ!k|5mL?il5~~JjS4nD^sR9757!4rH@D_5f8Gm~49fsyZ4;d9DQEH)vkwyZDg;n|e z78(ddf|c_{D6)8e;a(0;vVexx_&$2W5dE{V(hR)zFtf2BuW2p{dQx}&nL6N1n$Bt< zNtaUg`_76$Tk@ZnixGSzn!j0-t6t!6=xUoC-ySDU2z2~~PpGlz2g>lXdls%r``6Ue zbgI(bIR3BZ8}Dl^@xs?6;i*q8?sgH`+4`iztrl-otQT#_09xr1{;W7m@xg^}`lL%& z2JxQgrfI6*wyFdtvRgwz_G>!6{JbjdQg8rS?C?GS1$w%Ck_=;1YBZU!7-f<|^5nNf zjW`xos_PWC#uIvpM5@%!R`X$8ZSh?LkaA5TAuu+--e|nDIfqNASG<_$zs8fvK~!+K zse+{??auIL38WN5woiOH=I^hA1o-|o_M-ipo0Mf0(!0;d08@#!oa(J0%M^mT<00x( zp=G6y9srpYmq2`|`4QAivr02qVcnZ%pPhLyjXb|_O zEZ5P0d0np99@=^(Smpa>NtgT7+<&#n_JAh>NyJZ-HLxNs+z}pL96VkX7a%24A`z03 z{^$D^oUx<~Gco)++X7(V)YRenC|A}75Fw=sf2>G^@$Gl(9M>j8jZey6=-IbFMH-!v z{o^^S$A&>bM69!qupHOn;1Q6p(m4pPSWUMy*Sn{ME|Ozo5TPJlcK?F<3Bug#%bqPV ziHuA94C<{0^N=p9O8ZK9TM}6!3s!m`LWmFgevYGyi=C#0uV$+)SF64s(lnoxkcuyD zF7(w~9i}8o3QEnk5Xif|*^JQJ1!p*AEWGEYbcc?G21oxG93FC4khwNJd;vF(pZWa( z&$C{*n0$P-Tlr>UB9XyDRC==ikIOFRedmrek3ZuMk_MnZEyJMbQ5*XFkiYfB|1ire zdR)D6uB_62uA8pHl-A~y)*2kFaa_cFBz~MM@X_G+kmkU!DTD$r71|Xd_S!qTXt>$q zBK;JkF+wT5(dvM}g}u)887H-8#KBSD#7eMS$(%p5HPuU(wa_Ef z`H7!yN?2U;-RJ$TvC1#Ff7-iTK{vD5Pc$45ne>KRy!bh|?XZEXO@j_8+!R-LP$%x( zUyU#m*vAt)lflJ_&Y>b_G$ynAYmtc&YluN9>*ow!v{>NT5P|#qO+_k9(uadydbp(? z1qrM=L{!s$MW_D99q$=ro)-GQZ;=&2y ztdJW8Q7Qwe`Nyo1GNu$E?*y&TaE_5O5b~Sddt2tTZ#PWk)qYGp6J#qR$a{6!rUMoh z_OUDBbrt=aSRyPnZ{?eXg?IzxAYs5czA~e1HlQSdSeBJ#gg-Sv&4jf|eSS_0$xo_Y zPFErbE|JXg6XW$xT$VDQakzJCQ>~mq+@HVtx&>Wtkt1F_p60hLY&FXGC(~X?Q;4@@yxWP{sCI{=*mFqg(3SCtUop4^YfP zRh0OuJm~a#o$Z0;O8cVRj$D|M+Uq2c0Z*&|V$~{r(kfl%n-R+;GR;{z->b zpbx(zuB?oD14U>rVkU;+U& z|2J8S(R311It5S1)136hWz+v8g_P+}@$5C94`&2Gc*F0(e)Gb`yxCbnE_ z_*KXN19u&>gbIDnfQkg6Z}9Mvj9ZwHLTtN+OBrBfkR$XX)Htqm*p1CaT!I6O_NOf#OSCI z5d04nf`+O^q>%t24AF$7gftnGhKE{=2(ko}PBTAz0>vRNC;Mqnfma0_J^FOFP|P7C zH}f-Hs|z0jQ+wnIAb?K-E0!0+ulmzL%X$M08=+mkazeJ9fOLT3m2Cch1gy&c69RU( zQf22XBiS{Hrn-C!(!Ksv*dq$EPT}K%M&VHEggqbXU!`hNb^ix?>#CLbk1Nx0VeDtd zr$pg^Mhiw3QCD{<<%5825C6oc!EPg}Y6bfq$Wi={K;H*)8XfmV?^oZc&OgRr?qYgk zXelHP7_?-sP-qgn(>|IZIB_#7DDWj)NX!SIhC5w!>6* z^YH~y=u_KJd>-j=i4xe9R2)cuW4s?u)_temXGCWeZn~tDH?|%amHvSr*3XN-xdr&= z6M*upzY~%_OT?sFpw?GQ;{pIKr;e?^dX40 z@t&Yms;C@+45yMlzLfap&SP^*?JX*x%XX&Dh4Aw)VoK10)K34VkrXNYqLgF`oQ%cj z*qKAeki@Lbtlf~8ITYqPAblLSA8JQ4J5H#AQJo3YAtbG|X{4m4H?^$g&-2hdV8ZP{ zpe-|$|Q3;i^x3^ zw*Ag-cSJ{Bg4x>f#n<$WO){N4souurhLx{P+k&$^gGc0N!1}PgM)=utJQwSU$6%vX z-)T&*Zyx|r%&q~lz)Pxir?v1`@W=X)sPP-z!xLwAY7eh99dxiWjdk>cNk2^ZcZ~;a zVsLCqzbTH4EK1&at@bb3SwWMKM5)4{GeawpxRTy{I?F+SRKM?FZgy>3Fh<=R0- zk_;Zu?AUoE8{I&_Uxj@RgKOTH)?Tp3MB#gEM3vwTjH-Am#R>7L?=^BhNtNj*_$nzG z85gDx=#XLIhzHhLH^I&{v5;No<1Hx1z=v-0o5hT$8sp{Bwi|~n{=mV8mkI&_oFrCoR> zFA+;G699rL@u=fvY)Jmo#La_W%I|iv&T$}W2cW|MC2Fkx+=l3 z`3MS&mr~E#r(7^mOmnS`6La9hi0k4pvCodFhiGdGL5%>qd1Y?Lxy$?|jrcnM5D1m6 zpEsHZL0;GYy%pD&d;pVP--r>|nz{qUnMpa2ATs&TeW!CuW`q40rr#OGs48yBuc$9G zZywt#ggLdNEYqs{L%gcNieYG}R#bpo1~(*8s}uSvK>nDTh1?d_%+b10hFgWSAosTX$qx3%)8!aTaOEOrLG@D8sz@_F-1X zjw@HDMc|uW>4;)yx<7k7cUNHMX4PIQ6V{b3YC+g-+RM=y@?{*tWCkV{zs>5~r1-(s z0a==vL^cgT=F6CDhy-MD^^^*Br?lroVwAy>G^yk3(f6J6FqYJ%M6o|ujbuP6BV|uj zdJJt}eEwTp)p@S%(6Q^rRA^}ePBU~}he8Z^_y0=n1^cIChgkKug!86*#~p}7?`joR zq{W}Wx4=8n7{A$R2VJMmf#^2Zg)hU{o%f^?A|Ab+!7e&5_3XXs0*=dd9^+!#BWLs4 zA!&V{K$mf@GK!L=`4eLEaV?(zFer=b)mKg{x6h&qB7W`g|(?Mwdp6zY}`TkES0pW|{L zJPD%LQ$^nC>NAosMw4#f)}3M3o*$o4eR#fq!VQEw8E%-`w((tZ{V@naT_3SDVA~Es z9~W>tB*OTICN11t=exmex53?KePA?}M&P*hI+;=DtTh%-PkvB317RcFK`|rA7EWw~ zFZV8CQ3nG1Gr!vMeEDzKXzxHj)o2>e(6Lemwyq%4Lr%7cqi0h=UuAm^5C%OYtdU{X zKjmD2J1(&@3-Re;@F?m*y_>U{H11~(jf3woF_FqMr7Nx7MIFQ5wcHbCHs$5^ zn7)r5s;U@0QEt3LCUz2sqSmVxW^jYLF@w}Hi&M)5P$o*3Y@k0POXt6l!Qs;v^ z7KDglGvx!Hg1*b^iD9&&5M72YU#Z#j9bH(u#0i8!*YjL=^yE1wg z&5bum{r%=oWM!`9$u5DwK;m!yB!q7pVx)l|0Au1}W<>T{<=fqu3 z9;CPvW&!er7~{rl%W6uf#(-OK|AjF<8VwVDd)6;Zp&Dku_w(l_rBV%3H?K^ePK>V3 zLeur^03Z;`IT!H9EPIl!^X-krpgFg&xA*?hA!A(S_epNC8jHqnZ6Y$FLhWDf9y3j? z3N~0tN6K^Nipd-z0+CJWHjXtgyJ_40?G-u|Uw$r}@DQVigCbcNhX`|BW8>pB81Rw% z&o3y)WP^g}(Wqma=4^R89w5D?=Mu}=n60v{9b;CpdiOhV6;1)rd|{Pe_LOr>2jntd z_f4juik5;OVJ;L^b?6CoU3&|TjwG$Q|FV8wli%JQMwUl1;^7aBi6o`iI4Uzfb(vu0 z|F8eoWdGMuD1ySmN>aw9{C_lL|G%89=m0YSi@-6&;-M}hqe>adiEu&CPU<=?8$<}Z z?j75-NZE6+m4b&g+CvzMF4f@~W0Wem2bAbZEJGfWAO!u_eQjuvEz(HojW%|YW1u*P z0QAU;$!Zn1kUcC=u(0&>J6uzvX^R+2mVPozd}Ul0wAtCgje#Fai-yeEbld|{KBU95 zvto6}M4C}E0&CSRGXj&Ys-{ML)*(6h3T@wB-{U)>b>CP{qk=gg5PY>B`XHko-1Q!i zOk-+i$3x(*?*Ie0Y^1ldv*U#ZnKro5vXDPmCnwS&+oVJ)-l@=3o!Aj!05Up^faaPVQ%aa)Wtdc$s1AX5NSVV%A zG>X%koby`A*|g=d=fzV6MSH+X;<5`Mdr>zH~FAt`$0x!cqy zv9aS@B{YQ3N=p89sPw?(B&thG?J@#&58Fi||KQGEQ8?YUPGM$>Gn(Z!ZTRlkxKTtw zMt@lH2cZg~E9q+z!jNiX(!3Zb=YiB$DA*(3JWMSJ{Qs0RoHBdCS3heMTi&z?pRJ_|LsPho zpqu2-n<9}>ULUET9UoRtVPe@9{ssCPg(E(Q3v1k|B*ussvho-)^-qEs?{#~~*z&8JxIS;s z0B87HyTi62f4_Gg7m;uU>2Up8m+7C830%r#NAg*(+5FPHzZ~;`u+2_-l^!^d$@aSl zMzV#5y_j`x4KjK#e1XrZ43u&gzEjk&Zz%do;TCqnMaRY#$7S9@9984lrITWL?l22S zb5bvpEKLODs>bBA0}a=eDEt8>eXUk29`N}-_pc_g>;XlC`wtJ!$ z0E7NxTPCwr+;k`?Gyz2!$uFyqD|l0a)6L9YKU&$hf^>bg!Uc8A^{8)uQV8X~Tpo1-8~`LUK7APWD*_A8teohGvRwAM27p&7bfLyI|+9#Nl`bN_K64T*Qp#muP)fg&`4oBb~kbkH!89wyloB4U!GW9^3pP&OFajY+b+mvVMsq1Uh84cj;P{K!+Cv%Z>FL6CIqt z7|e}L`>__jq-;%ulP)*~1(+{@&XzAJaoO^nv2en?v4=d-P_sU81U)jNKs}EaK z9PVwrKYXo}SiU9g@XeeK?2uzdi0wshdYn2KYT5q%X819~v=X@dL(6>K)scP!a|CuK zIug~94IHQ!?iug{sh^en*#Va1=Zn&{JS$+7mxM@;yy9ko!YAv)d4=QQjic;hn~UPn zg5BytB3oHV5Sjv3Yka8_fQ!a1zPycCK)yrqQ7@~(lR74EC9TU9yDB_|*|iMx@y{}T zG6~M_=^gmtd0?EV7)fB#FrIC_s7E) zvtzCs+Rj-9BpiOP*coZ<#LWbmvN57U%sAK%HW;6#8#_q=Hst+H9Y zM2elGz|pyKrAVgJU?3N)eydZp+&w6_zEN-Km6BnUUvX8(>$^LR(vfk&QurVU)6EMB zj}8!=Dn#7Gm;N_n^OG)VHbyMhIX0{et;t|Wj+(h0#&QCrVYV!WQe8|`PSgO_eFD2G2~kRKb^H( zO&rogGKtHBVU@za&k)i?HWTdVMPI5P500~I5#ssY-3Ppg2o18-Y3ks?SX{T(XjY#? z0q*jpKl4owL6CkKY*ukX)><{{_nYk1xh%^7k!aWf&4b(pbQZe9zdz$I<~4 zI#0=ycL*06ZhS_Ugm{{Y(IzKJ^d#AZH&-JfbL)F0Tnu86Qm992r5ra;w5pahW~8&r z@<@W#<1Z6 zcW>-m>C!?2$s@wUDrHlW3qGTy>2HA9xrDiM8#K5RQ3zYjb3eSgFKE&8TTX(j2By8S z4-OAE@X$WbFOp98=BAsEJ&oq)RQy)qR3FM{e#GAM5SbjYY?U#`=|mT~O+0hC8F?tDX+x#as$V26Cw|dQn;C;GqwlQLF{>Fk;<1flm2g<-+L5&<7C%g%u0xn ze6gj?@AHER{bKg9K42q>N=Hc-DvfEldXfNx~B&<_6=+O>5(Ja_KKZW54im7|AH97#&vh3*d+6Eo)u)X4iDjbe1 z`+rUr`TLP5@1fv_a!PWZqge_f`jPY=B{5!V*SEpue5z z{}Fgq$9L((LCgld^3QkyS0Nl75w&g#N}2V7ioWmJo4;2I6w*|;*S)8mKv|yr%p*qt zn+GQhA4LE#aL~N8XdZ+(&n|_0C9f4_Cfa?wl{aXDNLtUv3 zB-UcT?3H+nWH{JXP#kJx62JIwkp$;Py#Q&P7P}v7PtamN);JSzUItT02g1 zLX{Z*0cwLT_d@1U2L8}AXjprajpb|FL1Y*@%sD6~18lEbp{s`c2SOhwomciiX#Ge% zWrHKH8+ri~WS#!!6wu}9MUuG9bHfU6hLQq|M{;GslnvAd3@^mdDdph533^DjB=yPa zm`Xu55G17iKhK(qUoM=*#f|Ih@4Ai+LxXj|+&`<5>x zd)a^!d2f3ss^j2ra;dNvab#cHR=c_{*Bt5RK$W#EqMJLS6pK|aQ(Jol40ab#wsu7G zkO7t8cc~b>4i|Tpn5kGVA7}RcPUlH-{2WdOpGD#iIK6t3zW%ec+?O;R1+(PhnZ=*x znhrI^iKv@v$}SWD$n2YyIjo(ixn|0~UT6PhS>10VLi^_@S*Ff)b*_FI?F>1Vq-KNIbox?Pe zQ{n!*h%0xatd=dr;Byidp!Nn{(v6dYDGjEE<@R^H;4@%$-x~g8$Vzw_3)eIjld9| zJ%j<1VQHi!Q8=q^B=d97%l*2)_pBuGeo37*>#St>W|HmsRN#{M5`{ss7I95c$b8X_ySI~|^l#Q25Z S&eY;N2P~|OBf8$oH}T&c3v8MI literal 0 HcmV?d00001 diff --git a/static/assets/send-payment.png b/static/assets/send-payment.png new file mode 100644 index 0000000000000000000000000000000000000000..6b518dbb61f276b3474b418029df8a3ee7f38fb7 GIT binary patch literal 195797 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

PBP#Y&)A>`v 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�|iVbM>jrs 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

TE@+uPiCYe;c!~^ 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 Date: Mon, 24 Jul 2023 13:31:32 -0500 Subject: [PATCH 09/46] Adding some install steps to app tutorial, and adding a page to explain the contacts list components and store --- .../_category_.json | 12 +- .../account-creation.mdx | 14 +- .../contacts-list.mdx | 155 +++++++++++ .../example-application-tutorial/overview.mdx | 245 ++++++++++++++++-- package.json | 1 + src/theme/prism-include-languages.js | 20 ++ yarn.lock | 5 + 7 files changed, 425 insertions(+), 27 deletions(-) create mode 100644 docs/building-apps/example-application-tutorial/contacts-list.mdx create mode 100644 src/theme/prism-include-languages.js diff --git a/docs/building-apps/example-application-tutorial/_category_.json b/docs/building-apps/example-application-tutorial/_category_.json index 966c7f9e0..9a592308a 100644 --- a/docs/building-apps/example-application-tutorial/_category_.json +++ b/docs/building-apps/example-application-tutorial/_category_.json @@ -1,7 +1,7 @@ { - "position": 55, - "label": "Example Application Tutorial", - "link": { - "type": "generated-index" - } - } \ No newline at end of file + "position": 55, + "label": "Example Application Tutorial", + "link": { + "type": "generated-index" + } +} diff --git a/docs/building-apps/example-application-tutorial/account-creation.mdx b/docs/building-apps/example-application-tutorial/account-creation.mdx index a79797a89..178b17481 100644 --- a/docs/building-apps/example-application-tutorial/account-creation.mdx +++ b/docs/building-apps/example-application-tutorial/account-creation.mdx @@ -5,20 +5,24 @@ sidebar_position: 20 Accounts are the central data structure in Stellar and can only exist with a valid keypair (a public and secret key) and the required minimum balance of XLM. Read more in the [Accounts section](../../fundamentals-and-concepts/stellar-data-structures/accounts). -To start, we’ll have our user create an account. In BasicPay, the signup page will display a randomized public and secret keypair that the user can select with the option to choose a new set if preferred. +To start, we'll have our user create an account. In BasicPay, the signup page will display a randomized public and secret keypair that the user can select with the option to choose a new set if preferred. :::info -Since we are building a [non-custodial application](../application-design-considerations#non-custodial-service), the secret key will only ever live in the browser. It will never be shared with the server or anybody else. +Since we are building a [non-custodial application], the encrypted secret key will only ever live in the browser. It will never be shared with a server or anybody else. ::: ![public and private keys](/assets/public-and-private-keys.png) -Next, we’ll trigger the user to submit a pincode to encrypt their secret key before it gets saved to their browser’s `localStorage` (this is handled by the SDK). The user will need to remember their pincode for future logins and to submit transactions. +Next, we'll trigger the user to submit a pincode to encrypt their secret key before it gets saved to their browser's `localStorage` (this is handled by the [`js-stellar-wallets` SDK]). The user will need to remember their pincode for future logins and to submit transactions. -With BasicPay, when the user clicks the “Signup” button, they will be asked to confirm their pincode. When they do, the `create_account` operation is triggered, and the user’s account is automatically funded with XLM for the minimum balance (starting with 10,000 XLM). +With BasicPay, when the user clicks the “Signup” button, they will be asked to confirm their pincode. When they do, the `create_account` operation is triggered, and the user's account is automatically funded with XLM for the minimum balance (starting with 10,000 XLM). ![funded account](/assets/funded-account.png) -When you’re ready to move the application to Pubnet, accounts will need to be funded with real XLM. This is something the application can cover itself by depositing XLM into the user’s account (as we did with BasicPay on Testnet), with the use of [sponsored reserves](../../encyclopedia/sponsored-reserves), or the user can cover the required balance with their own XLM. +When you're ready to move the application to Pubnet, accounts will need to be funded with real XLM. This is something the application can cover itself by depositing XLM into the user's account (this is how we did it with BasicPay on Testnet, using Friendbot), with the use of [sponsored reserves], or the user can cover the required balance with their own XLM. + +[non-custodial application]: <../application-design-considerations#non-custodial-service> +[`js-stellar-wallets` SDK]: +[sponsored reserves]: <../../encyclopedia/sponsored-reserves> diff --git a/docs/building-apps/example-application-tutorial/contacts-list.mdx b/docs/building-apps/example-application-tutorial/contacts-list.mdx new file mode 100644 index 000000000..c0e2ad007 --- /dev/null +++ b/docs/building-apps/example-application-tutorial/contacts-list.mdx @@ -0,0 +1,155 @@ +--- +title: Contacts List +sidebar_position: 15 +--- + +A central feature for _BasicPay_ is a list of contacts that contains a user's name, and a Stellar address associated with it. While this particular function doesn't do a _tremendous_ amount of Stellar-related functionality, it makes sense for it to be the first thing we discuss. Understanding this simple component will set a good foundation for you to understand some of the more advanced components later on. + +## Creating a `localStorage` store + +As with the rest of our user-data, the contacts list will live in the browser's `localStorage`. We are using the [`svelt-local-storage-store` package] to facilitate this. We create a Svelte `store` to hold the data, and add a few custom functions to manage the list: `empty`, `remove`, `add`, `favorite`, and `lookup`. + +:::note + +This tutorial code is simplified for display here. The code is fully typed, documented, and commented in the [source code repository]. + +::: + +```js file="/src/lib/stores/contactsStore.js" +import { v4 as uuidv4 } from 'uuid' +import { persisted } from 'svelte-local-storage-store' +import { StrKey } from 'stellar-sdk' +import { error } from '@sveltejs/kit' +import { get } from 'svelte/store' + +// We are wrapping this store in its own function which will allow us to write +// and customize our own store functions to maintain consistent behavior +// wherever the actions need to take place. +function createContactsStore() { + const { subscribe, set, update } = persisted('bpa:contactList', []) + + return { + subscribe, + + // Erases all contact entries from the list and creates a new, empty contact list. + empty: () => set([]), + + // Removes the specified contact entry from the list. + remove: (id) => update((list) => list.filter((contact) => contact.id !== id)), + + // Adds a new contact entry to the list with the provided details. + add: (contact) => + update((list) => { + if (StrKey.isValidEd25519PublicKey(contact.address)) { + return [...list, { ...contact, id: uuidv4() }] + } else { + throw error(400, { message: 'invalid public key' }) + } + }), + + // Toggles the "favorite" field on the specified contact. + favorite: (id) => + update((list) => { + const i = list.findIndex((contact) => contact.id === id) + if (i >= 0) { + list[i].favorite = !list[i].favorite + } + return list + }), + + // Searches the contact list for an entry with the specified address. + lookup: (address) => { + let list = get(contacts) + let i = list.findIndex((contact) => contact.address === address) + if (i >= 0) { + return list[i].name + } else { + return false + } + }, + } +} + +// We export `contacts` as the variable that can be used to interact with the contacts store. +export const contacts = createContactsStore() +``` + +Source: + +## Accessing the `localStore` data + +The `contacts` store is now exported form this file, and can be accessed and used inside a Svelte page or component. Here is how we've implemented a "favorite contacts" component for displaying on the main BasicPay dashboard. + +:::note + +In our `*.svelte` component files, we will not dive too deeply into the HTML markup outside of the ` + +

Favorite Contacts

+ + + + + + + + + {#if favoriteContacts} + + {#each favoriteContacts as contact (contact.id)} + + + + + + + {/each} + + {/if} +
FavoriteNameAddress
+ contacts.favorite(contact.id)} + /> + +
+
+
+ Avatar Tailwind CSS Component +
+
+
+
{contact.name}
+
+
+
+ + + +
+``` + +Source: + +[`svelt-local-storage-store` package]: +[source code repository]: diff --git a/docs/building-apps/example-application-tutorial/overview.mdx b/docs/building-apps/example-application-tutorial/overview.mdx index 3697ee95e..4ffd055b5 100644 --- a/docs/building-apps/example-application-tutorial/overview.mdx +++ b/docs/building-apps/example-application-tutorial/overview.mdx @@ -3,13 +3,13 @@ title: Overview sidebar_position: 10 --- -In this tutorial, we’ll walk through the steps needed to build a basic payment application on Stellar’s Testnet. After this tutorial, you should have a good understanding of the fundamental Stellar concepts and a solid base for iterative development. +In this tutorial, we'll walk through the steps needed to build a basic payment application on Stellar's Testnet. After this tutorial, you should have a good understanding of the fundamental Stellar concepts and a solid base for iterative development. -For this tutorial, we’ll walk through the steps as we build a sample application we’ve called [BasicPay](https://basicpay.pages.dev), which will be used to showcase various features. +For this tutorial, we'll walk through the steps as we build a sample application we've called [BasicPay], which will be used to showcase various features. :::caution -**Although BasicPay is a full-fledged application on Stellar’s Testnet, it has been built solely to showcase Stellar functionality for the educational purposes of this tutorial, not to be copied, pasted, and used on Mainnet.** +**Although BasicPay is a full-fledged application on Stellar's Testnet, it has been built solely to showcase Stellar functionality for the educational purposes of this tutorial, not to be copied, pasted, and used on Mainnet.** ::: @@ -17,23 +17,236 @@ For this tutorial, we’ll walk through the steps as we build a sample applicati ### Project requirements -To build a basic Stellar application, you’ll need: +To build a basic Stellar application, you'll need: -- Application framework (for BasicPay, we use SvelteKit opting for JavaScript with JSDoc typing, and we used [svelte-add](https://github.com/svelte-add/svelte-add) to get our project started) -- Frontend framework (for BasicPay, we’re using Daisy UI to simplify the use of Tailwind CSS) -- A way to interact with the Stellar network (for BasicPay, we use the [js-stellar-sdk](https://github.com/stellar/js-stellar-sdk), but you could use traditional fetch requests) -- A way to interact with the user’s keypair (for BasicPay, we are using the [js-stellar-wallets SDK](https://github.com/stellar/js-stellar-wallets), but you can opt to use an existing wallet) +- Application framework (for BasicPay, we use [SvelteKit] opting for JavaScript with JSDoc typing). SvelteKit is quite flexible, although we are _mainly_ using it for its routing capabilities. We could use it for quite a bit more, but we've worked to minimize how much of a "SvelteKit tutorial" this project is. +- Frontend framework (for BasicPay, we're using [DaisyUI] to simplify the use of [Tailwind CSS]) +- A way to interact with the Stellar network (for BasicPay, we use the [`js-stellar-sdk`], but you could use traditional fetch requests). The [`js-stellar-sdk`] is also used for building transactions to submit to the Stellar network. +- A way to interact with the user's keypair (for BasicPay, we are using the [`js-stellar-wallets` SDK], but you can opt to use an existing wallet) -While we are using the above components to construct our application, we have done our best to build it in such a way that dependency on any one of these things is minimized. Ideally, you should be able to use the JavaScript code we’ve written and plug it into any other framework you’d like with minimal effort. +While we are using the above components to construct our application, we have done our best to build it in such a way that dependency on any one of these things is minimized. Ideally, you should be able to use the JavaScript code we've written and plug it into any other framework you'd like with minimal effort. -We’ve made the following choices during the development of this application that you may need to consider as you follow this project: +We've made the following choices during the development of this application that you may need to consider as you follow this project: -- We’ve designed this app with a desktop in mind. -- We’re using a dark mode theme. No light mode is available, so deal with it. -- This is written as a client-side application. No server-side actions actually take place. -- We’re deploying this as a static site with Cloudflare pages. +- We've designed this app with a desktop in mind. For the most part, the app is responsive to various screen sizes, but we have _chosen_ not to go out of our way to prioritize the mobile user experience. +- We have enabled the default DaisyUI "light" and "dark" themes, which should switch with the preferences of your device. There is no toggle switch enabled, though. +- This is written as a client-side application. No server-side actions actually take place. If you are building an application with a backend and frontend, you will need to consider carefully which information lives where, and especially so when a user's secret key is concerned. +- We're deploying this as a static "single-page application" with [Cloudflare Pages]. Your own deployment decisions will have an impact on your configuration and build process. +- 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. +- We have not implemented _any_ automated testing. You'll probably want some for your application. ### Dev helpers -- [Friendbot](https://friendbot.stellar.org/): a bot that funds accounts with 10,000 fake XLM on Stellar’s Testnet -- [Testnet toml file](https://testanchor.stellar.org/.well-known/stellar.toml) +- [Stellar Laboratory]: An experimental playground to interact with the Stellar network +- [Friendbot]: a bot that funds accounts with 10,000 fake XLM on Stellar's Testnet +- [Testnet toml file]: An example `stellar.toml` file that demonstrates what information an anchor might publish +- [BasicPay's "Dev Helpers" Page]: If you're _using_ the BasicPay application, we've created a few + +## Getting started + +Here are the steps we've taken in order to build BasicPay. Feel free to be inspired and customize these directions as you may need. The entire [BasicPay codebase] is freely open and available on GitHub for reference. + +:::note + +This part of the tutorial will need a large helping of "your mileage may vary." We will outline what steps we've taken for our deployment situation, but you will want to review what options are needed for your environment(s). + +::: + +### Install frameworks + +The first thing we'll need to do is create a SvelteKit app, using `npm`, we are using v18.x of nodejs. + +```bash +npm create svelte@latest my-basic-payment-app +``` + +This will walk you through the SvelteKit creation process, asking you about all the various options. We've chosen the following options: + +- **Which Svelte app template?** Skeleton project +- **Are you type checking with TypeScript?** Yes, using JavaScript with JSDoc comments +- **Select additional options** Add ESLint for code linting; Add Prettier for code formatting + +After this process, the scaffolding for your application will live inside the `my-basic-payment-app` directory. You can `cd` into that directory and add some UI dependencies. + +```bash +cd my-basic-payment-app +yarn add -D svelte-preprocess tailwindcss autoprefixer postcss @sveltejs/adapter-static \ + @tailwindcss/typography \ + daisyui svelte-feather-icons +``` + +Before we configure anything, we'll need to generate our `tailwind.config.js` and `postcss.config.js` files. + +```bash +npx tailwindcss init -p +``` + +Now, we will require a bit of configuration to make all those components work together. First, modify your `svelte.config.js` file: + +```js title="/svelte.config.js" +// highlight-start +import preprocess from 'svelte-preprocess' +import adapter from '@sveltejs/adapter-static' +// highlight-end + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + kit: { + // Note: Your `dapter` configuration may need customizations depending + // on how you are building and deploying your application. + // highlight-start + adapter: adapter({ + fallback: 'index.html', + }), + // highlight-end + }, + // highlight-start + preprocess: [ + preprocess({ + postcss: true, + }), + ], + // highlight-end +} + +export default config +``` + +Next, you can configure the `tailwind.config.js` file. + +1. We import the `daisyui` and `typography` plugins +2. We configure our content paths (you may need to modify these values, depending on your project structure) +3. We add the `daisyui` plugin **after** any officialy `@tailwindcss` plugins (only `typography` in our example) + +```js title="/tailwind.config.js" +// highlight-start +const daisyui = require('daisyui') +const typography = require('@tailwindcss/typography') +// highlight-end + +/** @type {import('tailwindcss').Config} */ +export default { + content: [ + // highlight-start + './src/routes/**/*.{html,js,svelte,ts}', + './src/routes/**/**/*.{html,js,svelte,ts}', + './src/lib/components/**/*.{html,js,svelte,ts}', + // highlight-end + ], + // highlight-next-line + plugins: [typography, daisyui], +} +``` + +Add your tailwind directives to your app's main CSS file. + +```css title="/src/app.postcss" +@tailwind base; +@tailwind components; +@tailwind utilities; +``` + +Then import the CSS file into your base SvelteKit layout. (You may need to create this file.) + +```svelte title="/src/routes/+layout.svelte" + + + +``` + +We also created a `/src/routes/+layout.js` file to configure our application as _only_ client-side. This means the app will be delivered to the client as unrendered HTML and JavaScript. + +```js file="/src/routes/+layout.js" +// Disable pre-rendering of pages during build-time +export const prerender = false +// Disable server-side rendering +export const ssr = false +``` + +Your SvelteKit project is now configured and ready to run! + +```bash +yarn run dev +``` + +### Stellar dependencies + +In order to work with the Stellar network, datastructures, and locally stored Keypairs, we're going to install and configure a few more dependencies. + +```bash +# Stellar SDKs +yarn add -D stellar-sdk @stellar/wallet-sdk +# We will need some polyfills to make things available client-side +yarn add -D @esbuild-plugins/node-globals-polyfill @esbuild-plugins/node-modules-polyfill \ + path @rollup/plugin-inject buffer svelte-local-storage-store uuid +``` + +We will use a `window.js` file to inject Buffer into our client-side code, since that's required by some parts of the `stllar-sdk`. + +```js title="/src/lib/window.js" +import { browser } from '$app/environment' +import { Buffer } from 'buffer' + +if (browser) { + window.Buffer = Buffer +} else { + globalThis.Buffer = Buffer + globalThis.window = {} +} +export default globalThis +``` + +The actual "injection" takes place in our `vite.config.js` file. + +```js title="/vite.config.js" +import { sveltekit } from '@sveltejs/kit/vite' +import { defineConfig } from 'vite' +import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill' +import inject from '@rollup/plugin-inject' +import path from 'path' + +export default defineConfig({ + plugins: [sveltekit()], + optimizeDeps: { + esbuildOptions: { + define: { + global: 'globalThis', + }, + plugins: [ + NodeGlobalsPolyfillPlugin({ + buffer: true, + }), + ], + }, + }, + build: { + rollupOptions: { + plugins: [ + inject({ + window: path.resolve('src/lib/window.js'), + }), + ], + }, + }, + ssr: { + noExternal: ['@stellar/wallet-sdk', '@albedo-link/intent'], + }, +}) +``` + +That _should_ take care of everything you need! If you've followed these steps, you now have running client-side-only application that's ready to build out and interact with the Stellar network! Way to go!! + +[BasicPay]: +[SvelteKit]: +[DaisyUI]: +[Tailwind CSS]: +[`js-stellar-sdk`]: +[`js-stellar-wallets` SDK]: +[Cloudflare Pages]: +[Stellar Laboratory]: +[Friendbot]: +[Testnet toml file]: +[BasicPay codebase]: diff --git a/package.json b/package.json index e0b526507..61c5dd151 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "mdx-mermaid": "^1.3.2", "mermaid": "^8.11.5", "prism-react-renderer": "^1.3.5", + "prism-svelte": "^0.5.0", "react": "^17.0.2", "react-dom": "^17.0.2", "redocusaurus": "^1.4.0", diff --git a/src/theme/prism-include-languages.js b/src/theme/prism-include-languages.js new file mode 100644 index 000000000..44bf07914 --- /dev/null +++ b/src/theme/prism-include-languages.js @@ -0,0 +1,20 @@ +import siteConfig from '@generated/docusaurus.config'; +export default function prismIncludeLanguages(PrismObject) { + const { + themeConfig: {prism}, + } = siteConfig; + const {additionalLanguages} = prism; + // Prism components work on the Prism instance on the window, while prism- + // react-renderer uses its own Prism instance. We temporarily mount the + // instance onto window, import components to enhance it, then remove it to + // avoid polluting global namespace. + // You can mutate PrismObject: registering plugins, deleting languages... As + // long as you don't re-assign it + globalThis.Prism = PrismObject; + additionalLanguages.forEach((lang) => { + // eslint-disable-next-line global-require, import/no-dynamic-require + require(`prismjs/components/prism-${lang}`); + }); + require('prism-svelte') + delete globalThis.Prism; +} diff --git a/yarn.lock b/yarn.lock index 28512ed8f..12be4eaa1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10698,6 +10698,11 @@ prism-react-renderer@^1.3.1, prism-react-renderer@^1.3.5: resolved "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.3.5.tgz" integrity sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg== +prism-svelte@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/prism-svelte/-/prism-svelte-0.5.0.tgz#c4aeffeaddb179cfef213aab91ee785b66d22992" + integrity sha512-db91Bf3pRGKDPz1lAqLFSJXeW13mulUJxhycysFpfXV5MIK7RgWWK2E5aPAa71s8TCzQUXxF5JOV42/iOs6QkA== + prismjs@^1.27.0, prismjs@^1.28.0: version "1.29.0" resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz" From 215a3a1aa621776b0784e982372ce8e5b92846a0 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 24 Jul 2023 13:55:13 -0500 Subject: [PATCH 10/46] markdown formatting --- .../account-creation.mdx | 6 +- .../contacts-list.mdx | 101 +++++------ .../example-application-tutorial/overview.mdx | 158 +++++++++--------- 3 files changed, 133 insertions(+), 132 deletions(-) diff --git a/docs/building-apps/example-application-tutorial/account-creation.mdx b/docs/building-apps/example-application-tutorial/account-creation.mdx index 178b17481..44db5d7b8 100644 --- a/docs/building-apps/example-application-tutorial/account-creation.mdx +++ b/docs/building-apps/example-application-tutorial/account-creation.mdx @@ -23,6 +23,6 @@ With BasicPay, when the user clicks the “Signup” button, they will be asked When you're ready to move the application to Pubnet, accounts will need to be funded with real XLM. This is something the application can cover itself by depositing XLM into the user's account (this is how we did it with BasicPay on Testnet, using Friendbot), with the use of [sponsored reserves], or the user can cover the required balance with their own XLM. -[non-custodial application]: <../application-design-considerations#non-custodial-service> -[`js-stellar-wallets` SDK]: -[sponsored reserves]: <../../encyclopedia/sponsored-reserves> +[non-custodial application]: ../application-design-considerations#non-custodial-service +[`js-stellar-wallets` sdk]: https://github.com/stellar/js-stellar-wallets +[sponsored reserves]: ../../encyclopedia/sponsored-reserves diff --git a/docs/building-apps/example-application-tutorial/contacts-list.mdx b/docs/building-apps/example-application-tutorial/contacts-list.mdx index c0e2ad007..34723fc9a 100644 --- a/docs/building-apps/example-application-tutorial/contacts-list.mdx +++ b/docs/building-apps/example-application-tutorial/contacts-list.mdx @@ -16,62 +16,63 @@ This tutorial code is simplified for display here. The code is fully typed, docu ::: ```js file="/src/lib/stores/contactsStore.js" -import { v4 as uuidv4 } from 'uuid' -import { persisted } from 'svelte-local-storage-store' -import { StrKey } from 'stellar-sdk' -import { error } from '@sveltejs/kit' -import { get } from 'svelte/store' +import { v4 as uuidv4 } from "uuid"; +import { persisted } from "svelte-local-storage-store"; +import { StrKey } from "stellar-sdk"; +import { error } from "@sveltejs/kit"; +import { get } from "svelte/store"; // We are wrapping this store in its own function which will allow us to write // and customize our own store functions to maintain consistent behavior // wherever the actions need to take place. function createContactsStore() { - const { subscribe, set, update } = persisted('bpa:contactList', []) - - return { - subscribe, - - // Erases all contact entries from the list and creates a new, empty contact list. - empty: () => set([]), - - // Removes the specified contact entry from the list. - remove: (id) => update((list) => list.filter((contact) => contact.id !== id)), - - // Adds a new contact entry to the list with the provided details. - add: (contact) => - update((list) => { - if (StrKey.isValidEd25519PublicKey(contact.address)) { - return [...list, { ...contact, id: uuidv4() }] - } else { - throw error(400, { message: 'invalid public key' }) - } - }), - - // Toggles the "favorite" field on the specified contact. - favorite: (id) => - update((list) => { - const i = list.findIndex((contact) => contact.id === id) - if (i >= 0) { - list[i].favorite = !list[i].favorite - } - return list - }), - - // Searches the contact list for an entry with the specified address. - lookup: (address) => { - let list = get(contacts) - let i = list.findIndex((contact) => contact.address === address) - if (i >= 0) { - return list[i].name - } else { - return false - } - }, - } + const { subscribe, set, update } = persisted("bpa:contactList", []); + + return { + subscribe, + + // Erases all contact entries from the list and creates a new, empty contact list. + empty: () => set([]), + + // Removes the specified contact entry from the list. + remove: (id) => + update((list) => list.filter((contact) => contact.id !== id)), + + // Adds a new contact entry to the list with the provided details. + add: (contact) => + update((list) => { + if (StrKey.isValidEd25519PublicKey(contact.address)) { + return [...list, { ...contact, id: uuidv4() }]; + } else { + throw error(400, { message: "invalid public key" }); + } + }), + + // Toggles the "favorite" field on the specified contact. + favorite: (id) => + update((list) => { + const i = list.findIndex((contact) => contact.id === id); + if (i >= 0) { + list[i].favorite = !list[i].favorite; + } + return list; + }), + + // Searches the contact list for an entry with the specified address. + lookup: (address) => { + let list = get(contacts); + let i = list.findIndex((contact) => contact.address === address); + if (i >= 0) { + return list[i].name; + } else { + return false; + } + }, + }; } // We export `contacts` as the variable that can be used to interact with the contacts store. -export const contacts = createContactsStore() +export const contacts = createContactsStore(); ``` Source: @@ -151,5 +152,5 @@ In our `*.svelte` component files, we will not dive too deeply into the HTML mar Source: -[`svelt-local-storage-store` package]: -[source code repository]: +[`svelt-local-storage-store` package]: https://github.com/joshnuss/svelte-local-storage-store +[source code repository]: https://github.com/stellar/basic-payment-app diff --git a/docs/building-apps/example-application-tutorial/overview.mdx b/docs/building-apps/example-application-tutorial/overview.mdx index 4ffd055b5..ae86ad518 100644 --- a/docs/building-apps/example-application-tutorial/overview.mdx +++ b/docs/building-apps/example-application-tutorial/overview.mdx @@ -86,31 +86,31 @@ Now, we will require a bit of configuration to make all those components work to ```js title="/svelte.config.js" // highlight-start -import preprocess from 'svelte-preprocess' -import adapter from '@sveltejs/adapter-static' +import preprocess from "svelte-preprocess"; +import adapter from "@sveltejs/adapter-static"; // highlight-end /** @type {import('@sveltejs/kit').Config} */ const config = { - kit: { - // Note: Your `dapter` configuration may need customizations depending - // on how you are building and deploying your application. - // highlight-start - adapter: adapter({ - fallback: 'index.html', - }), - // highlight-end - }, + kit: { + // Note: Your `dapter` configuration may need customizations depending + // on how you are building and deploying your application. // highlight-start - preprocess: [ - preprocess({ - postcss: true, - }), - ], + adapter: adapter({ + fallback: "index.html", + }), // highlight-end -} - -export default config + }, + // highlight-start + preprocess: [ + preprocess({ + postcss: true, + }), + ], + // highlight-end +}; + +export default config; ``` Next, you can configure the `tailwind.config.js` file. @@ -121,22 +121,22 @@ Next, you can configure the `tailwind.config.js` file. ```js title="/tailwind.config.js" // highlight-start -const daisyui = require('daisyui') -const typography = require('@tailwindcss/typography') +const daisyui = require("daisyui"); +const typography = require("@tailwindcss/typography"); // highlight-end /** @type {import('tailwindcss').Config} */ export default { - content: [ - // highlight-start - './src/routes/**/*.{html,js,svelte,ts}', - './src/routes/**/**/*.{html,js,svelte,ts}', - './src/lib/components/**/*.{html,js,svelte,ts}', - // highlight-end - ], - // highlight-next-line - plugins: [typography, daisyui], -} + content: [ + // highlight-start + "./src/routes/**/*.{html,js,svelte,ts}", + "./src/routes/**/**/*.{html,js,svelte,ts}", + "./src/lib/components/**/*.{html,js,svelte,ts}", + // highlight-end + ], + // highlight-next-line + plugins: [typography, daisyui], +}; ``` Add your tailwind directives to your app's main CSS file. @@ -161,9 +161,9 @@ We also created a `/src/routes/+layout.js` file to configure our application as ```js file="/src/routes/+layout.js" // Disable pre-rendering of pages during build-time -export const prerender = false +export const prerender = false; // Disable server-side rendering -export const ssr = false +export const ssr = false; ``` Your SvelteKit project is now configured and ready to run! @@ -187,66 +187,66 @@ yarn add -D @esbuild-plugins/node-globals-polyfill @esbuild-plugins/node-modules We will use a `window.js` file to inject Buffer into our client-side code, since that's required by some parts of the `stllar-sdk`. ```js title="/src/lib/window.js" -import { browser } from '$app/environment' -import { Buffer } from 'buffer' +import { browser } from "$app/environment"; +import { Buffer } from "buffer"; if (browser) { - window.Buffer = Buffer + window.Buffer = Buffer; } else { - globalThis.Buffer = Buffer - globalThis.window = {} + globalThis.Buffer = Buffer; + globalThis.window = {}; } -export default globalThis +export default globalThis; ``` The actual "injection" takes place in our `vite.config.js` file. ```js title="/vite.config.js" -import { sveltekit } from '@sveltejs/kit/vite' -import { defineConfig } from 'vite' -import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill' -import inject from '@rollup/plugin-inject' -import path from 'path' +import { sveltekit } from "@sveltejs/kit/vite"; +import { defineConfig } from "vite"; +import { NodeGlobalsPolyfillPlugin } from "@esbuild-plugins/node-globals-polyfill"; +import inject from "@rollup/plugin-inject"; +import path from "path"; export default defineConfig({ - plugins: [sveltekit()], - optimizeDeps: { - esbuildOptions: { - define: { - global: 'globalThis', - }, - plugins: [ - NodeGlobalsPolyfillPlugin({ - buffer: true, - }), - ], - }, - }, - build: { - rollupOptions: { - plugins: [ - inject({ - window: path.resolve('src/lib/window.js'), - }), - ], - }, + plugins: [sveltekit()], + optimizeDeps: { + esbuildOptions: { + define: { + global: "globalThis", + }, + plugins: [ + NodeGlobalsPolyfillPlugin({ + buffer: true, + }), + ], }, - ssr: { - noExternal: ['@stellar/wallet-sdk', '@albedo-link/intent'], + }, + build: { + rollupOptions: { + plugins: [ + inject({ + window: path.resolve("src/lib/window.js"), + }), + ], }, -}) + }, + ssr: { + noExternal: ["@stellar/wallet-sdk", "@albedo-link/intent"], + }, +}); ``` That _should_ take care of everything you need! If you've followed these steps, you now have running client-side-only application that's ready to build out and interact with the Stellar network! Way to go!! -[BasicPay]: -[SvelteKit]: -[DaisyUI]: -[Tailwind CSS]: -[`js-stellar-sdk`]: -[`js-stellar-wallets` SDK]: -[Cloudflare Pages]: -[Stellar Laboratory]: -[Friendbot]: -[Testnet toml file]: -[BasicPay codebase]: +[basicpay]: https://basicpay.pages.dev +[sveltekit]: https://kit.svelte.dev +[daisyui]: https://daisyui.com +[tailwind css]: https://tailwindcss.com +[`js-stellar-sdk`]: https://github.com/stellar/js-stellar-sdk +[`js-stellar-wallets` sdk]: https://github.com/stellar/js-stellar-wallets +[cloudflare pages]: https://pages.cloudflare.com/ +[stellar laboratory]: https://laboratory.stellar.org +[friendbot]: https://friendbot.stellar.org/ +[testnet toml file]: https://testanchor.stellar.org/.well-known/stellar.toml +[basicpay codebase]: https://github.com/stellar/basic-payment-app From 1a188faad2f12024003676b9af2771cf51e2f32b Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 24 Jul 2023 16:06:12 -0500 Subject: [PATCH 11/46] More progress on tutorial application steps --- .../account-creation.mdx | 167 ++++++- .../confirmation-modal.mdx | 407 ++++++++++++++++++ .../contacts-list.mdx | 31 +- .../example-application-tutorial/overview.mdx | 26 +- docusaurus.config.js | 4 +- package.json | 1 + yarn.lock | 19 + 7 files changed, 636 insertions(+), 19 deletions(-) create mode 100644 docs/building-apps/example-application-tutorial/confirmation-modal.mdx diff --git a/docs/building-apps/example-application-tutorial/account-creation.mdx b/docs/building-apps/example-application-tutorial/account-creation.mdx index 44db5d7b8..0f3eeacd3 100644 --- a/docs/building-apps/example-application-tutorial/account-creation.mdx +++ b/docs/building-apps/example-application-tutorial/account-creation.mdx @@ -3,7 +3,9 @@ title: Account Creation sidebar_position: 20 --- -Accounts are the central data structure in Stellar and can only exist with a valid keypair (a public and secret key) and the required minimum balance of XLM. Read more in the [Accounts section](../../fundamentals-and-concepts/stellar-data-structures/accounts). +Accounts are the central data structure in Stellar and can only exist with a valid keypair (a public and secret key) and the required minimum balance of XLM. Read more in the [Accounts section]. + +## User experience To start, we'll have our user create an account. In BasicPay, the signup page will display a randomized public and secret keypair that the user can select with the option to choose a new set if preferred. @@ -23,6 +25,169 @@ With BasicPay, when the user clicks the “Signup” button, they will be asked When you're ready to move the application to Pubnet, accounts will need to be funded with real XLM. This is something the application can cover itself by depositing XLM into the user's account (this is how we did it with BasicPay on Testnet, using Friendbot), with the use of [sponsored reserves], or the user can cover the required balance with their own XLM. +## Code implementation + +We will create a Svelte `store` to interact with our user's randomly generated keypair. The store will take advantage of some of the `js-stellar-wallets` SDK to encrypt/decrypt the keypair, as well as sign transactions. + +### Creating the `walletStore` store + +Our `walletStore` will make a few things possible throughout our application. + +1. We can "register" a keypair, which entails encrypting the keypair, storing it in the browser's storage, and keeping track of that keypair's `keyId`. +2. We can "sign" transactions, by providing the pincode to decrypt the keypair first +3. We can "confirm" the pincode is a valid one for the stored keypair (or that it matches for signups) + +```js title="/src/lib/stores/walletStore.js" +import { persisted } from "svelte-local-storage-store"; +import { KeyManager, KeyManagerPlugins, KeyType } from "@stellar/wallet-sdk"; +import { TransactionBuilder } from "stellar-sdk"; +import { error } from "@sveltejs/kit"; +import { get } from "svelte/store"; + +// We are wrapping this store in its own function which will allow us to write +// and customize our own store functions to maintain consistent behavior +// wherever the actions need to take place. +function createWalletStore() { + // Make a `persisted` store that will determine which `keyId` the + // `keyManager` should load, when the time comes. + const { subscribe, set } = persisted("bpa:walletStore", { + keyId: "", + publicKey: "", + }); + + return { + subscribe, + + // Registers a user by storing their encrypted keypair in the browser's + // `localStorage`. + register: async ({ publicKey, secretKey, pincode }) => { + try { + // Get our `KeyManager` to interact with stored keypairs + const keyManager = setupKeyManager(); + + // Use the `keyManager` to store the key in the browser's local + // storage + let keyMetadata = await keyManager.storeKey({ + key: { + type: KeyType.plaintextKey, + publicKey: publicKey, + privateKey: secretKey, + }, + password: pincode, + encrypterName: KeyManagerPlugins.ScryptEncrypter.name, + }); + + // Set the `walletStore` fields for the `keyId` and `publicKey` + set({ + keyId: keyMetadata.id, + publicKey: publicKey, + // Don't include this in a real-life production application. + // It's just here to make the secret key accessible in case + // we need to do some manual transactions or something. + devInfo: { + secretKey: secretKey, + }, + }); + } catch (err) { + console.error("Error saving key", err); + throw error(400, { message: err.toString() }); + } + }, + + // Compares a submitted pincode to make sure it is valid for the stored, encrypted keypair. + confirmCorrectPincode: async ({ + pincode, + firstPincode = "", + signup = false, + }) => { + // If we are not signing up, make sure the submitted pincode successfully + // decrypts and loads the stored keypair. + if (!signup) { + try { + const keyManager = setupKeyManager(); + let { keyId } = get(walletStore); + await keyManager.loadKey(keyId, pincode); + } catch (err) { + throw error(400, { message: "invalid pincode" }); + } + // If we are signing up for the first time (thus, there is no stored + // keypair), just make sure the first and second pincodes match. + } else { + if (pincode !== firstPincode) { + throw error(400, { message: "pincode mismatch" }); + } + } + }, + + // Sign and return a Stellar transaction + sign: async ({ transactionXDR, network, pincode }) => { + try { + // Get our `keyManager` to interact with stored keypairs + const keyManager = setupKeyManager(); + + // Use the `keyManager` to sign the transaction with the + // encrypted keypair + let signedTransaction = await keyManager.signTransaction({ + transaction: TransactionBuilder.fromXDR(transactionXDR, network), + id: get(walletStore).keyId, + password: pincode, + }); + return signedTransaction; + } catch (err) { + console.error("Error signing transaction", err); + throw error(400, { message: err.toString() }); + } + }, + }; +} + +// We export `walletStore` as the variable that can be used to interact with the wallet store. +export const walletStore = createWalletStore(); + +// Configure a `KeyManager` for use with stored keypairs. +const setupKeyManager = () => { + // We make a new `KeyStore` + const localKeyStore = new KeyManagerPlugins.LocalStorageKeyStore(); + + // Configure it to use `localStorage` and specify a(n optional) prefix + localKeyStore.configure({ + prefix: "bpa", + storage: localStorage, + }); + + // Make a new `KeyManager`, that uses the previously configured `KeyStore` + const keyManager = new KeyManager({ + keyStore: localKeyStore, + }); + + // Configure the `KeyManager` to use the `scrypt` encrypter + keyManager.registerEncrypter(KeyManagerPlugins.ScryptEncrypter); + + // Return the `KeyManager` for use in other functions + return keyManager; +}; +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stores/walletStore.js + +### Creating the account on the Stellar network + +After we've registered the user, we need to "fund" the account on the Stellar network. As discussed previously, there are multiple ways to accomplish this task, but we are using the Friendbot utility to create the account, and make sure the user has some (testnet) XLM to experiment with. + +```js title="/src/lib/stellar/horizonQueries.js" +// Fund an account using the Friendbot utility on the Testnet. +export async function fundWithFriendbot(publicKey) { + console.log(`i am requesting a friendbot funding for ${publicKey}`); + await server.friendbot(publicKey).call(); +} +``` + +### Using the `walletStore` store + +Now, our `walletStore` is used in a ton of places in our application. Probably more than anywhere else, we make use of it in the "confirmation modal" when asking a user to input their pincode. Read on to see how we've done that. + +[accounts section]: ../../fundamentals-and-concepts/stellar-data-structures/accounts [non-custodial application]: ../application-design-considerations#non-custodial-service [`js-stellar-wallets` sdk]: https://github.com/stellar/js-stellar-wallets [sponsored reserves]: ../../encyclopedia/sponsored-reserves +[contacts list]: ./contacts-list diff --git a/docs/building-apps/example-application-tutorial/confirmation-modal.mdx b/docs/building-apps/example-application-tutorial/confirmation-modal.mdx new file mode 100644 index 000000000..8f5f13c3a --- /dev/null +++ b/docs/building-apps/example-application-tutorial/confirmation-modal.mdx @@ -0,0 +1,407 @@ +--- +title: Confirmation Modal +sidebar_position: 22 +--- + +Since our user's keypair is encrypted with our pincode and stored in their browser, we will occassionally need to prompt them for that pincode in order to sign a transaction, or otherwise prove that they should be permitted to perform some action or view some data. + +## User Experience + +{/* TODO: Bri can make this better */} + +The user should be informed about any actions that may take place. Especially when user funds are on the line. So, we'll overtly request their confirmation before anything is done. Also, since we have no way of knowing their pincode, we couldn't even decrypt their keypair without them (even if we wanted to). + +The modal window we've implemented facilitates this confirmation flow everywhere we need it. + +## Code implementation + +Our modal function uses the `svelte-simple-modal` package to give us a versatile starting point. If you need to, install it now. + +```bash npm2yarn +npm install --save-dev svelte-simple-modal +``` + +### Wrapping the rest of our app in the modal + +On the Svelte side of things, this modal component will be a "wrapper" around the rest of our application. This will allow us to trigger the modal from anywhere we need, and it should behave similarly no matter what. + +```svelte title="/src/routes/+layout.svelte" + + +// highlight-next-line + + +// highlight-next-line + +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/+layout.svelte + +### Creating a reusable modal Svelte component + +In order to avoid reinventing the wheel every time we need a modal, we will create a reusable component that can accomodate most of our needs. Then, when we need the confirmation modal, we can pass an object of props to customize the modal's behavior. The basic parts of this component look like this. + +```svelte title="/src/lib/components/ConfirmationModal.svelte" + + +
+``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/components/ConfirmationModal.svelte + +### Trigger the modal component at signup + +We can now use this modal component when it is time to confirm something from the user. As an example, here is how the modal is triggered when someone is signing up. + +```svelte title="/src/routes/signup/+page.svelte" + + +
+
+
+

Signup now!

+

+ Please provide a 6-digit pincode to sign up. This pincode will be used to encrypt + the secret key for your Stellar address, before it is stored in your browser's local + storage. Your secret key to this address will be stored on your device. You will be + the only one to ever have custody over this key. +

+
+
+
+
+
+
+ +
+ +
+ +
+
+ +
+ {#if showSecret} +
+ +
+ +
+
+ {/if} +
+ + +
+
+ +
+ +
+
+
+
+
+
+``` + +### Customizing confirmation/rejection behavior + +Now, as those components have been written here, they don't actually _do_ anything when the user inputs their pincode, or clicks on a button. Let's change that! + +Since the confirmation behavior will need to vary depending on the circumstances (i.e., different actions for signup, transaction submission, etc.), we've got a way to pass that as a prop when we open the modal window. + +First, in our modal component, we declare a dummy function to act as a prop, as well as an "internal" function that will call the prop function during the course of execution. + +```svelte title="/src/lib/components/ConfirmationModal.svelte" + + +
+ +
+``` + +Now that our modal component is setup to make use of a prop function for confirmation and/or rejection, we can declare what those functions should do inside the page that spawns the modal. + +```svelte title="/src/routes/signup/+page.svelte" + + +
+ +
+``` + +As you can see, we didn't actually need a customized `onReject` function, so we didn't pass one. No harm, no foul! diff --git a/docs/building-apps/example-application-tutorial/contacts-list.mdx b/docs/building-apps/example-application-tutorial/contacts-list.mdx index 34723fc9a..b083147e5 100644 --- a/docs/building-apps/example-application-tutorial/contacts-list.mdx +++ b/docs/building-apps/example-application-tutorial/contacts-list.mdx @@ -1,11 +1,25 @@ --- title: Contacts List -sidebar_position: 15 +sidebar_position: 25 --- -A central feature for _BasicPay_ is a list of contacts that contains a user's name, and a Stellar address associated with it. While this particular function doesn't do a _tremendous_ amount of Stellar-related functionality, it makes sense for it to be the first thing we discuss. Understanding this simple component will set a good foundation for you to understand some of the more advanced components later on. +A central feature for _BasicPay_ is a list of contacts that contains a user's name, and a Stellar address associated with it. -## Creating a `localStorage` store +## User experience + +{/* TODO: Bri can make this better */} + +The user has a few ways of interacting with the contact list.... + +They can add a user/address on the `/dashboard/contacts` page. it checks for a valid public key, too! + +See it in action here: https://basicpay.pages.dev/dashboard/contacts + +## Code implementation + +We will create a Svelte `store` to keep track of a user's contact list. + +### Creating the `contacts` store As with the rest of our user-data, the contacts list will live in the browser's `localStorage`. We are using the [`svelt-local-storage-store` package] to facilitate this. We create a Svelte `store` to hold the data, and add a few custom functions to manage the list: `empty`, `remove`, `add`, `favorite`, and `lookup`. @@ -15,7 +29,7 @@ This tutorial code is simplified for display here. The code is fully typed, docu ::: -```js file="/src/lib/stores/contactsStore.js" +```js title="/src/lib/stores/contactsStore.js" import { v4 as uuidv4 } from "uuid"; import { persisted } from "svelte-local-storage-store"; import { StrKey } from "stellar-sdk"; @@ -26,6 +40,7 @@ import { get } from "svelte/store"; // and customize our own store functions to maintain consistent behavior // wherever the actions need to take place. function createContactsStore() { + // Make a `persisted` store that will hold our entire contact list. const { subscribe, set, update } = persisted("bpa:contactList", []); return { @@ -75,9 +90,9 @@ function createContactsStore() { export const contacts = createContactsStore(); ``` -Source: +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stores/contactsStore.js -## Accessing the `localStore` data +## Using the `contacts` store The `contacts` store is now exported form this file, and can be accessed and used inside a Svelte page or component. Here is how we've implemented a "favorite contacts" component for displaying on the main BasicPay dashboard. @@ -87,7 +102,7 @@ In our `*.svelte` component files, we will not dive too deeply into the HTML mar ::: -```svelte file="/src/routes/dashboard/components/FavoriteContacts.svelte" +```svelte title="/src/routes/dashboard/components/FavoriteContacts.svelte" @@ -159,7 +165,7 @@ Then import the CSS file into your base SvelteKit layout. (You may need to creat We also created a `/src/routes/+layout.js` file to configure our application as _only_ client-side. This means the app will be delivered to the client as unrendered HTML and JavaScript. -```js file="/src/routes/+layout.js" +```js title="/src/routes/+layout.js" // Disable pre-rendering of pages during build-time export const prerender = false; // Disable server-side rendering @@ -168,19 +174,19 @@ export const ssr = false; Your SvelteKit project is now configured and ready to run! -```bash -yarn run dev +```bash npm2yarn +npm run dev ``` ### Stellar dependencies In order to work with the Stellar network, datastructures, and locally stored Keypairs, we're going to install and configure a few more dependencies. -```bash +```bash npm2yarn # Stellar SDKs -yarn add -D stellar-sdk @stellar/wallet-sdk +npm install --save-dev stellar-sdk @stellar/wallet-sdk # We will need some polyfills to make things available client-side -yarn add -D @esbuild-plugins/node-globals-polyfill @esbuild-plugins/node-modules-polyfill \ +npm install --save-dev @esbuild-plugins/node-globals-polyfill @esbuild-plugins/node-modules-polyfill \ path @rollup/plugin-inject buffer svelte-local-storage-store uuid ``` @@ -239,6 +245,8 @@ export default defineConfig({ That _should_ take care of everything you need! If you've followed these steps, you now have running client-side-only application that's ready to build out and interact with the Stellar network! Way to go!! +Next up, we'll look at how we register a user and create their account on the Stellar network. + [basicpay]: https://basicpay.pages.dev [sveltekit]: https://kit.svelte.dev [daisyui]: https://daisyui.com diff --git a/docusaurus.config.js b/docusaurus.config.js index 8b7c8f671..0cbaa6611 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -89,7 +89,9 @@ const config = { showLastUpdateTime: true, breadcrumbs: true, routeBasePath: "/docs", - remarkPlugins: [require("mdx-mermaid"), require('remark-math')], + remarkPlugins: [require("mdx-mermaid"), require('remark-math'), [ + require('@docusaurus/remark-plugin-npm2yarn'), { sync: true } + ]], rehypePlugins: [require('rehype-katex')], sidebarPath: require.resolve("./sidebars.js"), editUrl: "https://github.com/stellar/stellar-docs/tree/main", diff --git a/package.json b/package.json index 61c5dd151..7a2071d98 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "@docusaurus/core": "^2.2.0", "@docusaurus/plugin-google-analytics": "^2.2.0", "@docusaurus/preset-classic": "^2.2.0", + "@docusaurus/remark-plugin-npm2yarn": "^2.4.1", "@mdx-js/react": "^1.6.22", "clsx": "^1.2.1", "docusaurus-plugin-openapi-docs": "^1.7.2", diff --git a/yarn.lock b/yarn.lock index 12be4eaa1..2ca02eec9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1657,6 +1657,15 @@ "@types/react" "*" prop-types "^15.6.2" +"@docusaurus/remark-plugin-npm2yarn@^2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@docusaurus/remark-plugin-npm2yarn/-/remark-plugin-npm2yarn-2.4.1.tgz#c67f5bc97cc6a4adee5eec0f3e97238b674b844b" + integrity sha512-RTX4hGCrwibqjDVf6edWVNwdvWHjx+YmfKwxqXxfhNnYjypTCXWTAyKeIfCUW2DNdtqAI2ZM0zFhB1maua2JbQ== + dependencies: + npm-to-yarn "^2.0.0" + tslib "^2.4.1" + unist-util-visit "^2.0.3" + "@docusaurus/theme-classic@2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-2.2.0.tgz#a048bb1bc077dee74b28bec25f4b84b481863742" @@ -9705,6 +9714,11 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npm-to-yarn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/npm-to-yarn/-/npm-to-yarn-2.0.0.tgz#59c9c615eca3ba8920308a0b418007b73ffc7492" + integrity sha512-/IbjiJ7vqbxfxJxAZ+QI9CCRjnIbvGxn5KQcSY9xHh0lMKc/Sgqmm7yp7KPmd6TiTZX5/KiSBKlkGHo59ucZbg== + nprogress@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz" @@ -12922,6 +12936,11 @@ tslib@^2.0.3, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.4.0: resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== +tslib@^2.4.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.1.tgz#fd8c9a0ff42590b25703c0acb3de3d3f4ede0410" + integrity sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" From f857773925ee19c4424f7179e382f371b6f210a9 Mon Sep 17 00:00:00 2001 From: Bri Wylde <92327786+briwylde08@users.noreply.github.com> Date: Mon, 31 Jul 2023 09:43:45 -0600 Subject: [PATCH 12/46] Update confirmation-modal.mdx --- .../example-application-tutorial/confirmation-modal.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/building-apps/example-application-tutorial/confirmation-modal.mdx b/docs/building-apps/example-application-tutorial/confirmation-modal.mdx index 8f5f13c3a..b97b282aa 100644 --- a/docs/building-apps/example-application-tutorial/confirmation-modal.mdx +++ b/docs/building-apps/example-application-tutorial/confirmation-modal.mdx @@ -3,15 +3,15 @@ title: Confirmation Modal sidebar_position: 22 --- -Since our user's keypair is encrypted with our pincode and stored in their browser, we will occassionally need to prompt them for that pincode in order to sign a transaction, or otherwise prove that they should be permitted to perform some action or view some data. +Since the user's keypair is encrypted with a pincode and stored in their browser, we will occasionally need to prompt them for that pincode to sign a transaction or otherwise prove that they should be permitted to perform some action or view some data. ## User Experience {/* TODO: Bri can make this better */} -The user should be informed about any actions that may take place. Especially when user funds are on the line. So, we'll overtly request their confirmation before anything is done. Also, since we have no way of knowing their pincode, we couldn't even decrypt their keypair without them (even if we wanted to). +The user should be informed about any actions that may take place, especially when funds are on the line. To ensure this, we will overtly request their confirmation via pincode before anything is done. The application has no way of knowing a user's pincode, so it can't decrypt their keypair without their confirmation. -The modal window we've implemented facilitates this confirmation flow everywhere we need it. +The modal window we've implemented facilitates this confirmation flow whenever we need it. ## Code implementation From 8e8750527a44b2b6d8f5296362a82c7511098e55 Mon Sep 17 00:00:00 2001 From: Bri Wylde <92327786+briwylde08@users.noreply.github.com> Date: Mon, 31 Jul 2023 09:45:30 -0600 Subject: [PATCH 13/46] update copy --- .../example-application-tutorial/confirmation-modal.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/building-apps/example-application-tutorial/confirmation-modal.mdx b/docs/building-apps/example-application-tutorial/confirmation-modal.mdx index b97b282aa..e69666cdf 100644 --- a/docs/building-apps/example-application-tutorial/confirmation-modal.mdx +++ b/docs/building-apps/example-application-tutorial/confirmation-modal.mdx @@ -7,8 +7,6 @@ Since the user's keypair is encrypted with a pincode and stored in their browser ## User Experience -{/* TODO: Bri can make this better */} - The user should be informed about any actions that may take place, especially when funds are on the line. To ensure this, we will overtly request their confirmation via pincode before anything is done. The application has no way of knowing a user's pincode, so it can't decrypt their keypair without their confirmation. The modal window we've implemented facilitates this confirmation flow whenever we need it. From 339e5e013734ab73ea8a41e7388f5df26a512848 Mon Sep 17 00:00:00 2001 From: Bri Wylde <92327786+briwylde08@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:25:36 -0600 Subject: [PATCH 14/46] update user experience copy --- .../example-application-tutorial/contacts-list.mdx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/building-apps/example-application-tutorial/contacts-list.mdx b/docs/building-apps/example-application-tutorial/contacts-list.mdx index b083147e5..d752c4792 100644 --- a/docs/building-apps/example-application-tutorial/contacts-list.mdx +++ b/docs/building-apps/example-application-tutorial/contacts-list.mdx @@ -3,15 +3,11 @@ title: Contacts List sidebar_position: 25 --- -A central feature for _BasicPay_ is a list of contacts that contains a user's name, and a Stellar address associated with it. +One central feature of BasicPay is a list of contacts containing a user's name and associated Stellar addresses. ## User experience -{/* TODO: Bri can make this better */} - -The user has a few ways of interacting with the contact list.... - -They can add a user/address on the `/dashboard/contacts` page. it checks for a valid public key, too! +There are a few ways for a user to interact with the contact list. One way is that they can add a user and address on the `/dashboard/contacts` page (which also checks for a valid public key!). See it in action here: https://basicpay.pages.dev/dashboard/contacts From 681fdae13bc1b876c672b252644372c6dabecf39 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Mon, 31 Jul 2023 10:49:47 -0600 Subject: [PATCH 15/46] add screenshots --- .../confirmation-modal.mdx | 2 ++ .../contacts-list.mdx | 4 +++- static/assets/add-contact.png | Bin 0 -> 9968 bytes static/assets/confirm-pincode.png | Bin 0 -> 6078 bytes 4 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 static/assets/add-contact.png create mode 100644 static/assets/confirm-pincode.png diff --git a/docs/building-apps/example-application-tutorial/confirmation-modal.mdx b/docs/building-apps/example-application-tutorial/confirmation-modal.mdx index e69666cdf..69d78f28c 100644 --- a/docs/building-apps/example-application-tutorial/confirmation-modal.mdx +++ b/docs/building-apps/example-application-tutorial/confirmation-modal.mdx @@ -11,6 +11,8 @@ The user should be informed about any actions that may take place, especially wh The modal window we've implemented facilitates this confirmation flow whenever we need it. +![confirmation modal](/assets/confirm-pincode.png) + ## Code implementation Our modal function uses the `svelte-simple-modal` package to give us a versatile starting point. If you need to, install it now. diff --git a/docs/building-apps/example-application-tutorial/contacts-list.mdx b/docs/building-apps/example-application-tutorial/contacts-list.mdx index d752c4792..d32fb3ad5 100644 --- a/docs/building-apps/example-application-tutorial/contacts-list.mdx +++ b/docs/building-apps/example-application-tutorial/contacts-list.mdx @@ -7,7 +7,9 @@ One central feature of BasicPay is a list of contacts containing a user's name a ## User experience -There are a few ways for a user to interact with the contact list. One way is that they can add a user and address on the `/dashboard/contacts` page (which also checks for a valid public key!). +There are a few ways for a user to interact with the contact list. One way is that they can add a user and address on the `/dashboard/contacts` page (which also checks for a valid public key!). + +![contact list](/assets/add-contact.png) See it in action here: https://basicpay.pages.dev/dashboard/contacts diff --git a/static/assets/add-contact.png b/static/assets/add-contact.png new file mode 100644 index 0000000000000000000000000000000000000000..5b2e3daabc55277d8a0fb7fde174665992642c9c GIT binary patch literal 9968 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

wVYf7Q zj-(Q0a#5dEzBODcs(!v-)w%Zp7AHyu*M=R*b+BBBm9=$NZJ3pjd%693goZe&?5N{- z=jijJF4tSJK?Ys0%J(j5ag=i*e4sCn{VBLkU%i*98>0HLXyN>I)+*;-*Ru61RJdd?nWAaz5_`is zQhaN0t>c-!QPezB_90``klqCMdH>XKl_@mj7t_xV1Wv5FqN&{Nw_Zn(_uA1Z9AB8n zM3bwmK^`J?&{n32fnl_ToO^nU&wJ`AjY|#w)S~Qu?G8__9uD=z$aMulkJcHgNYu7y z{HH|;R3i5iP|wiyud7zd=a^!NLX$P-NCS39czngDVg=YP4OV^8u&q`zCV<6&P)9nZ`bgFZ z0pz@4ILtbw$C~49eWq8HOa1)0z?Wk}|2M=R+RdA;D~i;9FMck5+W=`vE8r+|MAi-= z8is54^8TjUUg^C%y<%Ol=8F5AAvtXod}N^J{qu9A1C}bR)Z5wl<5J1+7BRr=vZLw|FtUHSB<+aB&T=W3{dGPKM}?ser&>C70PxD!vzf=@X3D|Y z2v(veD_bTxRI;ra@K)&aNBLEl$##jMFT;xhw6)e4S`ZYPm94J?GY1 z9+)+3ii4T}h7*W(CigRYs!If{Pziel zi4G*!A1`P&;Q^wDW#p!5<_Ob124W5C@rarw0kBDs@?NCUuw|yo0*2qP50v;b)3=eR zukqNG7wNr0%|^t#Rj9v!NCE7UwQ%FDin7|cUd1aVE7vmMzOmJ96Yu! zSF#|(jgODR!2sHE;(~lbm>$jAfM9qZAHl!NVBq5N)6BFvaqQvMRih-J=+N$v03F`a z@kcdbBw%52;oh&+z12C0z=#*W5f2Rj`UjNnso>bXoYQ9#^ALpEd)ynqFkEEwRuJd~ zDucns5)wh^&k%%66$ zsfaI)C@~x4*z^x_H}C(91a5>7rn-H7sC$}~XL%Y$He^`{wOipIgBsbn>%+$RGC^mo zt}$O^1??*A3JMA?hLRrz6qJ?o8ycdnqG2FmMWYU!Qjup~e*TvRZZptF)wubkV~dwY z1$+EK`9VE zgR^SQYy=fo&l>JG9Dbk1@IJSslG-ESFb}`TkP$1^yh_EH6(NDc3?of1E1tZSA|A+Ovvy8NA&DKg&{I!U!8jR}R}bN9<8cQ&Y2XX?e8`#o`DW z8lEJny426zp|D|%fDIl0<-3`W%nDBtgYQ&*gU%3-8g{-`bFX~xlOsYoJtZ)U{0F>z zjUiwJga4^umkO}tyJvjk7hJgEdT2j*dMhp;9*O~BcyzsX)=|S}Kdj>Tf2aqACevh)68M7 z*?jpTgJ02YtMVR3C*+TZ7nc0cF{s;l^+KdbS;OKXB|c6_xDZcqG6z*be31W;&#A=< zE$q~GhQ|P3T|Fm8UB)0kBL^Cyr=3N7!EM^0x4VDvo}U^io}LW$Nv{ZLoY8@C9J>bx zB)jil8e4+nI3n#n@UVb!V*ji{=?__rz00Rz4>nz^@+r_Z631 zlqa2u@8#Yl0Om_2nn_qbddUw8wez-m%t`Q>2UAvD-bw~cnZ}a0`_Crj!b4HSQA$}? zZ1L^CkUD>8(z5kQWs%Vd7nw+6hGq7JdY9v&ITi7lnwqi^TXETWfAsYA#rF>Eg;X>Iv4-U9^ zc*Y|4TfKc2Ooy~>*$t_+zpVBB#F4La9P)!@0nXJl{E{q*T*UYH&aKKR@s$l z*2Scqe_M-QW68?m(+}<)+;!`WZ5G+g+DmbbmlTT{FbMzKj`T;;Av~{rjcCP0M@}~E ztZhavNaLDAc;PCOkjkg6`X5c3LCpa-dp#wZ55IqZH+g8|%iF3lY7I0d9}SNj2z$Q7 zhkm6p{?`yoMOvcrcSlu2DMGizOt(kzpIO_l>w@|A)-{%s-#X}rp22tp*yd?K>isJn zCmggY8JIq)QR)6aC}sXV5#C5#7?R z3=^1olNk?fA4}rXqc4dw1hC2BD%g3%mDNt!;%-#|BBuNte-29)tTn_=42{vC^R#{76-D+_1 M(kfDw5}$(p3s7T@k^lez literal 0 HcmV?d00001 diff --git a/static/assets/confirm-pincode.png b/static/assets/confirm-pincode.png new file mode 100644 index 0000000000000000000000000000000000000000..dfd0d2a5b2cffef0ef49c257b1f1a2d10f19f692 GIT binary patch literal 6078 zcmc&&XEaxEgOYLieJ(iAywouB1b~~!^M_*EiNhECNQKnYQKed@;-D9hdO+g;2>?u1nopDr zeN#84{E=}7Y3)0G-40GI3(7@5?$V$iT-2oC4CnhAhrE(JWKPIp7_nO$!4y3&-C$o) zohrAR_%K!3?_wcm;J~`>y}KGWU)d?wTzqw(M#YIIc1)2cQIk4R z)9L0?$H@UfqED{x=qQD%*H7V?9M~7Zf8Re(4?NvvCw3woIKF3nLj?fL?Ek0I+OV3I zNv>WgT;hWFFeAKYsFgD>Jqz=>c(_{%i`)NeL)Q%3O6y1tWGou2ohT=*=N)%tky`1_ zyuW>CZJ9XbW&js^u4N3sECfRv+yLO7Dl=u@J^6~pr?(K{6;5960H3dKJgs3t%=L<> z24szseafuz4EKrDI*x&OZ7zbb(%;TaRAl1OT4(E6ZWx!ILlv zVE2=*sL4Xpr?{3Z{PxcS3gVT+53{&OI#0Y@n z6(!iyBZDN*DpG@>0<(LX4dj9qd5AwT)_lOK$}6KYndDW_w?FY=`2rxu@KAFFNus5(I#(p>0JBZX2cJI+Y_# zk@eWf!Y7YMM7^BXXA7=BCOGwo2z8q>6Xwq5KY>m>pUT;g6`3SVIT^t*=J?FAUq#RK zOV!ma=HrnY+%9d4h*r`y^QypiBl1yMS&1ytG=E-$G4?4$WjE0>E^1*!FQ!@)6j})S ztF>2BMPA(CGcZFWWDCWi@AUMBne_AqZ~=%VbIl#5cVeIMs;_*Il=u$zEkzN8%(hMm(xGW%Z%3=z!;(2 zWOdV8Lp(%7`g9<j9SR0Py>R zFSJXM{BY;+8p;(u!~5mWXN=bPPN~bUU7XM?c^%UQfyJYO7$TJ8?&KLy7A%^NOY~G| zXeBNoKeP%72m0!7eY;`;_i(~Ru1D2g==pKn<)3rN$aq=kXup}=M6_!|h0xcC3s49FsmQvxq2Tb0>ERb9Sd^+Xx^p*Cc4#>BG@L63-N}`~!pe%*{7C@-N@5m5P$)E}j~6nWL8Hg2A{-SJ#TSbv zkx(rlB2$~^5b{Y9&JHnpG&EthaC?n6?Jvr^=3eGvOF0e6;09TSF#9a<9P5()KN0l& z+Yug83&?c)LU1v&xVv*sYOg2D{LA2HRtH#YXsF|L3LQUxmhcSi`4zi)U)@ zlOHq@4XfKPck@S0CzY(sAPEeiTsfU*+gfgll9S5-5Uk;26tUfHJ$PH0i%-LVqA)7fyGZL0_d;7Mctz3uaAHe__ecY3B$i?_}uRbVYmSH>8Fc^*NzDQuFK5*WHM=`1`+?U)D5tB2haUy@*4m4Z?2>s z2Oe-w7N>Hvcc;;PT6nh34ltJrBrS4Dlwc^NQ+h<)LwOgxLK%F)1T!lfd3taO03u!) zrx+D^oBUj(~cwfORe!y|l#B;b07f(%zQ`fVyGO-3Qx#r<6(5uxp!pUJ}`Xp7HOBA6;7WNepdrG*$5BR&n0%!a-jWHes@ZZs#P zY-Y6GTfZt8JC(PRQXDJ%NPfi=GDd15s?ye)pN-Sh?S-rSa#y^pv~2&xF`>wWrue*8bX zaQ|AR`Uwew!1q22e+{qVEu-)M$fUU^7KFi}4OSrDWR+~VZj51EY$w^b5zCWxl*KtgNJv?}H>Eni<6~5}$5G`bH zLIUkmiFGZHBM)&yb??lMt}t_VTYZh-mUzfx9@C4RYgdHfl{Cw@o}PBf9h~XxR=S-P zeph9acYCtA)tvzw$dH7?RJYhIpb0M;J>D2=YZ?@A5z&%lhwzW2G_&e;3la*owRXWj zFtgpKZ)n`TXJDUV6>9Kej(`hzHO1Kl1*1RCrOAb{59g-2KkB$7B4#Mk zM*kpiMxy$g0b>Cd+B&KZj$$lzPTS+UDpIp|=o$GGiq;&FZ-rv&6QwK5H%oN?RBEWp z4J4o9CL7(Ff;4(`{Ghs5N0*PE^l-B&Sw>Tfc|@|;JWvVST^${eM>Vb()oj?{eahAw z+O-AyZ^2?v);v5HVT8Wqeyd^?s_B!gkDeu*i!gr%vW1J9jw>TV_wz@g78uEI9hOJzVSdY<1C1&BC7Pe;r-f zJlbQ(!0CiOYRZm1o*8~$KRu!TtHKr1V44}in!tA)lf-Lm|B9Dip>%8d%>}*YQomRR zqbi%wDh|SN@uK%97mZp4i!i*A3m?MxmD1MKR9&$luiai;f~SU;2~z)Fu)NujxOhAd zzv6xK_Rh+c!df+c!DrOGB09%^5t)QNYHHt%yLiJldM`Up9YP8-WGbD50@ZX0#z)e| z0e6Yb&&JuE3g#$+_0bz?HzDfFh!(|5@6#URLJdv0F;kGLN9)MaK8vsWadc^;CRx3~ zy zF2=5q%)6_+m^!Uct+!d=hvK@s{zOL27kD--#Y-rqvdQ(}!b3J!QuDSA{Bz#HgllVyXuaWZwL8SA7c^JP5PfGvNQ^nm=bdGyk^fS7z(k2Sg8shEr3dz@*1KR~*3 zB}kf7Fc&uR{>|A9(rQ)6^2ZVK6Fv~4BUrr6VBBoaV{>3-bYd7sO|1l#P~@gVXbg-r zbx&quL7JaGXgyd@UYe1~rKM;l?~pz=Uf%ZWA(i!ai4xZ{n8l$U(r$w>pv)`t&gbqZ z@>>OUK?OyV^cln4jTiajAIBe_Mq8RK)W)dYYhO^7KRM?ADBWlxXv06yC(#Bc#{~}Q zn3P3kpM8g2D4O%&^Tb@^ z(e#a-P}D?p2#9Ob;}Gl77(saT1bCu1&hl?z-2Ne!*~hd6*+<)Tel&y`D9&;w{4rxG z4#=CR(DLduX*p;kTPPfkOQTjj=MAk5Gu@P~*{0#6=VN$y`1i`%Bk?`3GPH{SLCb^r zi|X^I#QkC@MlG}p z{BS4=$D?-a<8;VYN;G2~ZcQkF!yk11Ov~Yp59+Tp3CemmbgJZIotRg_mzb9)=p|D1 z^ynz4K#=k}cxep7^jpYX5MlQ!-G)XReA75DKh$2lJe~wUgDEa`TuLSl=@Ey+xn=eS zD~m+gyN$-*`K%Gzfu48_4`w)|-CXg;sU2iVu5&4ArA*~aJCxe`=#mUHTHzHZH zyLQau2bZ4Arb(IV&m*@cUpE|_G!ffx|7EUNgE;$kQ{GQ(wz{TkAC;ix-k>k!qnyCV zFr9TfWA%tlnga2T>p(jVqxxy6!RNIZ>~IUeN2S=G{cf4-lTpipkZ_Yslhbn9e{+@l zQ#3#`26N_t*YL3&mi1e1`x;sN=a-x9YR5{{9w~*h(0TifB1oXYbO)F({RdsubsCxD z+h1=${$86Q&d<1(w0La%-gyfA4Wv1ziSxEaARnQwB4u4p5FgB^M@9FT^V_B$sMs$# zd?*ZnjSA2g>=j6?c(Pc&z>Kt8TH0MV<=BHjNx`onms47k|2` ze{5;uv9fdQP-^N>Zno&*&xKehPTsDOa|t@i1*g1Is4BpkP3R5ZK)s#aN8!j%(mIoq zRjgCac~_>NeW{EKOVMV({auAbbvDQ~muXYE6&8^G$J!PL0o+I~<2KcPKmAy10iXOS4aIe2>y=Re$dlDlfsB)(wo(^Q_* zr}6o7P8AAi6TTUpRyQ+ttFrPu>@~Ziz*ib5HcLpiGt2C{nXPy7Q?c6eE_B2 z?BS06iIL3=`mb_@EWKqbQB8qjp~N1ApDCw&^jD~@7mE2V0G9Y)zvda(*a~TG4RU7~ z?&l=p2M6=u5-*~AdflkMzdM5i!M3-UIC8!)huYcQ**#{)eA~7i5C`rq6i6ca4y!%* z?~mSU{tT*St_T;V6h4_fLsiac*4G<}*8g5zq^H~7Os97!jq(+HeZG)0tSkw) zRHuin|Fd#CV{dYa$&qb+>p8`{$6!ZxHLO+Wcwyut)tQyBaABf+;NG6-+IRBFUvu9| z&b#Q4ZWjq`eWv9V#%V11g#Mau1Yr&Td4#MzbG!*F8?PZh^W8C(0q*)XzHw(`uhQcg z+mAmRv4T?<#h7E%m7Lqs>}zZEM8n@%T-q z?V?`q9={e((H2)tVsM0X+{}B!MoItnhdZ1CPzHaQxJt%4+>e`G{l+B#Hk@+j*z`Zj b`ZKD}OgCnzFy0y Date: Fri, 4 Aug 2023 10:38:19 -0600 Subject: [PATCH 16/46] update payment page --- .../example-application-tutorial/payment.mdx | 18 +++++++++++------- static/assets/fees.png | Bin 0 -> 30322 bytes static/assets/payment.png | Bin 0 -> 52493 bytes 3 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 static/assets/fees.png create mode 100644 static/assets/payment.png diff --git a/docs/building-apps/example-application-tutorial/payment.mdx b/docs/building-apps/example-application-tutorial/payment.mdx index e49bf9f49..924c059cc 100644 --- a/docs/building-apps/example-application-tutorial/payment.mdx +++ b/docs/building-apps/example-application-tutorial/payment.mdx @@ -5,18 +5,22 @@ sidebar_position: 40 A payment operation sends an amount in a specific asset (XLM or non-XLM) to a destination account. With a basic payment operation, the asset sent is the same as the asset received. BasicPay also allows for path payments (where the asset sent is different than the asset received), which we’ll talk about in the next section. -In our BasicPay application, we’ll add a “Send Payment” button that allows the user to input the public key of a destination address with a specified asset they’d like to send along with the amount of the asset. The application will first verify that the destination account exists and is properly funded with XLM. +In our BasicPay application, the user will navigate to the Payments page where can either select a user from their contacts or input the public key of a destination address with a specified asset they’d like to send along with the amount of the asset. -:::info +![payment](/assets/payment.png) -An asset is displayed as an asset code and issuer address. Learn more in our [Assets section](https://developers.stellar.org/docs/fundamentals-and-concepts/stellar-data-structures/assets). - -::: +The user clicks the "Confirm Transaction" button. If the destination account exists and is properly funded with XLM, this will trigger a Transaction Preview where they can view the transaction details. All Stellar transactions require a small fee to make it to the ledger. Read more in our [Fees, Surge Pricing, and Fee Strategies section](../../encyclopedia/fees-surge-pricing-fee-strategies). In BasicPay, we’ve set it up so that the user always pays a static fee of 100,000 [stroops](../../fundamentals-and-concepts/stellar-data-structures/assets#amount-precision) (one stroop equals 0.0000001 XLM) per operation. Alternatively, you can add a feature to your application that allows the user to set their own fee. -![send payment](/assets/send-payment.png) +![payment](/assets/fees.png) + +The user then inputs their pincode and clicks the "Confirm" button, which signs and submits the transaction to the ledger. -Finally, the user will click the “Send” button, which triggers a modal with the transaction preview where the user will input their pincode and click “Confirm” which signs and submits the transaction to the ledger. +:::info + +An asset is displayed as an asset code and issuer address. Learn more in our [Assets section](https://developers.stellar.org/docs/fundamentals-and-concepts/stellar-data-structures/assets). + +::: diff --git a/static/assets/fees.png b/static/assets/fees.png new file mode 100644 index 0000000000000000000000000000000000000000..76436af1d4759b6b8fad1c6157350f76647e89ba GIT binary patch literal 30322 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 literal 0 HcmV?d00001 diff --git a/static/assets/payment.png b/static/assets/payment.png new file mode 100644 index 0000000000000000000000000000000000000000..f6448bb47acd682e8747cc1350086a53d0ee22a0 GIT binary patch literal 52493 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

Z?(lX;kj}|z+DN=8<-la__|L>! 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 Date: Fri, 4 Aug 2023 10:50:39 -0600 Subject: [PATCH 17/46] update manage trust page --- .../manage-trust.mdx | 8 +++++--- static/assets/add-assets.png | Bin 0 -> 72315 bytes 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 static/assets/add-assets.png diff --git a/docs/building-apps/example-application-tutorial/manage-trust.mdx b/docs/building-apps/example-application-tutorial/manage-trust.mdx index db1c49cbb..06a2bb5c2 100644 --- a/docs/building-apps/example-application-tutorial/manage-trust.mdx +++ b/docs/building-apps/example-application-tutorial/manage-trust.mdx @@ -5,7 +5,11 @@ sidebar_position: 30 For an account to hold and trade assets other than XLM, it must establish a [trustline](../../fundamentals-and-concepts/stellar-data-structures/accounts#trustlines) with the issuing account of that particular asset. Each trustline increases the account’s [base reserve](../../fundamentals-and-concepts/stellar-data-structures/accounts#base-reserves-and-subentries) by 0.5 XLM, which means the account will have to hold more XLM in its minimum balance. In BasicPay, we’ve already funded the account on Testnet. When moving your application to Pubnet, you can either cover an account’s minimum balance using sponsored reserves, or the user will have to supply their own XLM. -First, we’ll have the user create a trustline for an asset by navigating to the Assets page, selecting an asset, and clicking the “Add Asset” button. This triggers a modal form for them to confirm the transaction with their pincode. Once confirmed, a transaction containing the `changeTrust` operation is signed and submitted to the network, and a trustline is established with the issuing account for the asset. +First, we’ll have the user create a trustline for an asset by navigating to the Assets page, selecting an asset, and clicking the “Add Asset” button. + +![add-assets](/assets/add-assets.png) + +This triggers a modal form for the user to confirm the transaction with their pincode. Once confirmed, a transaction containing the `changeTrust` operation is signed and submitted to the network, and a trustline is established between the user's account and the issuing account for the asset. :::info @@ -13,8 +17,6 @@ Every transaction must contain a sequence number that is used to identify and ve ::: -![add asset](/assets/add-asset.png) - The `changeTrust` operation can also be used to modify or remove trustlines. Trustlines hold the balances for all of their associated assets (except XLM, which are held at the account level), and you can display the user’s various balances in your application. diff --git a/static/assets/add-assets.png b/static/assets/add-assets.png new file mode 100644 index 0000000000000000000000000000000000000000..744dc57789899d1d1705ae77681bbc0ce739b7a3 GIT binary patch literal 72315 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 literal 0 HcmV?d00001 From 53f8d89a22c61df15e011856669ae0f7e3bbab30 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Fri, 4 Aug 2023 11:02:49 -0600 Subject: [PATCH 18/46] update path payment page --- .../manage-trust.mdx | 2 ++ .../path-payment.mdx | 8 +++++--- .../example-application-tutorial/payment.mdx | 2 ++ static/assets/path-payment.png | Bin 0 -> 25757 bytes 4 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 static/assets/path-payment.png diff --git a/docs/building-apps/example-application-tutorial/manage-trust.mdx b/docs/building-apps/example-application-tutorial/manage-trust.mdx index 06a2bb5c2..bd80bb3cf 100644 --- a/docs/building-apps/example-application-tutorial/manage-trust.mdx +++ b/docs/building-apps/example-application-tutorial/manage-trust.mdx @@ -5,6 +5,8 @@ sidebar_position: 30 For an account to hold and trade assets other than XLM, it must establish a [trustline](../../fundamentals-and-concepts/stellar-data-structures/accounts#trustlines) with the issuing account of that particular asset. Each trustline increases the account’s [base reserve](../../fundamentals-and-concepts/stellar-data-structures/accounts#base-reserves-and-subentries) by 0.5 XLM, which means the account will have to hold more XLM in its minimum balance. In BasicPay, we’ve already funded the account on Testnet. When moving your application to Pubnet, you can either cover an account’s minimum balance using sponsored reserves, or the user will have to supply their own XLM. +## User experience + First, we’ll have the user create a trustline for an asset by navigating to the Assets page, selecting an asset, and clicking the “Add Asset” button. ![add-assets](/assets/add-assets.png) diff --git a/docs/building-apps/example-application-tutorial/path-payment.mdx b/docs/building-apps/example-application-tutorial/path-payment.mdx index d1c3d28bf..27a204036 100644 --- a/docs/building-apps/example-application-tutorial/path-payment.mdx +++ b/docs/building-apps/example-application-tutorial/path-payment.mdx @@ -5,11 +5,13 @@ sidebar_position: 50 A path payment is where the asset sent can be different from the asset received. There are two possible path payment operations: 1) `path_payment_strict_send`, which allows the user to specify the amount of the asset to send, and 2) `path_payment_strict_receive`, which allows the user to specify the amount of the asset received. -With BasicPay, the user will input the public key of the destination address, specify the asset sent and the asset received, and the amount of asset either sent or received. +## User experience -[ss] +With BasicPay, the user sends a path payment by navigating to the Payments page, where they can either select a user from their contacts or input the public key of a destination address. They then select the Send and Receive Different Assets toggle and determine whether they want to specify the asset sent or received. Finally they select the asset sent and the asset received and the amounts and select the Preview Transaction button. -The user will then sign and submit the transaction to the network. +![path payment](/assets/path-payment.png) + +The user will then preview the transaction, input their pincode, and select the Confirm button to sign and submit the transaction to the network. :::tip diff --git a/docs/building-apps/example-application-tutorial/payment.mdx b/docs/building-apps/example-application-tutorial/payment.mdx index 924c059cc..052362bf9 100644 --- a/docs/building-apps/example-application-tutorial/payment.mdx +++ b/docs/building-apps/example-application-tutorial/payment.mdx @@ -5,6 +5,8 @@ sidebar_position: 40 A payment operation sends an amount in a specific asset (XLM or non-XLM) to a destination account. With a basic payment operation, the asset sent is the same as the asset received. BasicPay also allows for path payments (where the asset sent is different than the asset received), which we’ll talk about in the next section. +## User experience + In our BasicPay application, the user will navigate to the Payments page where can either select a user from their contacts or input the public key of a destination address with a specified asset they’d like to send along with the amount of the asset. ![payment](/assets/payment.png) diff --git a/static/assets/path-payment.png b/static/assets/path-payment.png new file mode 100644 index 0000000000000000000000000000000000000000..893c3a93cbff2972aba7a800e3852af6e5ca084d GIT binary patch literal 25757 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 literal 0 HcmV?d00001 From 28ce356068506458583dd84ecfef41148a80857e Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 8 Aug 2023 10:47:57 -0500 Subject: [PATCH 19/46] Code implementation for manage trust, and some other minor changes --- .../account-creation.mdx | 2 + .../contacts-list.mdx | 101 +++++---- .../manage-trust.mdx | 198 ++++++++++++++++++ .../querying-data.mdx | 1 + 4 files changed, 259 insertions(+), 43 deletions(-) diff --git a/docs/building-apps/example-application-tutorial/account-creation.mdx b/docs/building-apps/example-application-tutorial/account-creation.mdx index 0f3eeacd3..a72690a71 100644 --- a/docs/building-apps/example-application-tutorial/account-creation.mdx +++ b/docs/building-apps/example-application-tutorial/account-creation.mdx @@ -182,6 +182,8 @@ export async function fundWithFriendbot(publicKey) { } ``` +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js + ### Using the `walletStore` store Now, our `walletStore` is used in a ton of places in our application. Probably more than anywhere else, we make use of it in the "confirmation modal" when asking a user to input their pincode. Read on to see how we've done that. diff --git a/docs/building-apps/example-application-tutorial/contacts-list.mdx b/docs/building-apps/example-application-tutorial/contacts-list.mdx index d32fb3ad5..a2f00fd7c 100644 --- a/docs/building-apps/example-application-tutorial/contacts-list.mdx +++ b/docs/building-apps/example-application-tutorial/contacts-list.mdx @@ -90,7 +90,55 @@ export const contacts = createContactsStore(); Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stores/contactsStore.js -## Using the `contacts` store +### Using the `contacts` store + +#### On the `/dashboard/contacts` page + +We also have a page dedicated to managing contacts. The `/dashboard/contacts` page will allow the user to collect and manage a list of contact entries that stores the contact's name and Stellar address. The contact can also be flagged/unflagged as a "favorite" contact to be displayed on the main `/dashboard` page. + +```svelte title="/src/routes/dashboard/contacts/+page.svelte" + + + +

All contacts

+ + + + + + + // highlight-next-line + {#each $contacts as contact (contact.id)} + + + + {/each} + +
+``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/contacts/+page.svelte + +#### On the `/dashboard` page The `contacts` store is now exported form this file, and can be accessed and used inside a Svelte page or component. Here is how we've implemented a "favorite contacts" component for displaying on the main BasicPay dashboard. @@ -114,52 +162,19 @@ In our `*.svelte` component files, we will not dive too deeply into the HTML mar $: favoriteContacts = $contacts?.filter((contact) => contact.favorite) +

Favorite Contacts

- + {#if favoriteContacts} + + // highlight-next-line + {#each favoriteContacts as contact (contact.id)} - - - + - - {#if favoriteContacts} - - {#each favoriteContacts as contact (contact.id)} - - - - - - - {/each} - - {/if} + {/each} + + {/if}
FavoriteNameAddress
- contacts.favorite(contact.id)} - /> - -
-
-
- Avatar Tailwind CSS Component -
-
-
-
{contact.name}
-
-
-
- - - -
``` diff --git a/docs/building-apps/example-application-tutorial/manage-trust.mdx b/docs/building-apps/example-application-tutorial/manage-trust.mdx index bd80bb3cf..6d2cdc19f 100644 --- a/docs/building-apps/example-application-tutorial/manage-trust.mdx +++ b/docs/building-apps/example-application-tutorial/manage-trust.mdx @@ -24,3 +24,201 @@ The `changeTrust` operation can also be used to modify or remove trustlines. Trustlines hold the balances for all of their associated assets (except XLM, which are held at the account level), and you can display the user’s various balances in your application. ![display assets](/assets/display-assets.png) + +See it in action here: https://basicpay.pages.dev/dashboard/assets + +## Code implementation + +The trustlines an account holds will be necessary to view in several parts of the BasicPay application. First, we'll discuss how we manage different trustlines for the account. + +### The `/dashboard/assets` page + +The `/dashboard/assets` page will allow the user to manage the Stellar assets their account carries trustlines to. On this page, they can select from several pre-suggested or highly ranked assets, or they could specify their own asset to trust using an asset code and issuer public key. They can also remove trustlines that already exist on their account. + +The layout of the page is quite similar to our contacts page. It's got a table displaying the existing trustlines, and a section where you can add new ones. The key difference is that the `contacts` store is held in the browser's `localStorage`, whereas an account's balances are held on the blockchain. So, we will be querying the network to get that information. For more information about how we query this information from the Stellar network, check out the [`fetchAccountBalances()` function] in the querying data section. + +{/* TODO: Use the actual link to the section once we have that ready. */} + +[`fetchaccountbalances()` function]: https://www.example.com + +```svelte title="/src/routes/dashboard/assets/+page.svelte" + + + +

Add Trusted Assets

+ + +{#if addAsset === 'custom'} +
+ + +
+{/if} + + + +

Existing Balances

+ + + + {#each balances as balance} + + + + + + + {/each} + +
{balance.asset_code}{balance.balance} + +
+``` + +### The `createChangeTrustTransaction` function + +In the above page, we've made use of the `createChangeTrustTransaction` function. This function can be used to add, delete, or modify trustlines on a Stellar account. + +```js title="/src/utils/stellar/transactions.js" +// Constructs and returns a Stellar transaction that will create or modify a +// trustline on an account. +export async function createChangeTrustTransaction({ source, asset, limit }) { + // We start by converting the asset provided in string format into a Stellar + // Asset() object + let trustAsset = new Asset(asset.split(":")[0], asset.split(":")[1]); + + // Next, we setup our transaction by loading the source account from the + // network, and initializing the TransactionBuilder. + let server = new Server(horizonUrl); + let sourceAccount = await server.loadAccount(source); + + // Chaning everything together from the `transaction` declaration means we + // don't have to assign anything to `builtTransaction` later on. Either + // method will have the same results. + let transaction = new TransactionBuilder(sourceAccount, { + networkPassphrase: networkPassphrase, + fee: maxFeePerOperation, + }) + // Add a single `changeTrust` operation (this controls whether we are + // adding, removing, or modifying the account's trustline) + .addOperation( + Operation.changeTrust({ + asset: trustAsset, + limit: limit?.toString(), + }), + ) + // Before the transaction can be signed, it requires timebounds + .setTimeout(standardTimebounds) + // It also must be "built" + .build(); + + return { + transaction: transaction.toXDR(), + network_passphrase: networkPassphrase, + }; +} +``` diff --git a/docs/building-apps/example-application-tutorial/querying-data.mdx b/docs/building-apps/example-application-tutorial/querying-data.mdx index 021db5855..2d035bfd6 100644 --- a/docs/building-apps/example-application-tutorial/querying-data.mdx +++ b/docs/building-apps/example-application-tutorial/querying-data.mdx @@ -11,3 +11,4 @@ Functions to query: - fetchAccount: gives all the same information as loadAccount, but doesn’t have the account object - getAccountBalances - submitTransaction +- that stellar.expert thing From 03f7fae9435488dee31e38a1e6b8be6a84e461f2 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 8 Aug 2023 12:23:21 -0500 Subject: [PATCH 20/46] Adding payment and path payment examples --- .../manage-trust.mdx | 24 +- .../path-payment.mdx | 388 +++++++++++++++++- .../example-application-tutorial/payment.mdx | 339 +++++++++++++++ 3 files changed, 745 insertions(+), 6 deletions(-) diff --git a/docs/building-apps/example-application-tutorial/manage-trust.mdx b/docs/building-apps/example-application-tutorial/manage-trust.mdx index 6d2cdc19f..ee0a0b680 100644 --- a/docs/building-apps/example-application-tutorial/manage-trust.mdx +++ b/docs/building-apps/example-application-tutorial/manage-trust.mdx @@ -35,11 +35,11 @@ The trustlines an account holds will be necessary to view in several parts of th The `/dashboard/assets` page will allow the user to manage the Stellar assets their account carries trustlines to. On this page, they can select from several pre-suggested or highly ranked assets, or they could specify their own asset to trust using an asset code and issuer public key. They can also remove trustlines that already exist on their account. -The layout of the page is quite similar to our contacts page. It's got a table displaying the existing trustlines, and a section where you can add new ones. The key difference is that the `contacts` store is held in the browser's `localStorage`, whereas an account's balances are held on the blockchain. So, we will be querying the network to get that information. For more information about how we query this information from the Stellar network, check out the [`fetchAccountBalances()` function] in the querying data section. +The layout of the page is quite similar to our contacts page. It's got a table displaying the existing trustlines, and a section where you can add new ones. The key difference is that the `contacts` store is held in the browser's `localStorage`, whereas an account's balances are held on the blockchain. So, we will be querying the network to get that information. For more information about how we query this information from the Stellar network, check out the `fetchAccountBalances()` function in the querying data section. {/* TODO: Use the actual link to the section once we have that ready. */} -[`fetchaccountbalances()` function]: https://www.example.com +[querying data section]: https://www.example.com ```svelte title="/src/routes/dashboard/assets/+page.svelte" + + + + + + + + + +{#if createAccount !== null && !createAccount} + +{/if} + + +{#if pathPayment} +
+
+

Sending

+
+
+
+ +
+
+ +
+
+
+
+ Strict {strictReceive ? 'Receive' : 'Send'} + +
+
+

Receiving

+
+
+
+
+ +
+
+ +
+
+
+{:else} + +{/if} + + + + +``` + +### The transaction functions + +In the above page, we've made use of the `createPathPaymentStrictReceiveTransaction` and `createPathPaymentStrictSendTransaction` functions. These are used to create transactions that contain the actual path payment operation. + +```js title="/src/lib/stellar/transactions.js" +// Constructs and returns a Stellar transaction that will contain a path payment strict send operation to send/receive different assets. +export async function createPathPaymentStrictSendTransaction({ + source, + sourceAsset, + sourceAmount, + destination, + destinationAsset, + destinationAmount, + memo, +}) { + // First, we setup our transaction by loading the source account from the + // network, and initializing the TransactionBuilder. This is the first step + // in constructing all Stellar transactions. + let server = new Server(horizonUrl); + let sourceAccount = await server.loadAccount(source); + let transaction = new TransactionBuilder(sourceAccount, { + networkPassphrase: networkPassphrase, + fee: maxFeePerOperation, + }); + + // We work out the assets to be sent by the source account and received by + // the destination account + let sendAsset = + sourceAsset === "native" + ? Asset.native() + : new Asset(sourceAsset.split(":")[0], sourceAsset.split(":")[1]); + let destAsset = + destinationAsset === "native" + ? Asset.native() + : new Asset( + destinationAsset.split(":")[0], + destinationAsset.split(":")[1], + ); + + // We will calculate an acceptable 2% slippage here for... reasons? + let destMin = ((98 * parseFloat(destinationAmount)) / 100).toFixed(7); + + // If a memo was supplied, add it to the transaction + if (memo) { + transaction.addMemo(Memo.text(memo)); + } + + // Add a single `pathPaymentStrictSend` operation + transaction.addOperation( + Operation.pathPaymentStrictSend({ + sendAsset: sendAsset, + sendAmount: sourceAmount.toString(), + destination: destination, + destAsset: destAsset, + destMin: destMin, + }), + ); + + // Before the transaction can be signed, it requires timebounds, and it must + // be "built" + let builtTransaction = transaction.setTimeout(standardTimebounds).build(); + return { + transaction: builtTransaction.toXDR(), + network_passphrase: networkPassphrase, + }; +} + +// Constructs and returns a Stellar transaction that will contain a path payment strict receive operation to send/receive different assets. +export async function createPathPaymentStrictReceiveTransaction({ + source, + sourceAsset, + sourceAmount, + destination, + destinationAsset, + destinationAmount, + memo, +}) { + // First, we setup our transaction by loading the source account from the + // network, and initializing the TransactionBuilder. This is the first step + // in constructing all Stellar transactions. + let server = new Server(horizonUrl); + let sourceAccount = await server.loadAccount(source); + let transaction = new TransactionBuilder(sourceAccount, { + networkPassphrase: networkPassphrase, + fee: maxFeePerOperation, + }); + + // We work out the assets to be sent by the source account and received by + // the destination account + let sendAsset = + sourceAsset === "native" + ? Asset.native() + : new Asset(sourceAsset.split(":")[0], sourceAsset.split(":")[1]); + let destAsset = + destinationAsset === "native" + ? Asset.native() + : new Asset( + destinationAsset.split(":")[0], + destinationAsset.split(":")[1], + ); + + /** @todo Figure out a good number to use for slippage. And why! And how to calculate it?? */ + // We will calculate an acceptable 2% slippage here for... reasons? + let sendMax = ((100 * parseFloat(sourceAmount)) / 98).toFixed(7); + + // If a memo was supplied, add it to the transaction + if (memo) { + transaction.addMemo(Memo.text(memo)); + } + + // Add a single `pathPaymentStrictSend` operation + transaction.addOperation( + Operation.pathPaymentStrictReceive({ + sendAsset: sendAsset, + sendMax: sendMax, + destination: destination, + destAsset: destAsset, + destAmount: destinationAmount, + }), + ); + + // Before the transaction can be signed, it requires timebounds, and it must + // be "built" + let builtTransaction = transaction.setTimeout(standardTimebounds).build(); + return { + transaction: builtTransaction.toXDR(), + network_passphrase: networkPassphrase, + }; +} +``` diff --git a/docs/building-apps/example-application-tutorial/payment.mdx b/docs/building-apps/example-application-tutorial/payment.mdx index 052362bf9..ad99df10d 100644 --- a/docs/building-apps/example-application-tutorial/payment.mdx +++ b/docs/building-apps/example-application-tutorial/payment.mdx @@ -26,3 +26,342 @@ The user then inputs their pincode and clicks the "Confirm" button, which signs An asset is displayed as an asset code and issuer address. Learn more in our [Assets section](https://developers.stellar.org/docs/fundamentals-and-concepts/stellar-data-structures/assets). ::: + +## Code implementation + +### The `/dashboard/send` page + +{/* TODO: Bri, is this too much from this code sample? Should we just cut ALL of the HTML out? */} + +The `/dashboard/send` page allows the user to send payments to other Stellar addresses. They can select from a dropdown containing their contact list names, or they could enter their own "Other..." public key. The following additional features have been implemented: + +- If the destination address is _not_ a funded account, the user is informed they will be using a `createAccount` operation, and must send at least 1 XLM. +- The user can select to send/receive different assets, and paths are queried from horizon depending on: + 1. if they want to strict send or strict receive, + 2. the source/destination assets they have selected, + 3. the source/destination accounts, and + 4. the amound entered for the send/receive value. +- An optional memo field is available for text-only memos. + +For now, we'll focus on regular payments, and we'll dig into the path payments in a [later section](./path-payment). + +```svelte title="/src/routes/dashboard/send/+page.svelte" + + + + + + + + + + +{#if otherDestination} + checkDestination(otherPublicKey)} + type="text" + placeholder="G..." + class="input-bordered input" + /> +{/if} + + +{#if createAccount} + +{/if} + + +
+
+
+ +
+
+ +
+ + + + + + +``` + +### The transaction functions + +In the above page, we've made use of the `createPaymentTransaction` function. This function can be used to send a payment of any asset from one Stellar address to another. + +We also have made use of the `createCreateAccountTransaction` function above. This is used when the destination account is not currently funded and active on the Stellar network. The only asset possible in this scenario is native XLM. + +```js title="/src/lib/stellar/transactions.js" +import { + TransactionBuilder, + Networks, + Server, + Operation, + Asset, + Memo, +} from "stellar-sdk"; +import { error } from "@sveltejs/kit"; + +// We are setting a very high maximum fee, which increases our transaction's +// chance of being included in the ledger. We're making this a `const` so we can +// change it on one place as and when recommendations and/or best practices +// evolve. Current recommended fee is `100_000` stroops. +const maxFeePerOperation = "100000"; +const horizonUrl = "https://horizon-testnet.stellar.org"; +const networkPassphrase = Networks.TESTNET; +const standardTimebounds = 300; // 5 minutes for the user to review/sign/submit + +// Constructs and returns a Stellar transaction that contains a `payment` operaion and an optional memo. +export async function createPaymentTransaction({ + source, + destination, + asset, + amount, + memo, +}) { + // First, we setup our transaction by loading the source account from the + // network, and initializing the TransactionBuilder. This is the first step + // in constructing all Stellar transactions. + let server = new Server(horizonUrl); + let sourceAccount = await server.loadAccount(source); + let transaction = new TransactionBuilder(sourceAccount, { + networkPassphrase: networkPassphrase, + fee: maxFeePerOperation, + }); + + let sendAsset; + if (asset && asset !== "native") { + sendAsset = new Asset(asset.split(":")[0], asset.split(":")[1]); + } else { + sendAsset = Asset.native(); + } + + // If a memo was supplied, add it to the transaction. Here, we have the + // option of a hash memo because this is common practice by anchor transfers + if (memo) { + if (typeof memo === "string") { + transaction.addMemo(Memo.text(memo)); + } else if (typeof memo === "object") { + transaction.addMemo(Memo.hash(memo.toString("hex"))); + } + } + + // Add a single `payment` operation + transaction.addOperation( + Operation.payment({ + destination: destination, + amount: amount.toString(), + asset: sendAsset, + }), + ); + + // Before the transaction can be signed, it requires timebounds, and it must + // be "built" + let builtTransaction = transaction.setTimeout(standardTimebounds).build(); + return { + transaction: builtTransaction.toXDR(), + network_passphrase: networkPassphrase, + }; +} + +// Constructs and returns a Stellar transaction that contains a `createAccount` operation and an optional memo. +export async function createCreateAccountTransaction({ + source, + destination, + amount, + memo, +}) { + // The minimum account balance on the Stellar network is 1 XLM (2 base + // reserves). We'll check that `amount` meets or exceeds that requirement + // early, so we can fail quickly. + if (parseFloat(amount.toString()) < 1) { + throw error(400, { message: "insufficient starting balance" }); + } + + // First, we setup our transaction by loading the source account from the + // network, and initializing the TransactionBuilder. This is the first step + // in constructing all Stellar transactions. + let server = new Server(horizonUrl); + let sourceAccount = await server.loadAccount(source); + let transaction = new TransactionBuilder(sourceAccount, { + networkPassphrase: networkPassphrase, + fee: maxFeePerOperation, + }); + + // If a memo was supplied, add it to the transaction + if (memo) { + transaction.addMemo(Memo.text(memo)); + } + + // Add a single `createAccount` operation + transaction.addOperation( + Operation.createAccount({ + destination: destination, + startingBalance: amount.toString(), + }), + ); + + // Before the transaction can be signed, it requires timebounds, and it must + // be "built" + let builtTransaction = transaction.setTimeout(standardTimebounds).build(); + return { + transaction: builtTransaction.toXDR(), + network_passphrase: networkPassphrase, + }; +} +``` From f6e941a33cd47965138151e500e5a392f07234af Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Tue, 8 Aug 2023 12:54:20 -0500 Subject: [PATCH 21/46] querying data page --- .../querying-data.mdx | 315 +++++++++++++++++- 1 file changed, 308 insertions(+), 7 deletions(-) diff --git a/docs/building-apps/example-application-tutorial/querying-data.mdx b/docs/building-apps/example-application-tutorial/querying-data.mdx index 2d035bfd6..504f44018 100644 --- a/docs/building-apps/example-application-tutorial/querying-data.mdx +++ b/docs/building-apps/example-application-tutorial/querying-data.mdx @@ -3,12 +3,313 @@ title: Querying Data sidebar_position: 70 --- -Throughout the application’s functionality, it will be querying data from Horizon, Stellar’s API. Information such as account balances, transaction history, sequence numbers for transactions, asset availability, and more are stored in Horizon’s database. +Throughout the application’s functionality, it will be querying data from Horizon, one of Stellar’s APIs. Information such as account balances, transaction history, sequence numbers for transactions, asset availability, and more are stored in Horizon’s database. -Functions to query: +:::note -- loadAccount: gives the account sequence number, asset balances, trustlines, and an account object that can be used in a transaction -- fetchAccount: gives all the same information as loadAccount, but doesn’t have the account object -- getAccountBalances -- submitTransaction -- that stellar.expert thing +Other places in this tutorial, we have omitted the JSDoc descriptions and typing, for the sake of clean presentation. Here, we're including those to make these functions more copy/paste-able. + +::: + +## Imports and types + +```js file="/src/lib/stellar/horizonQueries.js" +import { error } from "@sveltejs/kit"; +import { + Server, + TransactionBuilder, + Networks, + StrKey, + Asset, +} from "stellar-sdk"; + +const horizonUrl = "https://horizon-testnet.stellar.org"; +const server = new Server(horizonUrl); + +/** + * @module $lib/stellar/horizonQueries + * @description A collection of function that helps query various information + * from the [Horizon API](https://developers.stellar.org/api/horizon). This + * allows us to abstract and simplify some interactions so we don't have to have + * _everything_ contained within our `*.svelte` files. + */ + +// We'll import some type definitions that already exists within the +// `stellar-sdk` package, so our functions will know what to expect. +/** @typedef {import('stellar-sdk').ServerApi.AccountRecord} AccountRecord */ +/** @typedef {import('stellar-sdk').Horizon.ErrorResponseData} ErrorResponseData */ +/** @typedef {import('stellar-sdk').ServerApi.PaymentOperationRecord} PaymentOperationRecord */ +/** @typedef {import('stellar-sdk').Horizon.BalanceLine} BalanceLine */ +/** @typedef {import('stellar-sdk').Horizon.BalanceLineAsset} BalanceLineAsset */ +/** @typedef {import('stellar-sdk').Transaction} Transaction */ +/** @typedef {import('stellar-sdk').ServerApi.PaymentPathRecord} PaymentPathRecord */ +``` + +## fetchAccount + +gives the account sequence number, asset balances, trustlines + +```js file="/src/lib/stellar/horizonQueries.js" +/** + * Fetches and returns details about an account on the Stellar network. + * @async + * @function fetchAccount + * @param {string} publicKey Public Stellar address to query information about + * @returns {Promise} Object containing whether or not the account is funded, and (if it is) account details + * @throws {error} Will throw an error if the account is not funded on the Stellar network, or if an invalid public key was provided. + */ +export async function fetchAccount(publicKey) { + if (StrKey.isValidEd25519PublicKey(publicKey)) { + try { + let account = await server.accounts().accountId(publicKey).call(); + return account; + } catch (err) { + // @ts-ignore + if (err.response?.status === 404) { + throw error(404, "account not funded on network"); + } else { + // @ts-ignore + throw error(err.response?.status ?? 400, { + // @ts-ignore + message: `${err.response?.title} - ${err.response?.detail}`, + }); + } + } + } else { + throw error(400, { message: "invalid public key" }); + } +} +``` + +## fetchAccountBalances + +gets existing balances for the `publicKey` + +```js file="/src/lib/stellar/horizonQueries.js" +/** + * Fetches and returns balance details for an account on the Stellar network. + * @async + * @function fetchAccountBalances + * @param {string} publicKey Public Stellar address holding balances to query + * @returns {Promise} Array containing balance information for each asset the account holds + */ +export async function fetchAccountBalances(publicKey) { + const { balances } = await fetchAccount(publicKey); + return balances; +} +``` + +## fetchRecentPayments + +finds any payments made to/from the `publicKey` (includes payments, path payments, account merges) + +```js file="/src/lib/stellar/horizonQueries.js" +/** + * Fetches and returns recent `payment`, `createAccount` operations that had an effect on this account. + * @async + * @function fetchRecentPayments + * @param {string} publicKey Public Stellar address to query recent payment operations to/from + * @param {number} [limit] Number of operations to request from the server + * @returns {Promise} Array containing details for each recent payment + */ +export async function fetchRecentPayments(publicKey, limit = 10) { + const { records } = await server + .payments() + .forAccount(publicKey) + .limit(limit) + .order("desc") + .call(); + return records; +} +``` + +## submit + +submit a signed transaction to the stellar network + +```js file="/src/lib/stellar/horizonQueries.js" +/** + * Submits a Stellar transaction to the network for inclusion in the ledger. + * @async + * @function submit + * @param {Transaction} transaction Built transaction to submit to the network + * @throws Will throw an error if the transaction is not submitted successfully. + */ +export async function submit(transaction) { + try { + await server.submitTransaction(transaction); + } catch (err) { + throw error(400, { + // @ts-ignore + message: `${err.response?.title} - ${err.response?.data.extras.result_codes}`, + }); + } +} +``` + +## fetchAssetsWithHomeDomains + +we create our own new types. then, looks at all the issuer accounts, and returns only the ones with a `home_domain` set on the account. + +```js file="/src/lib/stellar/horizonQueries.js" +/** + * @typedef {Object} HomeDomainObject + * @property {string} home_domain Domain name the issuer of this asset has set for their account on the Stellar network. + */ + +/** @typedef {BalanceLineAsset & HomeDomainObject} HomeDomainBalanceLine */ + +/** + * Fetches `home_domain` from asset issuer accounts on the Stellar network and returns an array of balances. + * @async + * @function fetchAssetsWithHomeDomains + * @param {BalanceLine[]} balances Array of balances to query issuer accounts of + * @returns {Promise} Array of balance details for assets that do have a `home_domain` setting + */ +export async function fetchAssetsWithHomeDomains(balances) { + let homeDomains = await Promise.all( + balances.map(async (asset) => { + // We are only interested in issued assets (i.e., not LPs and not XLM) + if ("asset_issuer" in asset) { + // Fetch the account from the network, and add its info to the array, along with the home_domain + let account = await fetchAccount(asset.asset_issuer); + if ("home_domain" in account) { + return { + ...asset, + home_domain: account.home_domain, + }; + } + } + }), + ); + + // Filter out any null array entries before returning + // @ts-ignore + return homeDomains.filter((balance) => balance); +} +``` + +## findStrictSendPaths + +find the available strict send paths between a source asset/amount and receiving account + +```js file="/src/lib/stellar/horizonQueries.js" +/** + * Fetches available paths on the Stellar network between the destination account, and the asset sent by the source account. + * @async + * @function findStrictSendPaths + * @param {Object} opts Options object + * @param {string} opts.sourceAsset Stellar asset which will be sent from the source account + * @param {string|number} opts.sourceAmount Amount of the Stellar asset that should be debited from the srouce account + * @param {string} opts.destinationPublicKey Public Stellar address that will receive the destination asset + * @returns {Promise} Array of payment paths that can be selected for the transaction + * @throws Will throw an error if there are no available payment paths. + */ +export async function findStrictSendPaths({ + sourceAsset, + sourceAmount, + destinationPublicKey, +}) { + let asset = + sourceAsset === "native" + ? Asset.native() + : new Asset(sourceAsset.split(":")[0], sourceAsset.split(":")[1]); + let response = await server + .strictSendPaths(asset, sourceAmount.toString(), destinationPublicKey) + .call(); + if (response.records.length > 0) { + return response.records; + } else { + throw error(400, { message: "no strict send paths available" }); + } +} +``` + +## findStrictReceivePaths + +find the available strict receive paths between a source account and receiving asset/amount + +```js file="/src/lib/stellar/horizonQueries.js" +/** + * Fetches available paths on the Stellar network between the source account, and the asset to be received by the destination. + * @async + * @function findStrictReceivePaths + * @param {Object} opts Options object + * @param {string} opts.sourcePublicKey Public Stellar address that will be the source of the payment operation + * @param {string} opts.destinationAsset Stellar asset which should be received in the destination account + * @param {string|number} opts.destinationAmount Amount of the Stellar asset that should be credited to the destination account + * @returns {Promise} Array of payment paths that can be selected for the transaction + * @throws Will throw an error if there are no available payment paths. + */ +export async function findStrictReceivePaths({ + sourcePublicKey, + destinationAsset, + destinationAmount, +}) { + let asset = + destinationAsset === "native" + ? Asset.native() + : new Asset( + destinationAsset.split(":")[0], + destinationAsset.split(":")[1], + ); + let response = await server + .strictReceivePaths(sourcePublicKey, asset, destinationAmount.toString()) + .call(); + if (response.records.length > 0) { + return response.records; + } else { + throw error(400, { message: "no strict receive paths available" }); + } +} +``` + +## that stellar.expert thing + +create our own type. retrieve the most highly-rated assets from the stellar.expert API + +```js file="/src/lib/utils/stellarExpert.js" +const network = "testnet"; +const baseUrl = `https://api.stellar.expert/explorer/${network}`; + +/** + * An asset object that has been returned by our query to Stellar.Expert + * @typedef {Object} RankedAsset + * @property {string} asset Asset identifier + * @property {number} traded_amount Total traded amount (in stroops) + * @property {number} payments_amount Total payments amount (in stroops) + * @property {number} created Timestamp of the first recorder operation with asset + * @property {number} supply Total issued asset supply + * @property {Object} trustlines Trustlines established to an asset + * @property {number} trades Total number of trades + * @property {number} payments Total number of payments + * @property {string} domain Associated `home_domain` + * @property {Object} tomlInfo Asset information from stellar.toml file + * @property {Object} rating Composite asset rating + * @property {number} paging_token Paging token + * @see {@link https://stellar.expert/openapi.html#tag/Asset-Info-API/operation/getAllAssets} + */ + +/** + * Fetches and returns the most highly rated assets, according to the Stellar.Expert calculations. + * @async + * @function fetchAssets + * @returns {Promise} Array of objects containing details for each asset + */ +export async function fetchAssets() { + let res = await fetch( + `${baseUrl}/asset?${new URLSearchParams({ + // these are all the defaults, but you could customize them if needed + search: "", + sort: "rating", + order: "desc", + limit: "10", + cursor: "0", + })}`, + ); + let json = await res.json(); + + let records = json._embedded.records; + return records; +} +``` From f30125e282240869696fac06cda9bf4b01dd6c2c Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 14 Aug 2023 10:16:11 -0500 Subject: [PATCH 22/46] Adding sources to each code sample, using `title` instead of `file` in code block headings. --- .../querying-data.mdx | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/docs/building-apps/example-application-tutorial/querying-data.mdx b/docs/building-apps/example-application-tutorial/querying-data.mdx index 504f44018..ae260bdce 100644 --- a/docs/building-apps/example-application-tutorial/querying-data.mdx +++ b/docs/building-apps/example-application-tutorial/querying-data.mdx @@ -13,7 +13,7 @@ Other places in this tutorial, we have omitted the JSDoc descriptions and typing ## Imports and types -```js file="/src/lib/stellar/horizonQueries.js" +```js title="/src/lib/stellar/horizonQueries.js" import { error } from "@sveltejs/kit"; import { Server, @@ -45,11 +45,13 @@ const server = new Server(horizonUrl); /** @typedef {import('stellar-sdk').ServerApi.PaymentPathRecord} PaymentPathRecord */ ``` +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js + ## fetchAccount gives the account sequence number, asset balances, trustlines -```js file="/src/lib/stellar/horizonQueries.js" +```js title="/src/lib/stellar/horizonQueries.js" /** * Fetches and returns details about an account on the Stellar network. * @async @@ -81,11 +83,13 @@ export async function fetchAccount(publicKey) { } ``` +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js + ## fetchAccountBalances gets existing balances for the `publicKey` -```js file="/src/lib/stellar/horizonQueries.js" +```js title="/src/lib/stellar/horizonQueries.js" /** * Fetches and returns balance details for an account on the Stellar network. * @async @@ -99,11 +103,13 @@ export async function fetchAccountBalances(publicKey) { } ``` +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js + ## fetchRecentPayments finds any payments made to/from the `publicKey` (includes payments, path payments, account merges) -```js file="/src/lib/stellar/horizonQueries.js" +```js title="/src/lib/stellar/horizonQueries.js" /** * Fetches and returns recent `payment`, `createAccount` operations that had an effect on this account. * @async @@ -123,11 +129,13 @@ export async function fetchRecentPayments(publicKey, limit = 10) { } ``` +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js + ## submit submit a signed transaction to the stellar network -```js file="/src/lib/stellar/horizonQueries.js" +```js title="/src/lib/stellar/horizonQueries.js" /** * Submits a Stellar transaction to the network for inclusion in the ledger. * @async @@ -147,11 +155,13 @@ export async function submit(transaction) { } ``` +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js + ## fetchAssetsWithHomeDomains we create our own new types. then, looks at all the issuer accounts, and returns only the ones with a `home_domain` set on the account. -```js file="/src/lib/stellar/horizonQueries.js" +```js title="/src/lib/stellar/horizonQueries.js" /** * @typedef {Object} HomeDomainObject * @property {string} home_domain Domain name the issuer of this asset has set for their account on the Stellar network. @@ -189,11 +199,13 @@ export async function fetchAssetsWithHomeDomains(balances) { } ``` +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js + ## findStrictSendPaths find the available strict send paths between a source asset/amount and receiving account -```js file="/src/lib/stellar/horizonQueries.js" +```js title="/src/lib/stellar/horizonQueries.js" /** * Fetches available paths on the Stellar network between the destination account, and the asset sent by the source account. * @async @@ -225,11 +237,13 @@ export async function findStrictSendPaths({ } ``` +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js + ## findStrictReceivePaths find the available strict receive paths between a source account and receiving asset/amount -```js file="/src/lib/stellar/horizonQueries.js" +```js title="/src/lib/stellar/horizonQueries.js" /** * Fetches available paths on the Stellar network between the source account, and the asset to be received by the destination. * @async @@ -264,11 +278,13 @@ export async function findStrictReceivePaths({ } ``` +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js + ## that stellar.expert thing create our own type. retrieve the most highly-rated assets from the stellar.expert API -```js file="/src/lib/utils/stellarExpert.js" +```js title="/src/lib/utils/stellarExpert.js" const network = "testnet"; const baseUrl = `https://api.stellar.expert/explorer/${network}`; @@ -313,3 +329,5 @@ export async function fetchAssets() { return records; } ``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/utils/stellarExpert.js From 03b7b3d7a1a847e1476a048f3af888fb60db3ff9 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 14 Aug 2023 15:54:55 -0500 Subject: [PATCH 23/46] Start on the anchor integration steps from the technical side --- .../anchor-integration.mdx | 91 ----- .../anchor-integration/index.mdx | 48 +++ .../anchor-integration/sep1.mdx | 26 ++ .../anchor-integration/sep10.mdx | 331 ++++++++++++++++++ .../anchor-integration/sep24.mdx | 24 ++ .../anchor-integration/sep6.mdx | 30 ++ 6 files changed, 459 insertions(+), 91 deletions(-) delete mode 100644 docs/building-apps/example-application-tutorial/anchor-integration.mdx create mode 100644 docs/building-apps/example-application-tutorial/anchor-integration/index.mdx create mode 100644 docs/building-apps/example-application-tutorial/anchor-integration/sep1.mdx create mode 100644 docs/building-apps/example-application-tutorial/anchor-integration/sep10.mdx create mode 100644 docs/building-apps/example-application-tutorial/anchor-integration/sep24.mdx create mode 100644 docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx diff --git a/docs/building-apps/example-application-tutorial/anchor-integration.mdx b/docs/building-apps/example-application-tutorial/anchor-integration.mdx deleted file mode 100644 index 2e68e0358..000000000 --- a/docs/building-apps/example-application-tutorial/anchor-integration.mdx +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Anchor Integration -sidebar_position: 60 ---- - -An anchor is a Stellar-specific term for the on and off-ramps that connect the Stellar network to traditional financial rails, such as financial institutions or fintech companies. When a user deposits with an anchor, that anchor will credit their Stellar account with the equivalent amount of digital tokens. The user can then hold, transfer, or trade those tokens just like any other Stellar asset. When a user withdraws those tokens, the anchor redeems them for cash in hand or money in the bank. Read more about anchors in our [Anchor Documentation](https://developers.stellar.org/docs/anchoring-assets/overview). - -When a customer downloads a wallet application that is connected to an anchor service, their Stellar account can either be created by the wallet application or the anchor service. In this example, the account has been created by the wallet application, BasicPay. Account creation strategies are described more in-depth [here](../application-design-considerations#account-creation-strategies). - -In this example, we’ll use an anchor on Stellar’s Testnet to simulate a bank transfer into and out of the user’s wallet using [SEP-6: Deposit and Withdrawal API](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md) and/or [SEP-24: Hosted Deposit and Withdrawal](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md). - -:::info - -SEPs define standards for interoperability on Stellar. Read more in our [SEPs section](../../fundamentals-and-concepts/stellar-ecosystem-proposals). - -::: - -Our integrations will also use the following SEPs: - -- [SEP-1: Stellar TOML](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md) - a file that provides a place for the Internet to find information about an organization’s Stellar integration -- [SEP-9: Standard KYC Fields](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0009.md) - defines a list of standard KYC fields for use in Stellar ecosystem protocols -- [SEP-10: Stellar Web Authentication](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md) - defines the standard way for clients to create authenticated web sessions on behalf of a user who holds a Stellar account -- [SEP-12: KYC API](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md) - defines a standard way for Stellar clients to upload KYC information to anchors - -### Setup for anchored assets - -First, we need to set up our application so it can communicate with anchors to get asset information. - -Do this by first querying an anchor’s stellar.toml file. The [stellar.toml file](https://developers.stellar.org/docs/issuing-assets/publishing-asset-info#completing-your-stellartoml) is a common place where the Internet can find information about an organization’s Stellar integration. - -For anchors, we’re interested in the `currencies` they issue, the `transfer_server` keyword that indicates if the anchor supports SEP-6, SEP-24, or both, and the `web_auth_endpoint` which allows a wallet to set up an authenticated user session. - -BasicPay is interoperating with the testing anchor located at `testanchor.stellar.org` and you can view its toml file [here](https://testanchor.stellar.org/.well-known/stellar.toml). - -### Anchor integration with SEP-6: Deposit and Withdrawal API - -SEP-6 allows wallets and other clients to interact with anchors directly without the user needing to leave the wallet to go to the anchor’s site. In this integration, a user’s KYC information is gathered and handled by the wallet. - -#### Authentication - -The user must prove they own the account before they can withdraw or deposit any assets as part of SEP-10: Stellar Web Authentication. - -To do this, the wallet makes a GET request with a public `account` param to the anchor, which sends back an unsigned Stellar transaction (called a challenge transaction) with an invalid sequence number so it doesn’t actually do anything when submitted to the network. - -In response, the user signs the transaction, and the application POSTs it back to the anchor. If the signature checks out, the success response will contain a [JSON Web Token (JWT)](https://jwt.io/), which is stored in the `webAuthStore` store to use for future interactions with the anchor. - -#### Get `/info` - -First, BasicPay requests the `/info` endpoint from the anchor to understand the supported transfer methods ([deposit, withdraw, deposit-exchange, and withdraw-exchange](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md)) and fee information. - -#### Initiate transfer - -The user then can initiate one of the transfer methods (in BasicPay, only deposits and withdraws are supported) by selecting “Deposit” or “Withdraw” from the drop-down menu and specifying the asset to be deposited or withdrawn. KYC - -BasicPay then queries the anchor’s `sep-12` endpoint for the required KYC fields and presents these fields to the user. The user inputs this information and BasicPay PUTs that information to the KYC `/customer` endpoint. BasicPay then waits for the user’s `status` with the anchor to be approved. - -#### Complete transfer - -BasicPay then prompts the user to input additional information such as transfer type, destination, and amount. - -Once approved, the user clicks “Next” and BasicPay initiates the transfer with the anchor. - -In a withdrawal transaction, BasicPay will also present the user with a pre-built transaction for them to sign with their pincode. - -:::info - -All the fields that have been collected during this process are wrapped into a URL that contains query parameters: [example](https://testanchor.stellar.org/sep6/deposit?account=GAXQIC2BSZ5HZP3BD6RZQSD3LB66TB6A2TA5W3LZX2VDFMBAKHC4B62J&asset_code=SRT&type=bank_account&amount=11) - -::: - -### Anchor integration with SEP-24: Hosted Deposit and Withdrawal - -SEP-24 provides a standard way for wallets and anchors to interact by having the user open a webview hosted by an anchor to collect and handle KYC information. - -#### Authentication - -The user must first prove they own the account before they can withdraw or deposit any assets as part of SEP-10: Stellar Web Authentication. In BasicPay, the user clicks on the “Authenticate” button, triggering a challenge transaction from the anchor to BasicPay as part of SEP-10: Stellar Web Authentication, which is then presented to the user to sign. - -Once signed, BasicPay sends the transaction back to the anchor and then receives a session auth token, which is stored in the `webAuthStore` store. - -#### Get `/info` - -Similar to SEP-6, our application will request the `/info` endpoint from the anchor to understand the supported transfer methods (deposit, withdraw, deposit-exchange, and withdraw-exchange) and fee information. - -#### Initiate and complete transfer - -The user then initiates a transfer method (in BasicPay, only deposits and withdraws are supported) by POSTing a request to either the “SEP-24 Deposit” or “SEP-24 Withdraw” endpoint. The anchor then sends an interactive URL that BasicPay opens for the user to complete and confirm the transaction. - -Once the user clicks “Submit”, they’ll be brought back to the application. - -In a withdrawal transaction, BasicPay will also present the user with a pre-built transaction for them to sign with their pincode. `callback` should be in the form of a `postMessage`. Our application listens for that `postMessage` during the withdrawal and opens up the transaction dialog when the interactive flow is completed. diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/index.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/index.mdx new file mode 100644 index 000000000..e96d8063c --- /dev/null +++ b/docs/building-apps/example-application-tutorial/anchor-integration/index.mdx @@ -0,0 +1,48 @@ +--- +title: Anchor Integration +sidebar_position: 60 +--- + +An anchor is a Stellar-specific term for the on and off-ramps that connect the Stellar network to traditional financial rails, such as financial institutions or fintech companies. When a user deposits with an anchor, that anchor will credit their Stellar account with the equivalent amount of digital tokens. The user can then hold, transfer, or trade those tokens just like any other Stellar asset. When a user withdraws those tokens, the anchor redeems them for cash in hand or money in the bank. Read more about anchors in our [Anchor Documentation](https://developers.stellar.org/docs/anchoring-assets/overview). + +When a customer downloads a wallet application that is connected to an anchor service, their Stellar account can either be created by the wallet application or the anchor service. In this example, the account has been created by the wallet application, BasicPay. Account creation strategies are described more in-depth [here](../application-design-considerations#account-creation-strategies). + +In this example, we’ll use an anchor on Stellar’s Testnet to simulate a bank transfer into and out of the user’s wallet using [SEP-6: Deposit and Withdrawal API](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md) and/or [SEP-24: Hosted Deposit and Withdrawal](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md). + +:::info + +SEPs define community-decided standards for interoperability on Stellar. Read more in our [SEPs section](../../../fundamentals-and-concepts/stellar-ecosystem-proposals). + +::: + +Our integrations will also use the following SEPs: + +- [SEP-1: Stellar TOML](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0001.md) - a file that provides a place for the Internet to find information about an organization’s Stellar integration +- [SEP-9: Standard KYC Fields](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0009.md) - defines a list of standard KYC fields for use in Stellar ecosystem protocols +- [SEP-10: Stellar Web Authentication](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0010.md) - defines the standard way for clients to create authenticated web sessions on behalf of a user who holds a Stellar account +- [SEP-12: KYC API](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0012.md) - defines a standard way for Stellar clients to upload KYC information to anchors + +## Setup for anchored assets + +First, we need our application to know how it can communicate with anchors to get asset and infrastructure information. Do this by first querying an anchor’s stellar.toml file. + +BasicPay takes care of all the anchor transfer details on the `/dashboard/transfers` page. See it in action here: https://basicpay.pages.dev/dashboard/transfers + +The first thing we'll do is determine whether the user holds trustlines to any assets the have a `home_domain` field set on the Stellar network. If so, we'll display some interactive elements to the user for that asset/domain. + +```js title=/src/routes/dashboard/transfers/+page.js +import { fetchAssetsWithHomeDomains } from "$lib/stellar/horizonQueries"; + +/** @type {import('./$types').PageLoad} */ +export async function load({ parent }) { + const { balances } = await parent(); + return { + /** @type {import('$lib/stellar/horizonQueries').HomeDomainBalanceLine[]} */ + homeDomainBalances: await fetchAssetsWithHomeDomains(balances), + }; +} +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.js + +Now we know if there are any assets the user holds that may have the necessary infrastructure for authenticated transfers. So, we can query the domain in question for any relevant details. diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/sep1.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/sep1.mdx new file mode 100644 index 000000000..a80408ce4 --- /dev/null +++ b/docs/building-apps/example-application-tutorial/anchor-integration/sep1.mdx @@ -0,0 +1,26 @@ +--- +title: "SEP-1: Stellar TOML" +sidebar_position: 10 +--- + +The [stellar.toml file](https://developers.stellar.org/docs/issuing-assets/publishing-asset-info#completing-your-stellartoml) is a common place where the Internet can find information about an organization’s Stellar integration. Regardless of which type of transfer we want to use (SEP-6 or SEP-24), we'll need to start with SEP-1. + +For anchors, we’re interested in the `CURRENCIES` they issue, the `TRANSFER_SERVER` and/or `TRANSFER_SERVER_SEP0024` keywords that indicate if the anchor supports SEP-6, SEP-24, or both, and the `WEB_AUTH_ENDPOINT` which allows a wallet to set up an authenticated user session. + +BasicPay is interoperating with the testing anchor located at `testanchor.stellar.org` and you can view its toml file [here](https://testanchor.stellar.org/.well-known/stellar.toml). + +```js title=/src/lib/stellar/sep1.js +import { StellarTomlResolver } from "stellar-sdk"; + +// Fetches and returns the stellar.toml file hosted by a provided domain. +export async function fetchStellarToml(domain) { + let stellarToml = await StellarTomlResolver.resolve(domain); + return stellarToml; +} +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js + +Strictly speaking, the `StellarTomlResolver` function from the JavaScript SDK is the only function we _need_ to retrieve and use the information provided by the anchor (heck, we could even just write our own `fetch`-based function, and bypass the SDK altogether). However, we've created quite a few "helper" functions to make the rest of our queries a bit more verbose and clear as to what we're looking for from the anchor server. Make sure to check out the `sep1.js` source file linked above! + +Using the `stellar.toml` information for an asset with a `home_domain`, we can display to the user some options (depending on the available infrastructure). We'll start with SEP-10 authentication. diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/sep10.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/sep10.mdx new file mode 100644 index 000000000..01d5d0114 --- /dev/null +++ b/docs/building-apps/example-application-tutorial/anchor-integration/sep10.mdx @@ -0,0 +1,331 @@ +--- +title: "SEP-10: Stellar Web Authentication" +sidebar_position: 20 +--- + +Similar to the SEP-1 information, both SEP-6 and SEP-24 protocols make use of SEP-10 for authentication with the user. The user must prove they own the account before they can withdraw or deposit any assets as part of SEP-10: Stellar Web Authentication. + +Since we have the `stellar.toml` file information already, we can use that to display some interactive elements to the user. + +## Prompt for authentication + +:::note + +The `/src/routes/dashboard/transfers/+page.svelte` is doing **a lot** of work throughout these sections, and we are chopping it up in various ways for display as part of this tutorial. For a full picture of this file, please remember to check the source code. + +::: + +```svelte title=/src/routes/dashboard/transfers/+page.svelte + + + + +{#each data.homeDomainBalances as asset} + {#await fetchStellarToml(asset.home_domain) then stellarToml} + {#if 'WEB_AUTH_ENDPOINT' in stellarToml || 'TRANSFER_SERVER' in stellarToml} + {@const authStatus = getAuthStatus(asset.home_domain)} +

+ {asset.asset_code} ({asset.home_domain}) +
{authStatus}
+

+ {#if authStatus !== 'auth_valid'} + + + {:else} + + {/if} + {/if} + {/await} +{/each} +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte + +## Requesting a challenge transaction + +Now, when the user clicks the "authenticate" button, it triggers the `auth` function. + +```svelte title=/src/routes/dashboard/transfers/+page.svelte + +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte + +As part of the `auth` function, BasicPay makes a `GET` request with an `account` param (the public key of the user) to the anchor, which sends back a Stellar transaction signed by the server's signing key (called a challenge transaction) with an invalid sequence number so it couldn't actually do anything if it were accidentally submitted to the network. + +```js title=/src/lib/stellar/sep10.js +import { Utils } from "stellar-sdk"; +import { fetchStellarToml } from "$lib/stellar/sep1"; + +// Requests, validates, and returns a SEP-10 challenge transaction from an anchor server. +export async function getChallengeTransaction({ publicKey, homeDomain }) { + let { WEB_AUTH_ENDPOINT, TRANSFER_SERVER, SIGNING_KEY } = + await fetchStellarToml(homeDomain); + + // In order for the SEP-10 flow to work, we must have at least a server + // signing key, and a web auth endpoint (which can be the transfer server as + // a fallback) + if (!WEB_AUTH_ENDPOINT || !TRANSFER_SERVER || !SIGNING_KEY) { + throw error(500, { + message: + "could not get challenge transaction (server missing toml entry or entries)", + }); + } + + // Request a challenge transaction for the users's account + let res = await fetch( + `${WEB_AUTH_ENDPOINT || TRANSFER_SERVER}?${new URLSearchParams({ + // Possible parameters are `account`, `memo`, `home_domain`, and + // `client_domain`. For our purposes, we only supply `account`. + account: publicKey, + })}`, + ); + let json = await res.json(); + + // Validate the challenge transaction meets all the requirements for SEP-10 + validateChallengeTransaction({ + transactionXDR: json.transaction, + serverSigningKey: SIGNING_KEY, + network: json.network_passphrase, + clientPublicKey: publicKey, + homeDomain: homeDomain, + }); + return json; +} + +// Validates the correct structure and information in a SEP-10 challenge transaction. +function validateChallengeTransaction({ + transactionXDR, + serverSigningKey, + network, + clientPublicKey, + homeDomain, + clientDomain, +}) { + if (!clientDomain) { + clientDomain = homeDomain; + } + + try { + // Use the `readChallengeTx` function from Stellar SDK to read and + // verify most of the challenge transaction information + let results = Utils.readChallengeTx( + transactionXDR, + serverSigningKey, + network, + homeDomain, + clientDomain, + ); + // Also make sure the transaction was created for the correct user + if (results.clientAccountID === clientPublicKey) { + return; + } else { + throw error(400, { + message: "clientAccountID does not match challenge transaction", + }); + } + } catch (err) { + throw error(400, { message: JSON.stringify(err) }); + } +} +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep10.js + +## Sign and submit the challenge transaction + +In response, the user signs the transaction. You may have noticed we present this challenge transaction to the user with our regular confirmation modal. Once they've signed the transaction, the application sends it back to the anchor with a `POST` request. If the signature checks out, the success response will contain a [JSON Web Token (JWT)](https://jwt.io/), which BasicPay stores in the `webAuthStore` store to use for future interactions with the anchor. + +```html title=/src/routes/dashboard/transfers/+page.svelte + +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte + +The `submitChallengeTransaction` function is quite simple. We take the transaction (in XDR format) and the domain name, and submit it to the relevant `WEB_AUTH_ENDPOINT` provided by the home domain's `stellar.toml` file. + +```js title=/src/lib/stellar/sep10.js +// Submits a SEP-10 challenge transaction to an authentication server and returns the SEP-10 token. +export async function submitChallengeTransaction({ + transactionXDR, + homeDomain, +}) { + let webAuthEndpoint = await getWebAuthEndpoint(homeDomain); + + if (!webAuthEndpoint) + throw error(500, { + message: "could not authenticate with server (missing toml entry)", + }); + let res = await fetch(webAuthEndpoint, { + method: "POST", + mode: "cors", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ transaction: transactionXDR }), + }); + let json = await res.json(); + + if (!res.ok) { + throw error(400, { message: json.error }); + } + return json.token; +} +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep10.js + +## About the `webAuthStore` store + +Like so much of our BasicPay application, the various authentication tokens the user may have accumulated over time are stored in the browser's `localStorage`. There's not much special about this particular store, but here's how we put it together. + +```js title=/src/lib/stores/webAuthStore.js +import { get } from "svelte/store"; +import { persisted } from "svelte-local-storage-store"; +import { Buffer } from "buffer"; + +function createWebAuthStore() { + const { subscribe, update } = persisted("bpa:webAuthStore", {}); + + return { + subscribe, + + // Stores a JWT authentication token associated with a home domain server. + setAuth: (homeDomain, token) => + update((store) => { + return { + ...store, + [homeDomain]: token, + }; + }), + + // Determine whether or not a JSON web token has an expiration date in the future or in the past. + isTokenExpired: (homeDomain) => { + let token = get(webAuthStore)[homeDomain]; + if (token) { + let payload = JSON.parse( + Buffer.from(token.split(".")[1], "base64").toString(), + ); + let timestamp = Math.floor(Date.now() / 1000); + return timestamp > payload.exp; + } else { + return undefined; + } + }, + }; +} + +export const webAuthStore = createWebAuthStore(); +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stores/webAuthStore.js + +Now that we have successfully authenticated our user with an asset anchor, we can display and process the various transfer capabilities of the anchor in question. We'll begin with SEP-24, since there are fewer implemention steps. diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/sep24.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/sep24.mdx new file mode 100644 index 000000000..1963f9521 --- /dev/null +++ b/docs/building-apps/example-application-tutorial/anchor-integration/sep24.mdx @@ -0,0 +1,24 @@ +--- +title: "SEP-24: Hosted Deposit and Withdrawal" +sidebar_position: 30 +--- + +SEP-24 provides a standard way for wallets and anchors to interact by having the user open a webview hosted by an anchor to collect and handle KYC information. + +#### Authentication + +The user must first prove they own the account before they can withdraw or deposit any assets as part of SEP-10: Stellar Web Authentication. In BasicPay, the user clicks on the “Authenticate” button, triggering a challenge transaction from the anchor to BasicPay as part of SEP-10: Stellar Web Authentication, which is then presented to the user to sign. + +Once signed, BasicPay sends the transaction back to the anchor and then receives a session auth token, which is stored in the `webAuthStore` store. + +#### Get `/info` + +Similar to SEP-6, our application will request the `/info` endpoint from the anchor to understand the supported transfer methods (deposit, withdraw, deposit-exchange, and withdraw-exchange) and fee information. + +#### Initiate and complete transfer + +The user then initiates a transfer method (in BasicPay, only deposits and withdraws are supported) by POSTing a request to either the “SEP-24 Deposit” or “SEP-24 Withdraw” endpoint. The anchor then sends an interactive URL that BasicPay opens for the user to complete and confirm the transaction. + +Once the user clicks “Submit”, they’ll be brought back to the application. + +In a withdrawal transaction, BasicPay will also present the user with a pre-built transaction for them to sign with their pincode. `callback` should be in the form of a `postMessage`. Our application listens for that `postMessage` during the withdrawal and opens up the transaction dialog when the interactive flow is completed. diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx new file mode 100644 index 000000000..18c4bb06d --- /dev/null +++ b/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx @@ -0,0 +1,30 @@ +--- +title: "SEP-6: Deposit and Withdrawal API" +sidebar_position: 40 +--- + +SEP-6 allows wallets and other clients to interact with anchors directly without the user needing to leave the wallet to go to the anchor’s site. In this integration, a user’s KYC information is gathered and handled by the wallet. + +#### Get `/info` + +First, BasicPay requests the `/info` endpoint from the anchor to understand the supported transfer methods ([deposit, withdraw, deposit-exchange, and withdraw-exchange](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md)) and fee information. + +#### Initiate transfer + +The user then can initiate one of the transfer methods (in BasicPay, only deposits and withdraws are supported) by selecting “Deposit” or “Withdraw” from the drop-down menu and specifying the asset to be deposited or withdrawn. KYC + +BasicPay then queries the anchor’s `sep-12` endpoint for the required KYC fields and presents these fields to the user. The user inputs this information and BasicPay PUTs that information to the KYC `/customer` endpoint. BasicPay then waits for the user’s `status` with the anchor to be approved. + +#### Complete transfer + +BasicPay then prompts the user to input additional information such as transfer type, destination, and amount. + +Once approved, the user clicks “Next” and BasicPay initiates the transfer with the anchor. + +In a withdrawal transaction, BasicPay will also present the user with a pre-built transaction for them to sign with their pincode. + +:::info + +All the fields that have been collected during this process are wrapped into a URL that contains query parameters: [example](https://testanchor.stellar.org/sep6/deposit?account=GAXQIC2BSZ5HZP3BD6RZQSD3LB66TB6A2TA5W3LZX2VDFMBAKHC4B62J&asset_code=SRT&type=bank_account&amount=11) + +::: From cff066be3d54888d8add2582dabbe93d13b8f3cb Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 14 Aug 2023 16:01:58 -0500 Subject: [PATCH 24/46] linting an error or two in a disbursement platform file? --- docs/stellar-disbursement-platform/getting-started.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/stellar-disbursement-platform/getting-started.mdx b/docs/stellar-disbursement-platform/getting-started.mdx index 34a11e326..e3591d829 100644 --- a/docs/stellar-disbursement-platform/getting-started.mdx +++ b/docs/stellar-disbursement-platform/getting-started.mdx @@ -243,7 +243,7 @@ SECRET_SEP24_INTERACTIVE_URL_JWT_SECRET: SECRET_SEP24_MORE_INFO_URL_JWT_SECRET: # used to encrypt passwords of the SDP users # NOTE: you'll need to recreate any existing users in the database if this is reset -EC256_PRIVATE_KEY: +EC256_PRIVATE_KEY: ``` @@ -326,7 +326,7 @@ var DefaultWalletsNetworkMap = WalletsNetworkMapType{ -Once you’ve added the new wallet, make sure the wallet has whitelisted your SDP domain (the domain that appears in the deep link). +Once you’ve added the new wallet, make sure the wallet has whitelisted your SDP domain (the domain that appears in the deep link). Now you should be set with whichever countries and wallets you want available for new disbursements! From 4296c14e56f79eec7eefcd426d7918e86bdb75fb Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 14 Aug 2023 18:44:04 -0500 Subject: [PATCH 25/46] Fixing a broken link --- .../example-application-tutorial/anchor-integration/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/index.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/index.mdx index e96d8063c..842f9a70b 100644 --- a/docs/building-apps/example-application-tutorial/anchor-integration/index.mdx +++ b/docs/building-apps/example-application-tutorial/anchor-integration/index.mdx @@ -5,7 +5,7 @@ sidebar_position: 60 An anchor is a Stellar-specific term for the on and off-ramps that connect the Stellar network to traditional financial rails, such as financial institutions or fintech companies. When a user deposits with an anchor, that anchor will credit their Stellar account with the equivalent amount of digital tokens. The user can then hold, transfer, or trade those tokens just like any other Stellar asset. When a user withdraws those tokens, the anchor redeems them for cash in hand or money in the bank. Read more about anchors in our [Anchor Documentation](https://developers.stellar.org/docs/anchoring-assets/overview). -When a customer downloads a wallet application that is connected to an anchor service, their Stellar account can either be created by the wallet application or the anchor service. In this example, the account has been created by the wallet application, BasicPay. Account creation strategies are described more in-depth [here](../application-design-considerations#account-creation-strategies). +When a customer downloads a wallet application that is connected to an anchor service, their Stellar account can either be created by the wallet application or the anchor service. In this example, the account has been created by the wallet application, BasicPay. Account creation strategies are described more in-depth [here](../../application-design-considerations#account-creation-strategies). In this example, we’ll use an anchor on Stellar’s Testnet to simulate a bank transfer into and out of the user’s wallet using [SEP-6: Deposit and Withdrawal API](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0006.md) and/or [SEP-24: Hosted Deposit and Withdrawal](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md). From 76dd53438709bf3dab285d3f159ef2cfebbb6bb3 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Tue, 15 Aug 2023 14:15:23 -0600 Subject: [PATCH 26/46] overview updates --- .../example-application-tutorial/overview.mdx | 53 +++++++++++-------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/docs/building-apps/example-application-tutorial/overview.mdx b/docs/building-apps/example-application-tutorial/overview.mdx index c781d36aa..52e519cb0 100644 --- a/docs/building-apps/example-application-tutorial/overview.mdx +++ b/docs/building-apps/example-application-tutorial/overview.mdx @@ -3,13 +3,19 @@ title: Overview sidebar_position: 10 --- +:::note + +This tutorial walks through how to build an application with the [`js-stellar-sdk`], to build with the Wallet SDK, please follow the [Build a Wallet tutorial](../wallet/overview). + +::: + In this tutorial, we'll walk through the steps needed to build a basic payment application on Stellar's Testnet. After this tutorial, you should have a good understanding of the fundamental Stellar concepts and a solid base for iterative development. For this tutorial, we'll walk through the steps as we build a sample application we've called [BasicPay], which will be used to showcase various features. :::caution -**Although BasicPay is a full-fledged application on Stellar's Testnet, it has been built solely to showcase Stellar functionality for the educational purposes of this tutorial, not to be copied, pasted, and used on Mainnet.** +Although BasicPay is a full-fledged application on Stellar's Testnet, it has been built solely to showcase Stellar functionality for the educational purposes of this tutorial, not to be copied, pasted, and used on Mainnet. ::: @@ -19,18 +25,22 @@ For this tutorial, we'll walk through the steps as we build a sample application To build a basic Stellar application, you'll need: -- Application framework (for BasicPay, we use [SvelteKit] opting for JavaScript with JSDoc typing). SvelteKit is quite flexible, although we are _mainly_ using it for its routing capabilities. We could use it for quite a bit more, but we've worked to minimize how much of a "SvelteKit tutorial" this project is. -- Frontend framework (for BasicPay, we're using [DaisyUI] to simplify the use of [Tailwind CSS]) -- A way to interact with the Stellar network (for BasicPay, we use the [`js-stellar-sdk`], but you could use traditional fetch requests). The [`js-stellar-sdk`] is also used for building transactions to submit to the Stellar network. -- A way to interact with the user's keypair (for BasicPay, we are using the [`js-stellar-wallets` SDK], but you can opt to use an existing wallet) +- Application framework: we're using [SvelteKit] opting for JavaScript with JSDoc typing. SvelteKit is quite flexible and could be used for a lot, but we are mainly using it for its routing capabilities to minimize this being a "SvelteKit tutorial". +- Frontend framework: we're using [DaisyUI] to simplify the use of [Tailwind CSS]. +- A way to interact with the Stellar network: we're using the [`js-stellar-sdk`], but you could use traditional fetch requests. The [`js-stellar-sdk`] is also used for building transactions to submit to the Stellar network. +- A way to interact with the user's keypair: we're using the [`js-stellar-wallets` SDK], but you can opt to use an existing wallet. -While we are using the above components to construct our application, we have done our best to build it in such a way that dependency on any one of these things is minimized. Ideally, you should be able to use the JavaScript code we've written and plug it into any other framework you'd like with minimal effort. +:::note + +While we are using the above components to construct our application, we have done our best to write this tutorial in such a way that dependency on any one of these things is minimized. Ideally, you should be able to use the JavaScript code we've written and plug it into any other framework you'd like with minimal effort. + +::: -We've made the following choices during the development of this application that you may need to consider as you follow this project: +We've made the following choices during the development of BasicPay that you may also need to consider as you follow along: -- We've designed this app with a desktop in mind. For the most part, the app is responsive to various screen sizes, but we have _chosen_ not to go out of our way to prioritize the mobile user experience. +- We've designed this app for desktop. For the most part, the app is responsive to various screen sizes, but we have _chosen_ not to go out of our way to prioritize the mobile user experience. - We have enabled the default DaisyUI "light" and "dark" themes, which should switch with the preferences of your device. There is no toggle switch enabled, though. -- This is written as a client-side application. No server-side actions actually take place. If you are building an application with a backend and frontend, you will need to consider carefully which information lives where, and especially so when a user's secret key is concerned. +- This is written as a client-side application. No server-side actions actually take place. If you are building an application with a backend and frontend, you will need to consider carefully which information lives where, especially when a user's secret key is involved. - We're deploying this as a static "single-page application" with [Cloudflare Pages]. Your own deployment decisions will have an impact on your configuration and build process. - 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. @@ -44,14 +54,14 @@ This tutorial is probably best viewed as "_nearly_ comprehensive." We aren't goi ### Dev helpers -- [Stellar Laboratory]: An experimental playground to interact with the Stellar network +- [Stellar Laboratory]: an experimental playground to interact with the Stellar network - [Friendbot]: a bot that funds accounts with 10,000 fake XLM on Stellar's Testnet -- [Testnet toml file]: An example `stellar.toml` file that demonstrates what information an anchor might publish -- [BasicPay's "Dev Helpers" Page]: If you're _using_ the BasicPay application, we've created a few +- [Testnet toml file]: an example `stellar.toml` file that demonstrates what information an anchor might publish +- [BasicPay dev helpers]: if you're _using_ the BasicPay application, we've created a few helpful tools to help you explore its functionality ## Getting started -Here are the steps we've taken in order to build BasicPay. Feel free to be inspired and customize these directions as you may need. The entire [BasicPay codebase] is freely open and available on GitHub for reference. +Here are the steps we've taken to start building BasicPay. Feel free to be inspired and customize these directions as you see fit. The entire [BasicPay codebase] is freely open and available on GitHub for reference. :::note @@ -67,7 +77,7 @@ The first thing we'll need to do is create a SvelteKit app, using `npm`, we are npm create svelte@latest my-basic-payment-app ``` -This will walk you through the SvelteKit creation process, asking you about all the various options. We've chosen the following options: +This will walk you through the SvelteKit creation process, asking you about the various options. We've chosen the following options: - **Which Svelte app template?** Skeleton project - **Are you type checking with TypeScript?** Yes, using JavaScript with JSDoc comments @@ -121,9 +131,9 @@ export default config; Next, you can configure the `tailwind.config.js` file. -1. We import the `daisyui` and `typography` plugins -2. We configure our content paths (you may need to modify these values, depending on your project structure) -3. We add the `daisyui` plugin **after** any officialy `@tailwindcss` plugins (only `typography` in our example) +1. Import the `daisyui` and `typography` plugins +2. Configure our content paths (you may need to modify these values depending on your project structure) +3. Add the `daisyui` plugin **after** any officialy `@tailwindcss` plugins (only `typography` in our example) ```js title="/tailwind.config.js" // highlight-start @@ -153,7 +163,7 @@ Add your tailwind directives to your app's main CSS file. @tailwind utilities; ``` -Then import the CSS file into your base SvelteKit layout. (You may need to create this file.) +Then import the CSS file into your base SvelteKit layout (you may need to create this file). ```svelte title="/src/routes/+layout.svelte" + + + +{#each data.homeDomainBalances as asset} + {#await fetchStellarToml(asset.home_domain) then stellarToml} + {#if 'WEB_AUTH_ENDPOINT' in stellarToml || 'TRANSFER_SERVER' in stellarToml} + {@const authStatus = getAuthStatus(asset.home_domain)} +

+ {asset.asset_code} ({asset.home_domain}) +
{authStatus}
+

+ {#if authStatus !== 'auth_valid'} + + {:else} + + {#if 'TRANSFER_SERVER' in stellarToml} + {#await getSep6Info(asset.home_domain) then sep6Info} +

SEP-6 Transfers

+ {#each Object.entries(sep6Info) as [endpoint, details]} + {#if (endpoint === 'deposit' || endpoint === 'withdraw') && asset.asset_code in details} + + {/if} + {/each} + {/await} + {/if} + {/if} + {/if} + {/await} +{/each} +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte + +## A special SEP-6 modal component + +If you recall back to our [confirmation modal section](../confirmation-modal.mdx), we designed our modal component to be useful for anything we might require. Well, that's _almost_ true. The fact is that SEP-6 interactions are just plain complex. To facilitate that complexity, we've created a purpose-built SEP-6 transfer modal. There is **so much** to it, that we couldn't possibly cover everything it does here. However, we'll cover the main bits and link to the relevant source files. + +The modal component itself has been broken into several smaller Svelte components. Check out this source file to start looking through how we've put it together: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/TransferModalSep6.svelte + +{/* TODO: Bri, is that enough of a description/link to give users? Given we're trying to make this less about Svelte, and more about the Stellar interactions, it feels ok, but would love a sanity check? */} + +### Launching the SEP-6 modal + +The above buttons will use the `launchTransferModalSep6` function to display the modal to the user. Here's how it's defined in that same file. + +```html title=/src/routes/dashboard/transfers/+page.svelte + +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte + +Once launched, the `TransferModalSep6` will walk the user through a "wizard" to gather all the required information and utlimately create the transfer. + +### Modal step 1: Transfer details + +BasicPay then prompts the user to input additional information such as transfer type, destination, and amount. Some of this is prepopulated based on which button the user clicked. However, the user can change any of the fields if they so choose. + +We'll spare the code sample in this section, since it's mostly Svelte things going on. You can view the source here: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/TransferDetails.svelte + +### Modal step 2: Gather KYC information + +To find out what infrastructure the anchor has made available for us to use, we need to query the anchor's SEP-1 `stellar.toml` file for the `KYC_SERVER` field. If this is not defined, BasicPay will fallback to using the `TRANSFER_SERVER` for these requests. + +```js title=/src/lib/stellar/sep1.js +// Fetches and returns the endpoint used for SEP-12 KYC interactions. +export async function getKycServer(domain) { + let { KYC_SERVER, TRANSFER_SERVER } = await fetchStellarToml(domain); + // If `KYC_SERVER` is undefined in the domain's TOML file, `TRANSFER_SERVER` + // will be used + return KYC_SERVER ?? TRANSFER_SERVER; +} +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js + +Our SEP-6 modal then queries the anchor’s SEP-12 endpoint for the required KYC fields with a `GET` request, and we present these fields for the user to complete. + +```js title=/src/lib/stellar/sep12.js +import { getKycServer } from "$lib/stellar/sep1"; + +// Sends a `GET` request to query KYC status for a customer, returns current status of KYC submission +export async function getSep12Fields({ authToken, homeDomain }) { + let kycServer = await getKycServer(homeDomain); + + let res = await fetch(`${kycServer}/customer`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${authToken}`, + }, + }); + let json = await res.json(); + + return json; +} +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js + +Again, the presentation of the fields the user must complete is more on the Svelte side of things, so we won't share those details here. However, the source for this component is available here: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/KYCInformation.svelte + +### Modal step 3: Put KYC fields and report status + +Now that the user has provided the necessary information for the KYC requirements of the anchor, we can submit them to the anchor's KYC server with a `PUT` request. + +```js title=/src/lib/stellar/sep12.js +// Sends a `PUT` request to the KYC server, submitting the supplied fields for the customer's record. +export async function putSep12Fields({ authToken, fields, homeDomain }) { + let kycServer = await getKycServer(homeDomain); + + let res = await fetch(`${kycServer}/customer`, { + method: "PUT", + mode: "cors", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${authToken}`, + }, + body: JSON.stringify(fields), + }); + let json = await res.json(); + + return json; +} +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js + +BasicPay receives back from the anchor a status message for the user to see. Once the status message is `ACCEPTED`, we can finally submit the actual transfer request! + +### Modal step 4: Submit transfer + +What BasicPay actually does to make this request is it takes all the fields that have been collected during this process wraps them into a URL that contains query parameters: [example](https://testanchor.stellar.org/sep6/deposit?account=GAXQIC2BSZ5HZP3BD6RZQSD3LB66TB6A2TA5W3LZX2VDFMBAKHC4B62J&asset_code=SRT&type=bank_account&amount=11) + +We submit a `GET` request to the URL with our authorization token in the headers, and the anchor takes it from there! + +```js title=/src/lib/stellar/sep6.js +// Initiates a transfer using the SEP-6 protocol. +export async function initiateTransfer6({ + authToken, + endpoint, + formData, + domain, +}) { + let transferServer = await getTransferServerSep6(domain); + let searchParams = new URLSearchParams(formData); + + let res = await fetch(`${transferServer}/${endpoint}?${searchParams}`, { + method: "GET", + mode: "cors", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${authToken}`, + }, + }); + let json = await res.json(); + + if (!res.ok) { + throw error(res.status, { + message: json.error, + }); + } else { + return json; + } +} +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js + +We then display the transfer server's response to the user, and wait for them to close the modal. + +### (Sometimes) Modal step 5: Send a Stellar payment + +In a withdrawal transaction, BasicPay will also present the user with a pre-built transaction for them to sign with their pincode. Here we will finally get to move back to our "regular" modal that _is_ so good at so many things! + +```html title=/src/routes/dashboard/transfers/+page.svelte + +``` + +Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte From 50a4f9020f62863d0a3a15700227d6b67632e79c Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Tue, 15 Aug 2023 15:40:15 -0600 Subject: [PATCH 34/46] update anchor integration --- .../anchor-integration/sep1.mdx | 4 ++-- .../anchor-integration/sep10.mdx | 14 +++++++------- .../anchor-integration/{index.mdx => setup.mdx} | 10 +++++----- 3 files changed, 14 insertions(+), 14 deletions(-) rename docs/building-apps/example-application-tutorial/anchor-integration/{index.mdx => setup.mdx} (88%) diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/sep1.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/sep1.mdx index a80408ce4..e926d3618 100644 --- a/docs/building-apps/example-application-tutorial/anchor-integration/sep1.mdx +++ b/docs/building-apps/example-application-tutorial/anchor-integration/sep1.mdx @@ -1,6 +1,6 @@ --- title: "SEP-1: Stellar TOML" -sidebar_position: 10 +sidebar_position: 20 --- The [stellar.toml file](https://developers.stellar.org/docs/issuing-assets/publishing-asset-info#completing-your-stellartoml) is a common place where the Internet can find information about an organization’s Stellar integration. Regardless of which type of transfer we want to use (SEP-6 or SEP-24), we'll need to start with SEP-1. @@ -19,7 +19,7 @@ export async function fetchStellarToml(domain) { } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js Strictly speaking, the `StellarTomlResolver` function from the JavaScript SDK is the only function we _need_ to retrieve and use the information provided by the anchor (heck, we could even just write our own `fetch`-based function, and bypass the SDK altogether). However, we've created quite a few "helper" functions to make the rest of our queries a bit more verbose and clear as to what we're looking for from the anchor server. Make sure to check out the `sep1.js` source file linked above! diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/sep10.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/sep10.mdx index 01d5d0114..f4d4f05de 100644 --- a/docs/building-apps/example-application-tutorial/anchor-integration/sep10.mdx +++ b/docs/building-apps/example-application-tutorial/anchor-integration/sep10.mdx @@ -71,7 +71,7 @@ The `/src/routes/dashboard/transfers/+page.svelte` is doing **a lot** of work th {/each} ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte ## Requesting a challenge transaction @@ -124,7 +124,7 @@ Now, when the user clicks the "authenticate" button, it triggers the `auth` func ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte As part of the `auth` function, BasicPay makes a `GET` request with an `account` param (the public key of the user) to the anchor, which sends back a Stellar transaction signed by the server's signing key (called a challenge transaction) with an invalid sequence number so it couldn't actually do anything if it were accidentally submitted to the network. @@ -205,7 +205,7 @@ function validateChallengeTransaction({ } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep10.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep10.js ## Sign and submit the challenge transaction @@ -250,7 +250,7 @@ In response, the user signs the transaction. You may have noticed we present thi ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte The `submitChallengeTransaction` function is quite simple. We take the transaction (in XDR format) and the domain name, and submit it to the relevant `WEB_AUTH_ENDPOINT` provided by the home domain's `stellar.toml` file. @@ -281,11 +281,11 @@ export async function submitChallengeTransaction({ } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep10.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep10.js ## About the `webAuthStore` store -Like so much of our BasicPay application, the various authentication tokens the user may have accumulated over time are stored in the browser's `localStorage`. There's not much special about this particular store, but here's how we put it together. +Like so much of our BasicPay application, the various authentication tokens the user may have accumulated over time are stored in the browser's `localStorage`. There's not much special about this particular store, but here's how we put it together: ```js title=/src/lib/stores/webAuthStore.js import { get } from "svelte/store"; @@ -326,6 +326,6 @@ function createWebAuthStore() { export const webAuthStore = createWebAuthStore(); ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stores/webAuthStore.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stores/webAuthStore.js Now that we have successfully authenticated our user with an asset anchor, we can display and process the various transfer capabilities of the anchor in question. We'll begin with SEP-24, since there are fewer implemention steps. diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/index.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/setup.mdx similarity index 88% rename from docs/building-apps/example-application-tutorial/anchor-integration/index.mdx rename to docs/building-apps/example-application-tutorial/anchor-integration/setup.mdx index 842f9a70b..7d3dce3d3 100644 --- a/docs/building-apps/example-application-tutorial/anchor-integration/index.mdx +++ b/docs/building-apps/example-application-tutorial/anchor-integration/setup.mdx @@ -1,6 +1,6 @@ --- -title: Anchor Integration -sidebar_position: 60 +title: "Setup for Anchored Assets" +sidebar_position: 10 --- An anchor is a Stellar-specific term for the on and off-ramps that connect the Stellar network to traditional financial rails, such as financial institutions or fintech companies. When a user deposits with an anchor, that anchor will credit their Stellar account with the equivalent amount of digital tokens. The user can then hold, transfer, or trade those tokens just like any other Stellar asset. When a user withdraws those tokens, the anchor redeems them for cash in hand or money in the bank. Read more about anchors in our [Anchor Documentation](https://developers.stellar.org/docs/anchoring-assets/overview). @@ -28,7 +28,7 @@ First, we need our application to know how it can communicate with anchors to ge BasicPay takes care of all the anchor transfer details on the `/dashboard/transfers` page. See it in action here: https://basicpay.pages.dev/dashboard/transfers -The first thing we'll do is determine whether the user holds trustlines to any assets the have a `home_domain` field set on the Stellar network. If so, we'll display some interactive elements to the user for that asset/domain. +The first thing we'll do is determine whether the user holds trustlines to any assets that have a `home_domain` field set on the Stellar network. If so, we'll display some interactive elements to the user for that asset/domain. ```js title=/src/routes/dashboard/transfers/+page.js import { fetchAssetsWithHomeDomains } from "$lib/stellar/horizonQueries"; @@ -43,6 +43,6 @@ export async function load({ parent }) { } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.js -Now we know if there are any assets the user holds that may have the necessary infrastructure for authenticated transfers. So, we can query the domain in question for any relevant details. +Now we know if there are any assets the user holds that may have the necessary infrastructure for authenticated transfers and we can query the domain in question for any relevant details. From 808295ddfb6e48c3eb6861f7f4a1a986de201570 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Tue, 15 Aug 2023 15:40:37 -0600 Subject: [PATCH 35/46] Create _category_.json --- .../anchor-integration/_category_.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 docs/building-apps/example-application-tutorial/anchor-integration/_category_.json diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/_category_.json b/docs/building-apps/example-application-tutorial/anchor-integration/_category_.json new file mode 100644 index 000000000..57bc1cfc0 --- /dev/null +++ b/docs/building-apps/example-application-tutorial/anchor-integration/_category_.json @@ -0,0 +1,7 @@ +{ + "position": 60, + "label": "Anchor Integration", + "link": { + "type": "generated-index" + } + } \ No newline at end of file From 2c13824d82e1a0b494085f2c55151655fe53b92b Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:01:47 -0600 Subject: [PATCH 36/46] update querying data --- docs/anchoring-assets/overview.mdx | 2 +- .../querying-data.mdx | 42 ++++++++++--------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/docs/anchoring-assets/overview.mdx b/docs/anchoring-assets/overview.mdx index 00442658d..181d25a2d 100644 --- a/docs/anchoring-assets/overview.mdx +++ b/docs/anchoring-assets/overview.mdx @@ -13,7 +13,7 @@ Stellar has anchor services operating worldwide. View the [Anchor Directory](htt Anchors can issue their own assets on the Stellar network, or they can honor assets that already exist. To learn about issuing assets, check out the [Issue Assets section](https://developers.stellar.org/docs/category/issue-assets). -This documentation will instruct you on how to become an anchor. To understand how to integrate anchor services into your blockchain-based application, check out the [Build Apps section](../building-apps/example-application-tutorial/anchor-integration) and [Connect to Anchors section][/docs/category]. If you’re looking specifically for MoneyGram Access, see the [Integrate with MoneyGram Access tutorial](https://developers.stellar.org/docs/tutorials/moneygram-access-integration-guide). +This documentation will instruct you on how to become an anchor. To understand how to integrate anchor services into your blockchain-based application, check out the [Build Apps section](/docs/building-apps/example-application-tutorial/anchor-integration/setup) and [Connect to Anchors section][/docs/category]. If you’re looking specifically for MoneyGram Access, see the [Integrate with MoneyGram Access tutorial](https://developers.stellar.org/docs/tutorials/moneygram-access-integration-guide). ## Stellar Ecosystem Proposals (SEPs) and interoperability diff --git a/docs/building-apps/example-application-tutorial/querying-data.mdx b/docs/building-apps/example-application-tutorial/querying-data.mdx index ae260bdce..1b0bdfe29 100644 --- a/docs/building-apps/example-application-tutorial/querying-data.mdx +++ b/docs/building-apps/example-application-tutorial/querying-data.mdx @@ -3,11 +3,13 @@ title: Querying Data sidebar_position: 70 --- -Throughout the application’s functionality, it will be querying data from Horizon, one of Stellar’s APIs. Information such as account balances, transaction history, sequence numbers for transactions, asset availability, and more are stored in Horizon’s database. +Your application will be querying data from Horizon (one of Stellar's APIs) throughout its functionality. Information such as account balances, transaction history, sequence numbers for transactions, asset availability, and more are stored in Horizon’s database. + +Here is a list of some common queries that you'll make. :::note -Other places in this tutorial, we have omitted the JSDoc descriptions and typing, for the sake of clean presentation. Here, we're including those to make these functions more copy/paste-able. +In other places in this tutorial, we have omitted the JSDoc descriptions and typing for the sake of clean presentation. Here, we're including those to make these functions more copy/paste-able. ::: @@ -45,11 +47,11 @@ const server = new Server(horizonUrl); /** @typedef {import('stellar-sdk').ServerApi.PaymentPathRecord} PaymentPathRecord */ ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js ## fetchAccount -gives the account sequence number, asset balances, trustlines +Gives an account's sequence number, asset balances, and trustlines. ```js title="/src/lib/stellar/horizonQueries.js" /** @@ -83,11 +85,11 @@ export async function fetchAccount(publicKey) { } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js ## fetchAccountBalances -gets existing balances for the `publicKey` +Gets existing balances for a given `publicKey`. ```js title="/src/lib/stellar/horizonQueries.js" /** @@ -103,11 +105,11 @@ export async function fetchAccountBalances(publicKey) { } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js ## fetchRecentPayments -finds any payments made to/from the `publicKey` (includes payments, path payments, account merges) +Finds any payments made to or from the given `publicKey` (includes: payments, path payments, and account merges). ```js title="/src/lib/stellar/horizonQueries.js" /** @@ -129,11 +131,11 @@ export async function fetchRecentPayments(publicKey, limit = 10) { } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js ## submit -submit a signed transaction to the stellar network +Submit a signed transaction to the Stellar network. ```js title="/src/lib/stellar/horizonQueries.js" /** @@ -155,11 +157,11 @@ export async function submit(transaction) { } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js ## fetchAssetsWithHomeDomains -we create our own new types. then, looks at all the issuer accounts, and returns only the ones with a `home_domain` set on the account. +We create our own new types. Then, looks at all the issuer accounts, and returns only the ones with a `home_domain` set on the account. ```js title="/src/lib/stellar/horizonQueries.js" /** @@ -199,11 +201,11 @@ export async function fetchAssetsWithHomeDomains(balances) { } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js ## findStrictSendPaths -find the available strict send paths between a source asset/amount and receiving account +Find the available strict send paths between a source asset/amount and receiving account. ```js title="/src/lib/stellar/horizonQueries.js" /** @@ -237,11 +239,11 @@ export async function findStrictSendPaths({ } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js ## findStrictReceivePaths -find the available strict receive paths between a source account and receiving asset/amount +Find the available strict receive paths between a source account and receiving asset/amount. ```js title="/src/lib/stellar/horizonQueries.js" /** @@ -278,11 +280,11 @@ export async function findStrictReceivePaths({ } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/horizonQueries.js -## that stellar.expert thing +## Query Stellar Expert -create our own type. retrieve the most highly-rated assets from the stellar.expert API +Create our own type that retrieves the most highly-rated assets from the stellar.expert API. ```js title="/src/lib/utils/stellarExpert.js" const network = "testnet"; @@ -330,4 +332,4 @@ export async function fetchAssets() { } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/utils/stellarExpert.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/utils/stellarExpert.js From 07946cd83f0e500e47a922b0ddc4da8356a92d47 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Tue, 15 Aug 2023 16:23:28 -0600 Subject: [PATCH 37/46] update SEP6 --- .../anchor-integration/sep6.mdx | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx index 56dfc942b..5640d6de5 100644 --- a/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx +++ b/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx @@ -17,7 +17,7 @@ export async function getTransferServerSep6(domain) { } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js ## Get `/info` @@ -41,13 +41,13 @@ export async function getSep6Info(domain) { } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep6.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep6.js ## Display interactive elements -Since many of the SEP-6 (and SEP-24, for that matter) endpoints require authentication, we wait until our user is authenticated with SEP-10 before we display what kinds of transfers are available. Now that they have a valid authentication token, we can display some buttons the user can use to begin a transfer. +Since many of the SEP-6 (and SEP-24) endpoints require authentication, we wait until our user is authenticated with SEP-10 before we display what kinds of transfers are available. When they have a valid authentication token, we can display some buttons the user can use to begin a transfer. -The user then can initiate one of the transfer methods (in BasicPay, only deposits and withdraws are supported) by clicking the “Deposit” or “Withdraw” button underneath a supported asset. +The user can then initiate one of the transfer methods (in BasicPay, only deposits and withdraws are supported) by clicking the “Deposit” or “Withdraw” button underneath a supported asset. ```svelte title=/src/routes/dashboard/transfers/+page.svelte ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte -Once launched, the `TransferModalSep6` will walk the user through a "wizard" to gather all the required information and utlimately create the transfer. +Once launched, the `TransferModalSep6` will walk the user through a "wizard" to gather all the required information and ultimately create the transfer. ### Modal step 1: Transfer details -BasicPay then prompts the user to input additional information such as transfer type, destination, and amount. Some of this is prepopulated based on which button the user clicked. However, the user can change any of the fields if they so choose. +BasicPay prompts the user to input additional information such as transfer type, destination, and amount. Some of this is prepopulated based on which button the user clicked. However, the user can change any of the fields if they so choose. We'll spare the code sample in this section, since it's mostly Svelte things going on. You can view the source here: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/TransferDetails.svelte @@ -195,7 +193,7 @@ export async function getKycServer(domain) { } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js Our SEP-6 modal then queries the anchor’s SEP-12 endpoint for the required KYC fields with a `GET` request, and we present these fields for the user to complete. @@ -219,7 +217,7 @@ export async function getSep12Fields({ authToken, homeDomain }) { } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js Again, the presentation of the fields the user must complete is more on the Svelte side of things, so we won't share those details here. However, the source for this component is available here: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/KYCInformation.svelte @@ -247,13 +245,13 @@ export async function putSep12Fields({ authToken, fields, homeDomain }) { } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js BasicPay receives back from the anchor a status message for the user to see. Once the status message is `ACCEPTED`, we can finally submit the actual transfer request! ### Modal step 4: Submit transfer -What BasicPay actually does to make this request is it takes all the fields that have been collected during this process wraps them into a URL that contains query parameters: [example](https://testanchor.stellar.org/sep6/deposit?account=GAXQIC2BSZ5HZP3BD6RZQSD3LB66TB6A2TA5W3LZX2VDFMBAKHC4B62J&asset_code=SRT&type=bank_account&amount=11) +BasicPay makes this request by taking all the fields that have been collected during this process and wrapping them into a URL that contains query parameters: [example](https://testanchor.stellar.org/sep6/deposit?account=GAXQIC2BSZ5HZP3BD6RZQSD3LB66TB6A2TA5W3LZX2VDFMBAKHC4B62J&asset_code=SRT&type=bank_account&amount=11) We submit a `GET` request to the URL with our authorization token in the headers, and the anchor takes it from there! @@ -288,7 +286,7 @@ export async function initiateTransfer6({ } ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js We then display the transfer server's response to the user, and wait for them to close the modal. @@ -338,4 +336,4 @@ In a withdrawal transaction, BasicPay will also present the user with a pre-buil ``` -Source: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte From 1692c15de3f6a6d1d60a0f782b4776f0b9ff0918 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Wed, 16 Aug 2023 12:15:17 -0600 Subject: [PATCH 38/46] add screenshots to sep6 and sep10 --- .../anchor-integration/sep10.mdx | 6 ++++++ .../anchor-integration/sep6.mdx | 14 +++++++++++++- static/assets/auth-valid.png | Bin 0 -> 12066 bytes static/assets/auth_valid.png | Bin 0 -> 28628 bytes static/assets/authenticate.png | Bin 0 -> 6391 bytes static/assets/kyc_accepted.png | Bin 0 -> 9109 bytes static/assets/sep6_deposit_withdraw.png | Bin 0 -> 20267 bytes static/assets/sep6_kyc.png | Bin 0 -> 34424 bytes static/assets/sep6_transfer_details.png | Bin 0 -> 32678 bytes 9 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 static/assets/auth-valid.png create mode 100644 static/assets/auth_valid.png create mode 100644 static/assets/authenticate.png create mode 100644 static/assets/kyc_accepted.png create mode 100644 static/assets/sep6_deposit_withdraw.png create mode 100644 static/assets/sep6_kyc.png create mode 100644 static/assets/sep6_transfer_details.png diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/sep10.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/sep10.mdx index a74acd82b..386cf0c54 100644 --- a/docs/building-apps/example-application-tutorial/anchor-integration/sep10.mdx +++ b/docs/building-apps/example-application-tutorial/anchor-integration/sep10.mdx @@ -3,6 +3,8 @@ title: "SEP-10: Stellar Web Authentication" sidebar_position: 20 --- +import auth_valid from "../../../../static/assets/auth_valid.png"; + Similar to the SEP-1 information, both SEP-6 and SEP-24 protocols make use of SEP-10 for authentication with the user. The user must prove they own the account before they can withdraw or deposit any assets as part of SEP-10: Stellar Web Authentication. Since we have the `stellar.toml` file information already, we can use that to display some interactive elements to the user. @@ -77,6 +79,8 @@ The `/src/routes/dashboard/transfers/+page.svelte` is doing **a lot** of work th Now, when the user clicks the "authenticate" button, it triggers the `auth` function. +![authenticate](/assets/authenticate.png) + ```svelte title=/src/routes/dashboard/transfers/+page.svelte - - -{#each data.homeDomainBalances as asset} - {#await fetchStellarToml(asset.home_domain) then stellarToml} - {#if 'WEB_AUTH_ENDPOINT' in stellarToml || 'TRANSFER_SERVER' in stellarToml} - {@const authStatus = getAuthStatus(asset.home_domain)} -

- {asset.asset_code} ({asset.home_domain}) -
{authStatus}
-

- {#if authStatus !== 'auth_valid'} - - - {:else} - - {/if} - {/if} - {/await} -{/each} + ``` **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte @@ -81,51 +60,53 @@ Now, when the user clicks the "authenticate" button, it triggers the `auth` func ![authenticate](/assets/authenticate.png) -```svelte title=/src/routes/dashboard/transfers/+page.svelte +```html title=/src/routes/dashboard/transfers/+page.svelte + + ``` **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte @@ -225,11 +206,12 @@ In response, the user signs the transaction. You may have noticed we present thi import { webAuthStore } from "$lib/stores/webAuthStore"; // We import some of our `$lib` functions - // highlight-next-line + // highlight-start import { getChallengeTransaction, submitChallengeTransaction, } from "$lib/stellar/sep10"; + // highlight-end // Takes an action after the pincode has been confirmed by the user on a SEP-10 challenge transaction. const onAuthConfirm = async (pincode) => { @@ -252,6 +234,8 @@ In response, the user signs the transaction. You may have noticed we present thi /* ... */ + + ``` **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/sep24.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/sep24.mdx index ce1d1eb91..9ea7143a7 100644 --- a/docs/building-apps/example-application-tutorial/anchor-integration/sep24.mdx +++ b/docs/building-apps/example-application-tutorial/anchor-integration/sep24.mdx @@ -3,7 +3,7 @@ title: "SEP-24: Hosted Deposit and Withdrawal" sidebar_position: 40 --- -SEP-24 provides a standard way for wallets and anchors to interact by having the user open a webview hosted by an anchor to collect and handle KYC information. +SEP-24 provides a standard way for wallets and anchors to interact by having the user open a webview hosted by an anchor to collect and handle KYC information. In this integration, a user's KYC information is entirely gathered and handled by the anchor. For the most part, after the anchor's webview has opened, BasicPay will have little knowledge about what's going on. ## Get `/info` diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx index 480cc55a3..041437af4 100644 --- a/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx +++ b/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx @@ -3,11 +3,9 @@ title: "SEP-6: Deposit and Withdrawal API" sidebar_position: 30 --- -import sep6_transfer_details from "../../../../static/assets/sep6_transfer_details.png"; -import sep6_kyc from "../../../../static/assets/sep6_kyc.png"; -import kyc_accepted from "../../../../static/assets/kyc_accepted.png"; +import useBaseUrl from "@docusaurus/useBaseUrl"; -SEP-6 allows wallets and other clients to interact with anchors directly without the user needing to leave the wallet to go to the anchor’s site. In this integration, a user’s KYC information is gathered and handled by the wallet. +SEP-6 allows wallets and other clients to interact with anchors directly without the user needing to leave the wallet to go to the anchor’s site. In this integration, a user’s KYC information is gathered and handled by the wallet and submitted to the anchor _on behalf of_ the user. ## Find the anchor's `TRANSFER_SERVER` @@ -55,77 +53,31 @@ The user can then initiate one of the transfer methods (in BasicPay, only deposi ![sep6](/assets/sep6_deposit_withdraw.png) -```svelte title=/src/routes/dashboard/transfers/+page.svelte +```html title=/src/routes/dashboard/transfers/+page.svelte - - -{#each data.homeDomainBalances as asset} - {#await fetchStellarToml(asset.home_domain) then stellarToml} - {#if 'WEB_AUTH_ENDPOINT' in stellarToml || 'TRANSFER_SERVER' in stellarToml} - {@const authStatus = getAuthStatus(asset.home_domain)} -

- {asset.asset_code} ({asset.home_domain}) -
{authStatus}
-

- {#if authStatus !== 'auth_valid'} - - {:else} - - {#if 'TRANSFER_SERVER' in stellarToml} - {#await getSep6Info(asset.home_domain) then sep6Info} -

SEP-6 Transfers

- {#each Object.entries(sep6Info) as [endpoint, details]} - {#if (endpoint === 'deposit' || endpoint === 'withdraw') && asset.asset_code in details} - - {/if} - {/each} - {/await} - {/if} - {/if} - {/if} - {/await} -{/each} + ``` **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte @@ -173,6 +125,8 @@ The above buttons will use the `launchTransferModalSep6` function to display the }); }; + + ``` **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte @@ -185,7 +139,7 @@ BasicPay prompts the user to input additional information such as transfer type, We'll spare the code sample in this section, since it's mostly Svelte things going on. You can view the source here: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/TransferDetails.svelte - + ### Modal step 2: Gather KYC information @@ -205,7 +159,7 @@ export async function getKycServer(domain) { Our SEP-6 modal then queries the anchor’s SEP-12 endpoint for the required KYC fields with a `GET` request, and we present these fields for the user to complete. - + ```js title=/src/lib/stellar/sep12.js import { getKycServer } from "$lib/stellar/sep1"; @@ -259,7 +213,9 @@ export async function putSep12Fields({ authToken, fields, homeDomain }) { BasicPay receives back from the anchor a status message for the user to see. Once the status message is `ACCEPTED`, we can finally submit the actual transfer request! - + + +This component of the SEP-6 modal, like most of them, is almost entirely Svelte-related. So as to keep this tutorial (somewhat) uncluttered, we'll refer you to the source for the component, which you can find here: https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/components/KYCStatus.svelte ### Modal step 4: Submit transfer @@ -346,6 +302,8 @@ In a withdrawal transaction, BasicPay will also present the user with a pre-buil /* ... */ + + ``` **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/setup.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/setup.mdx index 7d3dce3d3..12bcb2eae 100644 --- a/docs/building-apps/example-application-tutorial/anchor-integration/setup.mdx +++ b/docs/building-apps/example-application-tutorial/anchor-integration/setup.mdx @@ -24,11 +24,11 @@ Our integrations will also use the following SEPs: ## Setup for anchored assets -First, we need our application to know how it can communicate with anchors to get asset and infrastructure information. Do this by first querying an anchor’s stellar.toml file. - BasicPay takes care of all the anchor transfer details on the `/dashboard/transfers` page. See it in action here: https://basicpay.pages.dev/dashboard/transfers -The first thing we'll do is determine whether the user holds trustlines to any assets that have a `home_domain` field set on the Stellar network. If so, we'll display some interactive elements to the user for that asset/domain. +We need our application to know how it can communicate with anchors to get asset and infrastructure information. Ultimately, this is done by querying an anchor’s stellar.toml file. Before we can do that, though, we need to figure out where to find that file. + +The first thing we'll do is determine whether the user holds trustlines to any assets that have a `home_domain` field set on the Stellar network. The presence of that field on an issuer's account tells us the asset _may_ be plugged into the existing Stellar rails allowing for transfers of the asset. If it's present, we'll display some interactive elements to the user for that asset/domain. ```js title=/src/routes/dashboard/transfers/+page.js import { fetchAssetsWithHomeDomains } from "$lib/stellar/horizonQueries"; @@ -45,4 +45,4 @@ export async function load({ parent }) { **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.js -Now we know if there are any assets the user holds that may have the necessary infrastructure for authenticated transfers and we can query the domain in question for any relevant details. +Now we know if there are any assets the user holds that may have the necessary infrastructure for authenticated transfers and we can query the domain in question for the relevant details. diff --git a/docs/building-apps/example-application-tutorial/confirmation-modal.mdx b/docs/building-apps/example-application-tutorial/confirmation-modal.mdx index 916393b50..84c269eee 100644 --- a/docs/building-apps/example-application-tutorial/confirmation-modal.mdx +++ b/docs/building-apps/example-application-tutorial/confirmation-modal.mdx @@ -25,26 +25,30 @@ npm install --save-dev svelte-simple-modal On the Svelte side, this modal component will be a "wrapper" around the rest of our application, which allows us to trigger the modal from anywhere we need, and it should behave similarly no matter what. -```svelte title="/src/routes/+layout.svelte" +```html title="/src/routes/+layout.svelte" // highlight-next-line - - -// highlight-next-line + + + // highlight-next-line ``` @@ -54,130 +58,48 @@ On the Svelte side, this modal component will be a "wrapper" around the rest of To avoid reinventing the wheel every time we need a modal, we will create a reusable component that can accomodate most of our needs. Then, when we need the confirmation modal, we can pass an object of props to customize the modal's behavior. +:::note + +In our `*.svelte` component files, we will **not** dive into the HTML markup outside of the ` -
+ ``` **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/components/ConfirmationModal.svelte @@ -186,125 +108,44 @@ The basic parts of this component look like this: We can now use this modal component whenever we need to confirm something from the user. For example, here is how the modal is triggered when someone signs up. -```svelte title="/src/routes/signup/+page.svelte" +```html title="/src/routes/signup/+page.svelte" -
-
-
-

Signup now!

-

- Please provide a 6-digit pincode to sign up. This pincode will be used to encrypt - the secret key for your Stellar address, before it is stored in your browser's local - storage. Your secret key to this address will be stored on your device. You will be - the only one to ever have custody over this key. -

-
-
-
-
-
-
- -
- -
- -
-
- -
- {#if showSecret} -
- -
- -
-
- {/if} -
- - -
-
- -
- -
-
-
-
-
-
+ ``` +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/signup/+page.svelte + ### Customizing confirmation and rejection behavior Now, as these components have been written so far, they don't actually _do_ anything when the user inputs their pincode or clicks on a button. Let's change that! @@ -313,97 +154,97 @@ Since the confirmation behavior must vary depending on the circumstances (for ex First, in our modal component, we declare a dummy function to act as a prop, as well as an "internal" function that will call the prop function during the course of execution. -```svelte title="/src/lib/components/ConfirmationModal.svelte" +```html title="/src/lib/components/ConfirmationModal.svelte" -
- -
+ ``` +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/components/ConfirmationModal.svelte + Now that our modal component is setup to make use of a prop function for confirmation and rejection, we can declare what those functions should do inside the page that spawns the modal. -```svelte title="/src/routes/signup/+page.svelte" +```html title="/src/routes/signup/+page.svelte" -
- -
+ ``` +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/signup/+page.svelte + As you can see, we didn't actually need a customized `onReject` function, so we didn't pass one. No harm, no foul! diff --git a/docs/building-apps/example-application-tutorial/contacts-list.mdx b/docs/building-apps/example-application-tutorial/contacts-list.mdx index 5ab606584..3916150d6 100644 --- a/docs/building-apps/example-application-tutorial/contacts-list.mdx +++ b/docs/building-apps/example-application-tutorial/contacts-list.mdx @@ -96,44 +96,29 @@ export const contacts = createContactsStore(); We also have a page dedicated to managing contacts. The `/dashboard/contacts` page will allow the user to collect and manage a list of contact entries that stores the contact's name and Stellar address. The contact can also be flagged or unflagged as a "favorite" contact to be displayed on the main `/dashboard` page. -```svelte title="/src/routes/dashboard/contacts/+page.svelte" +```html title="/src/routes/dashboard/contacts/+page.svelte" - -

All contacts

- - - - - - - // highlight-next-line - {#each $contacts as contact (contact.id)} - - - - {/each} - -
+ ``` **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/contacts/+page.svelte @@ -142,40 +127,21 @@ We also have a page dedicated to managing contacts. The `/dashboard/contacts` pa The `contacts` store is now exported from this file and can be accessed and used inside a Svelte page or component. Here is how we've implemented a "favorite contacts" component for display on the main BasicPay dashboard. -:::note - -In our `*.svelte` component files, we will not dive too deeply into the HTML markup outside of the ` - -

Favorite Contacts

- - {#if favoriteContacts} - - // highlight-next-line - {#each favoriteContacts as contact (contact.id)} - - - - {/each} - - {/if} -
+ ``` **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/components/FavoriteContacts.svelte diff --git a/docs/building-apps/example-application-tutorial/manage-trust.mdx b/docs/building-apps/example-application-tutorial/manage-trust.mdx index eefddb2cb..d2f957652 100644 --- a/docs/building-apps/example-application-tutorial/manage-trust.mdx +++ b/docs/building-apps/example-application-tutorial/manage-trust.mdx @@ -41,46 +41,49 @@ The trustlines an account holds will be necessary to view in several parts of th The `/dashboard/assets` page allows the user to manage the Stellar assets their account carries trustlines to. On this page, they can select from several pre-suggested or highly ranked assets, or they could specify their own asset to trust using an asset code and issuer public key. They can also remove trustlines that already exist on their account. -The layout of the page is quite similar to our contacts page. It has a table displaying the existing trustlines and a section where you can add new ones. The key difference is that the `contacts` store is held in the browser's `localStorage`, whereas an account's balances are held on the blockchain. So, we will be querying the network to get that information. For more information about how we query this information from the Stellar network, check out the [`fetchAccountBalances()`] function in the querying data section. +The layout of the page is quite similar to our contacts page. It has a table displaying the existing trustlines and a section where you can add new ones. The key difference is that the `contacts` store is held in the browser's `localStorage`, whereas an account's balances are held on the blockchain. So, we will be querying the network to get that information. For more information about how we query this information from the Stellar network, check out the `fetchAccountBalances()` function in [this querying data section]. -```svelte title="/src/routes/dashboard/assets/+page.svelte" +```html title="/src/routes/dashboard/assets/+page.svelte" - -

Add Trusted Assets

- - -{#if addAsset === 'custom'} -
- - -
-{/if} - - - -

Existing Balances

- - - - {#each balances as balance} - - - - - - - {/each} - -
{balance.asset_code}{balance.balance} - -
+ ``` +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/assets/+page.svelte + ### The `createChangeTrustTransaction` function In the above page, we've made use of the `createChangeTrustTransaction` function. This function can be used to add, delete, or modify trustlines on a Stellar account. @@ -243,4 +198,4 @@ export async function createChangeTrustTransaction({ source, asset, limit }) { } ``` -[`fetchaccountbalances()`]: ./querying-data.mdx +[this querying data section]: ./querying-data.mdx#fetchaccountbalances diff --git a/docs/building-apps/example-application-tutorial/overview.mdx b/docs/building-apps/example-application-tutorial/overview.mdx index 52e519cb0..431da0173 100644 --- a/docs/building-apps/example-application-tutorial/overview.mdx +++ b/docs/building-apps/example-application-tutorial/overview.mdx @@ -165,9 +165,9 @@ Add your tailwind directives to your app's main CSS file. Then import the CSS file into your base SvelteKit layout (you may need to create this file). -```svelte title="/src/routes/+layout.svelte" +```html title="/src/routes/+layout.svelte" diff --git a/docs/building-apps/example-application-tutorial/path-payment.mdx b/docs/building-apps/example-application-tutorial/path-payment.mdx index 34d86a821..04dd79cff 100644 --- a/docs/building-apps/example-application-tutorial/path-payment.mdx +++ b/docs/building-apps/example-application-tutorial/path-payment.mdx @@ -19,7 +19,7 @@ The user will then preview the transaction, input their pincode, and select the Most of this page has been discussed in the [Payment section](./payment#the-dashboardsend-page). Below, we're highlighting the unique pieces that are added to BasicPay to allow for the path payment feature. -```svelte title="/src/routes/dashboard/send/+page.svelte" +```html title="/src/routes/dashboard/send/+page.svelte" - - - - - - - - -{#if createAccount !== null && !createAccount} - -{/if} - - -{#if pathPayment} -
-
-

Sending

-
-
-
- -
-
- -
-
-
-
- Strict {strictReceive ? 'Receive' : 'Send'} - -
-
-

Receiving

-
-
-
-
- -
-
- -
-
-
-{:else} - -{/if} - - - - + ``` +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/send/+page.svelte + ### The transaction functions In the above section, we used the `createPathPaymentStrictReceiveTransaction` and `createPathPaymentStrictSendTransaction` functions. These are used to create transactions that contain the actual path payment operation. @@ -400,3 +283,5 @@ export async function createPathPaymentStrictReceiveTransaction({ }; } ``` + +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/transactions.js diff --git a/docs/building-apps/example-application-tutorial/payment.mdx b/docs/building-apps/example-application-tutorial/payment.mdx index e82e32595..413d1ee9b 100644 --- a/docs/building-apps/example-application-tutorial/payment.mdx +++ b/docs/building-apps/example-application-tutorial/payment.mdx @@ -25,8 +25,6 @@ The user then inputs their pincode and clicks the "Confirm" button, which signs ### The `/dashboard/send` page -{/* TODO: Bri, is this too much from this code sample? Should we just cut ALL of the HTML out? */} - The `/dashboard/send` page allows the user to send payments to other Stellar addresses. They can select from a dropdown containing their contact list names, or they can enter their own "Other..." public key. The following additional features have been implemented: @@ -41,7 +39,7 @@ The following additional features have been implemented: For now, we'll focus on regular payments, and we'll dig into the path payments in a [later section](./path-payment). -```svelte title="/src/routes/dashboard/send/+page.svelte" +```html title="/src/routes/dashboard/send/+page.svelte" - - - - - - - - -{#if otherDestination} - checkDestination(otherPublicKey)} - type="text" - placeholder="G..." - class="input-bordered input" - /> -{/if} - - -{#if createAccount} - -{/if} - - -
-
-
- -
-
- -
- - - - - - + ``` +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/send/+page.svelte + ### The transaction functions In the above section, we used the `createPaymentTransaction` function. This function can be used to send a payment of any asset from one Stellar address to another. From 99b1960851ac023cd90cbd3e76134cbd088a9e63 Mon Sep 17 00:00:00 2001 From: Bri Wylde <92327786+briwylde08@users.noreply.github.com> Date: Fri, 18 Aug 2023 10:55:56 -0600 Subject: [PATCH 42/46] editorial --- .../example-application-tutorial/querying-data.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/building-apps/example-application-tutorial/querying-data.mdx b/docs/building-apps/example-application-tutorial/querying-data.mdx index 582a1a241..69c939239 100644 --- a/docs/building-apps/example-application-tutorial/querying-data.mdx +++ b/docs/building-apps/example-application-tutorial/querying-data.mdx @@ -163,7 +163,7 @@ export async function submit(transaction) { We create a brand new `HomeDomainBalanceLine` type that includes the balance information of a user's trustline, and also adds the `home_domain` of the asset issuer. If you're using something else for type safety (or nothing at all), feel free to adapt or ignore the `@typedef`s we've included here. -Then, looks at all the issuer accounts, and returns only the ones with a `home_domain` set on the account. +Then, it looks at all the issuer accounts and returns only the ones with a `home_domain` set on the account. ```js title="/src/lib/stellar/horizonQueries.js" /** @@ -290,11 +290,11 @@ Stellar Expert is a third-party block explorer that is indispensable as a tool f :::note -Stellar Expert employs their own algorithm to determine the quality of an asset. This algorithm considers things like the number of payments made using an asset, the number of accounts holding that asset, how much of the asset is available on the DEX or in liquidity pools, and so on. These rankings aren't a "final determination" of an asset's quality, by any means. They are more like an observation of which Stellar assets see the most use and activity on the network. +Stellar Expert employs their own algorithm to determine the quality of an asset. This algorithm considers things like the number of payments made using an asset, the number of accounts holding that asset, how much of the asset is available on the DEX or in liquidity pools, and so on. These rankings aren't a "final determination" of an asset's quality by any means, and are more like an observation of which Stellar assets see the most use and activity on the network. ::: -We've created our own `RankedAsset` type so BasicPay knows how to interact with these objects. And we are then retrieve the 10 most highly-rated assets from the Stellar Expert API. +We've created our own `RankedAsset` type so BasicPay knows how to interact with these objects. And we are then retrieving the ten most highly-rated assets from the Stellar Expert API. ```js title="/src/lib/utils/stellarExpert.js" const network = "testnet"; From 52fafe3a7f2ed257b151a311c92b79adbf8096b4 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Fri, 18 Aug 2023 12:21:36 -0500 Subject: [PATCH 43/46] SEP-24 instructions and technical walkthrough --- .../anchor-integration/sep24.mdx | 267 +++++++++++++++++- .../anchor-integration/sep6.mdx | 15 +- 2 files changed, 269 insertions(+), 13 deletions(-) diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/sep24.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/sep24.mdx index 9ea7143a7..08decb0c9 100644 --- a/docs/building-apps/example-application-tutorial/anchor-integration/sep24.mdx +++ b/docs/building-apps/example-application-tutorial/anchor-integration/sep24.mdx @@ -5,14 +5,271 @@ sidebar_position: 40 SEP-24 provides a standard way for wallets and anchors to interact by having the user open a webview hosted by an anchor to collect and handle KYC information. In this integration, a user's KYC information is entirely gathered and handled by the anchor. For the most part, after the anchor's webview has opened, BasicPay will have little knowledge about what's going on. +:::info + +Remember, SEP-24 depends on [SEP-10 authentication]. Everything below assumes the user has successfully authenticated with the anchor server, and BasicPay has access to an unexpired authentication token to send with its requests. + +::: + +## Find the anchor's `TRANSFER_SERVER_SEP0024` + +Before we can ask anything about _how_ to make a SEP-24 transfer, we have to figure out _where_ to discover that information. Fortunately, the SEP-1 protocol describes standardized fields to find out what we need. + +```js title=/src/lib/stellar/sep1.js +// Fetches and returns the endpoint used for SEP-24 transfer interactions. +export async function getTransferServerSep24(domain) { + let { TRANSFER_SERVER_SEP0024 } = await fetchStellarToml(domain); + return TRANSFER_SERVER_SEP0024; +} +``` + +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep1.js + ## Get `/info` -Our application will request the `/info` endpoint from the anchor's transfer server to understand the supported transfer methods (deposit, withdraw, deposit-exchange, and withdraw-exchange) and available endpoints, as well as additional features that may be available during transfers. +Our application will request the `/info` endpoint from the anchor's transfer server to understand the supported transfer methods (deposit, withdraw) and available endpoints, as well as additional features that may be available during transfers. + +```js title=/src/lib/stellar/sep24.js +// Fetches and returns basic information about what the SEP-24 transfer server supports. +export async function getSep24Info(domain) { + let transferServerSep24 = await getTransferServerSep24(domain); + + let res = await fetch(`${transferServerSep24}/info`); + let json = await res.json(); + + if (!res.ok) { + throw error(res.status, { + message: json.error, + }); + } else { + return json; + } +} +``` + +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep24.js + +## The user clicks "deposit" or "withdraw" + +Now that we have all the SEP-24 information the anchor has made available to us, it's up to the user to actually begin the initiation process. In BasicPay, they do that by simply clicking a button that will then trigger the `launchTransferWindowSep24` function. + +:::note + +This file was pretty heavily covered in the [SEP-6 section]. We'll be presenting here the additions we make to this file, though we won't repeat things we've already covered. Remember to check the source files for the full picture. + +::: + +```html title=/src/routes/dashboard/transfers/+page.svelte + + + +``` + +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte + +## Retrieve the interactive URL + +BasicPay then initiates a transfer method by sending a `POST` request to either the “SEP-24 Deposit” or “SEP-24 Withdraw” endpoint. The anchor then sends an interactive URL that BasicPay will open as a popup for the user to complete and confirm the transfer. + +```js title=/src/lib/stellar/sep24.js +// Initiates a transfer using the SEP-24 protocol. +export async function initiateTransfer24({ + authToken, + endpoint, + homeDomain, + urlFields = {}, +}) { + let transferServerSep24 = await getTransferServerSep24(homeDomain); + + let res = await fetch( + `${transferServerSep24}/transactions/${endpoint}/interactive`, + { + method: "POST", + mode: "cors", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${authToken}`, + }, + body: JSON.stringify(urlFields), + }, + ); + let json = await res.json(); + + if (!res.ok) { + throw error(res.status, { + message: json.error, + }); + } else { + return json; + } +} +``` + +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep24.js + +## Launch the popup window and listen for a callback + +BasicPay doesn't really need (or want) to know everything that's happening between the user and the anchor during a SEP-24 transfer. However, we _do_ want to know when the interaction is over, since we may need to take some action at that point. So, we add a callback to the interactive URL and open the popup window. + +:::caution + +Since BasicPay is an entirely client-side application, we can't provide a callback as a URL. So, we are using a `postMessage` callback. For more information on the details of these callback options, check out [this section of the SEP-24 specification]. + +::: + +```html title=/src/routes/dashboard/transfers/+page.svelte + + + +``` + +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte + +## Complete transfer + +Once the user is finished with the interactive window from the anchor, they'll be brought back to BasicPay. We store the details of the transfer in the `transfersStore` store (Remember, this is just so we can track which anchors to query for transfers later on.) + +```html title=/src/routes/dashboard/transfers/+page.svelte + + + +``` + +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte + +## (Sometimes) Send a Stellar payment + +In a withdrawal transaction, BasicPay will also build and present to the user a Stellar transaction for them to sign with their pincode. + +```html title=/src/routes/dashboard/transfers/+page.svelte + -The user then initiates a transfer method (in BasicPay, only deposits and withdraws are supported) by POSTing a request to either the “SEP-24 Deposit” or “SEP-24 Withdraw” endpoint. The anchor then sends an interactive URL that BasicPay opens for the user to complete and confirm the transaction. + +``` -Once the user clicks “Submit”, they’ll be brought back to the application. +**Source:** https://github.com/stellar/basic-payment-app/blob/main/src/routes/dashboard/transfers/+page.svelte -In a withdrawal transaction, BasicPay will also present the user with a pre-built transaction for them to sign with their pincode. `callback` should be in the form of a `postMessage`. Our application listens for that `postMessage` during the withdrawal and opens up the transaction dialog when the interactive flow is completed. +[sep-10 authentication]: ./sep10.mdx +[sep-6 section]: ./sep6.mdx +[this section of the sep-24 specification]: https://www.stellar.org/protocol/sep-24#adding-parameters-to-the-url diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx index 041437af4..d1d724ae6 100644 --- a/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx +++ b/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx @@ -67,13 +67,6 @@ The user can then initiate one of the transfer methods (in BasicPay, only deposi import { getContext } from "svelte"; const { open } = getContext("simple-modal"); - // An object to easily and consistently class buttons based on the type of - // transfer that will take place. - const transferButtonClasses = { - deposit: "btn lg:w-1/2 join-item btn-accent", - withdraw: "btn lg:w-1/2 join-item btn-secondary", - }; - /* ... */ @@ -256,7 +249,13 @@ export async function initiateTransfer6({ **Source:** https://github.com/stellar/basic-payment-app/blob/main/src/lib/stellar/sep12.js -We then display the transfer server's response to the user, and wait for them to close the modal. +We then store the details of the transfer in the `transfersStore` store and display the transfer server's response to the user. We then wait for them to close the modal. + +:::note + +The only reason we're storing anything about the transfer in BasicPay is to help us keep track of which anchors the user has initiated transfers with. Otherwise, we wouldn't be able query for a transfer history (like on the `/dashboard` page). + +::: ### (Sometimes) Modal step 5: Send a Stellar payment From ea945c6f601f8980109a52172c0c81f0093753b8 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Fri, 18 Aug 2023 12:23:57 -0500 Subject: [PATCH 44/46] Adding some more detail to SEP-6 page --- .../anchor-integration/sep6.mdx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx b/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx index d1d724ae6..2f430e714 100644 --- a/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx +++ b/docs/building-apps/example-application-tutorial/anchor-integration/sep6.mdx @@ -259,7 +259,7 @@ The only reason we're storing anything about the transfer in BasicPay is to help ### (Sometimes) Modal step 5: Send a Stellar payment -In a withdrawal transaction, BasicPay will also present the user with a pre-built transaction for them to sign with their pincode. Here we will finally get to move back to our "regular" modal that _is_ so good at so many things! +In a withdrawal transaction, BasicPay will also build and present to the user a Stellar transaction for them to sign with their pincode. Here we will finally get to move back to our "regular" modal that _is_ so good at so many things! ```html title=/src/routes/dashboard/transfers/+page.svelte