Skip to main content

Application Design Considerations

Custody models​

When building an application, one of the first things you have to decide is how your users’ secret keys will be secured and stored. Stellar applications give users access to their accounts that are stored on the ledger, and access to these accounts is controlled by the account’s secret key. That secret key proves that the user has custody or “owns” the account.

There are four custody options to consider:

  • Non-custodial service - the user of the application stores their own secret key
  • Custodial service - the service provider (application) stores the users’ secret keys
  • Mixture of both - with the use of multisig, this option is useful for maintaining non-custodial status while still allowing for account recovery
  • Third-party key management services - integrate a third-party custodial service into your application that can store your users’ secret keys

Non-custodial service​

In a non-custodial service, the user of the application stores the secret key for their account and permissions the application to send requests to delegate transaction signing. There are some potential usability issues as the user has to know how to securely store their own account credentials and safely navigate transaction signing on their end. If they lose their secret key, they will also lose access to their account.

Typically, non-custodial applications create or import a pre-existing Stellar account for each user.

Custodial service​

With a custodial service, the service provider (an application such as a centralized exchange) stores the users’ secret keys and delegates usage rights to the user.

Many custodial services choose to use a single pooled Stellar account (called shared, omnibus, or pooled accounts) to handle transactions on behalf of their users instead of creating a new Stellar account for each user. To distinguish between individual users in a pooled account, we encourage the implementation of muxed accounts.

Learn how to set up an application as a custodial service in this [tutorial].

A mixture of non-custodial and custodial​

Building an application with multi-signature capabilities allows you to have a non-custodial service with account recovery. If the user loses their secret key, they can still sign transactions with other authorized signatures, granted the signature threshold is high enough.

Third-party key management services​​

There are several apps and services that specialize in adding additional security layers to users' accounts. Check them out if you're interested in integrating a third-party key management service:

Application security​

Even though wallets can operate client-side, they deal with a user’s secret keys, which give direct access to their account, and to any value they hold. That’s why it’s essential to require all web traffic to flow over strong TLS methods. Even when developing locally, use a non-signed localhost certificate to develop secure habits from the very beginning. Stellar is a powerful money-moving software — don’t skimp on security.

For more information, check out our guide to securing web-based products.

Wallet services​

A wallet typically has these basic functions: key storage, account creation, transaction signing, and queries to the Stellar database. There are some services that take care of all of these functions for you, so you can build whatever you’d like around it. Check out some of these wallet services below.

Account creation strategies​

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. A Stellar account is created with a keypair (a public key and private key) and the minimum balance of XLM.

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 each of these strategies.

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.
  2. The wallet initiates the first deposit on behalf of the user without requiring the user to add the asset/create the trustline.
  3. The anchor provides deposit instructions to the customer.
  4. The user transfers money from a bank account to the anchor’s bank account.
  5. Once the anchor receives the transfer, the anchor creates and funds the Stellar account for the customer.
  6. The wallet detects that the account has been created and a trustline must be established.
  7. The wallet prompts the user to add the asset/create the trustline.
  8. Finally, the anchor sends the deposit funds to the user’s Stellar account.
info

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).

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, which enhance the flow by allowing users to start using the wallet without having to secure XLM. 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.
  2. The wallet initiates a deposit on behalf of a user.
  3. The anchor provides deposit instructions to the wallet.
  4. The user transfers money from a bank account to the anchor’s account.
  5. 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.
  6. The anchor creates a Claimable Balance.
  7. The wallet detects the Claimable Balance for the account, claims the funds, and posts it in the wallet.

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.

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.
  2. Then the wallet creates a trustline, and initiates the first deposit.
  3. Once the deposit request is sent to the anchor, the anchor provides instructions for the deposit.
  4. The customer transfer funds from a personal bank account to the anchor’s account.
  5. The anchor receives the funds, then sends them to the user’s Stellar account.
  6. The wallet detects that funds were sent and notifies the user.
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 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.