Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Advanced Configuration
description: Understand how to configuration the SDP for various scenarios. This includes multi-tenancy, testnet vs. mainnet, etc.
description: Understand how to configure the SDP for various scenarios. This includes multi-tenancy, testnet vs. mainnet, etc.
keywords: [SDP, configuration]
sidebar_position: 45
---
Expand Down Expand Up @@ -54,8 +54,8 @@ You **must** generate a new, secure keypair for your Mainnet Distribution Accoun
- **Generate Keys**: Create a new keypair and set `DISTRIBUTION_PUBLIC_KEY` and `DISTRIBUTION_SEED`.
- **Generate Encryption Passphrase**: You should generate new encryption passphrases for your tenant distribution accounts and channel accounts by setting `DISTRIBUTION_ACCOUNT_ENCRYPTION_PASSPHRASE` and `CHANNEL_ACCOUNTS_ENCRYPTION_PASSPHRASE`.
- **Fund the Account**: The Distribution Account requires an initial balance of XLM to function. It is responsible for:
1. **Creating Channel Accounts**: The system will automatically create `NUM_CHANNEL_ACCOUNTS` (default: 2).
2. **Bootstrapping Tenants**: When a new tenant is provisioned, the system transfers a bootstrap amount of XLM from the Distribution Account to the Tenant's Distribution Account. This is controlled by `TENANT_XLM_BOOTSTRAP_AMOUNT` (default: 5 XLM).
1. **Creating Channel Accounts**: The system will automatically create `NUM_CHANNEL_ACCOUNTS` (default: 2).
2. **Bootstrapping Tenants**: When a new tenant is provisioned, the system transfers a bootstrap amount of XLM from the Distribution Account to the Tenant's Distribution Account. This is controlled by `TENANT_XLM_BOOTSTRAP_AMOUNT` (default: 5 XLM).

### Configuration Methods

Expand Down Expand Up @@ -214,3 +214,66 @@ This is determined by the field `distribution_account_type` in the API call abov
Once a tenant is created, the `distribution_account_type` cannot be changed. If you wish to use a different distribution account type, you will need to create a new tenant.

:::

## Embedded Wallets Configuration

Embedded Wallets allow receivers to receive disbursements without downloading a separate wallet application. Instead, the SDP creates lightweight, passkey-secured smart contract wallets on the Stellar network. This feature requires configuration across the SDP backend, Transaction Submission Service (TSS), and frontend dashboard.

For a complete guide on using Embedded Wallets, see the [Embedded Wallets](./embedded-wallets) documentation.

### Overview

To enable Embedded Wallets, you need to:

1. Make sure the SEP-10 account exists on the Stellar network by funding it
2. Configure the backend with the RPC endpoint
3. Configure TSS with the same RPC endpoint
4. Enable RPC features in the frontend dashboard

:::caution HTTPS Requirement

**The frontend dashboard MUST be served over HTTPS for Embedded Wallets to work.** Passkeys use the WebAuthn standard, which requires a secure context.

:::

### Backend (SDP Core Service) Configuration

The following environment variables configure the SDP backend for Embedded Wallets:

| Variable | Description | Default | Required |
| :-- | :-- | :-- | :-- |
| `ENABLE_EMBEDDED_WALLETS` | Enable embedded wallet features. Set to `true` to activate. | `false` | Yes |
| `EMBEDDED_WALLETS_WASM_HASH` | The WASM hash of the deployed smart contract for embedded wallets. This is network-specific. | - | Yes (when enabled) |
| `RPC_URL` | The URL of the Stellar RPC server. Required for interacting with smart contracts. | - | Yes (when enabled) |
| `RPC_REQUEST_AUTH_HEADER_KEY` | The HTTP header name for authenticating requests to a protected RPC server (e.g., `X-API-Key`). Optional. | - | No |
| `RPC_REQUEST_AUTH_HEADER_VALUE` | The value of the authentication header for protected RPC servers. Optional. | - | No |
| `ENABLE_SEP45` | Enable SEP-45 web authentication for smart contracts. Recommended for Embedded Wallets. | `false` | No |
| `SEP45_CONTRACT_ID` | The contract ID for SEP-45 authentication. Required when SEP-45 is enabled. | - | When SEP45 enabled |

### Transaction Submission Service (TSS) Configuration

The TSS also requires RPC configuration to submit smart contract transactions:

| Variable | Description | Default | Required |
| :-- | :-- | :-- | :-- |
| `RPC_URL` | The URL of the Stellar RPC server. Must match the backend RPC_URL. | - | Yes (when embedded wallets enabled) |
| `RPC_REQUEST_AUTH_HEADER_KEY` | The HTTP header name for RPC authentication. Optional. | - | No |
| `RPC_REQUEST_AUTH_HEADER_VALUE` | The authentication header value. Optional. | - | No |

### Frontend (Dashboard) Configuration

The frontend dashboard requires a single environment variable to enable embedded wallet features:

| Variable | Description | Default | Required |
| :-- | :-- | :-- | :-- |
| `RPC_ENABLED` | Enable RPC-dependent features including Embedded Wallets. Set to `true`. | `false` | Yes |

### HTTPS Requirement for Passkeys

:::danger Critical: HTTPS Required

Embedded Wallets use passkeys (WebAuthn) for authentication. **Passkeys only work in secure contexts**.

If your frontend is not served over HTTPS, receivers will not be able to create passkeys or authenticate with their embedded wallets.

:::
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ Operational Configuration allows controlling metrics, logging, and other operati
- `CRASH_TRACKER_TYPE` - The crash tracker type to use. Options: "SENTRY", "DRY_RUN". Default: "DRY_RUN".
- `SENTRY_DSN` - 🔑 The DSN (client key) of the Sentry project. If not provided, Sentry will not be used.
- `ENVIRONMENT` - The environment where the application is running. Example: "development", "staging", "production". Default: "development".
- `BASE_URL` - The SDP backend server's base URL. Default: "http://localhost:8000". Tenant-specific URLs will be configured during the [tenant provisioning process](./advanced-configration#provisioning-tenants).
- `SDP_UI_BASE_URL` - The SDP UI/dashboard Base URL used to send the invitation link when a new user is created. Tenant-specific URLs will be configured during the [tenant provisioning process](./advanced-configration#provisioning-tenants).
- `BASE_URL` - The SDP backend server's base URL. Default: "http://localhost:8000". Tenant-specific URLs will be configured during the [tenant provisioning process](./advanced-configuration#provisioning-tenants).
- `SDP_UI_BASE_URL` - The SDP UI/dashboard Base URL used to send the invitation link when a new user is created. Tenant-specific URLs will be configured during the [tenant provisioning process](./advanced-configuration#provisioning-tenants).

### Database Configuration

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
---
title: Embedded Wallets
description: Learn how to use Embedded Wallets to enable receivers without existing Stellar wallets to receive disbursements using passkey authentication.
keywords: [embedded wallets, passkeys, WebAuthn, smart contracts, disbursements]
sidebar_position: 50
---

# Embedded Wallets

## Introduction

Embedded Wallets allow receivers to receive disbursements without needing to download or manage a separate wallet application. When you create a disbursement with Embedded Wallets as the target wallet provider, the SDP automatically creates a lightweight, passkey-secured smart contract wallet for each receiver.

### Why Use Embedded Wallets?

Embedded Wallets significantly reduce friction for receivers who don't have an existing Stellar wallet:

- **No App Download Required**: Receivers don't need to download a separate wallet application
- **Passwordless Authentication**: Uses passkeys (biometric or device-based authentication) instead of passwords
- **Phishing-Resistant**: Built on WebAuthn standards that prevent credential theft
- **Simple User Experience**: Receivers can claim their funds with just a few clicks

### Limitations

Before enabling Embedded Wallets, note the current limitations:

- **No exchange transfers**: Embedded wallets cannot send directly to exchanges.
- **No built-in offramp**: Offramping must be handled out-of-band (for example, a direct transfer to a user-provided address).
- **Single wallet per receiver**: Each receiver can create only one embedded wallet

### Key Concepts

**Smart Contract Wallets**: Embedded Wallets are Stellar smart contract accounts that are deployed on-chain when a receiver creates their passkey. These contracts are controlled by the receiver's passkey credential.

**Passkeys**: A modern authentication method that replaces passwords with cryptographic keys stored securely on the user's device, unlocked with biometrics (fingerprint, Face ID, etc.) or device PIN.

**SEP-45**: A Stellar web authentication protocol for contract accounts (`C...`) that lets wallets prove control of a smart contract wallet and obtain a JWT session token from a service. The SDP uses SEP-45 during SEP-24 flows to verify that receivers control their embedded wallets.

---

## What are Passkeys?

Passkeys are a replacement for passwords that provide stronger security and a better user experience. Instead of remembering and typing a password, users authenticate with biometrics (like fingerprint or facial recognition) or their device's PIN/pattern.

### How Passkeys Work

When a receiver creates an embedded wallet:

1. The browser or device generates a **cryptographic key pair** (public key and private key)
2. The **private key** is stored securely on the receiver's device and never leaves it
3. The **public key** is sent to the SDP and used to create the smart contract wallet
4. When signing in later, the receiver uses biometrics to unlock their private key

### Why Passkeys are More Secure

**Phishing-Resistant**: Unlike passwords, passkeys are cryptographically bound to your domain. Even if a receiver visits a fake website, their passkey won't work there.

**Automatically Unique**: Each passkey is unique per service. There's no risk of password reuse across sites.

**Breach-Resistant**: The SDP only stores public keys. Even if the database is compromised, attackers cannot use public keys to authenticate.

**No Weak Passwords**: Users can't create weak or easily-guessed credentials. All passkeys use strong cryptography.

:::info Learn More About Passkeys

For more details about passkey technology, visit [passkeys.dev](https://passkeys.dev/docs/intro/what-are-passkeys/) or read about the [WebAuthn specification](https://www.w3.org/TR/webauthn/).

:::

---

## How It Works

The Embedded Wallet flow includes the following steps:

1. **Disbursement Creation**: An administrator creates a disbursement and selects "Embedded Wallet" as the wallet provider
2. **Invitation Sent**: The SDP sends an invitation link to each receiver via SMS or email. The link is unique per receiver.
3. **Passkey Creation**: The receiver clicks the link and creates a passkey using their device's biometric authentication
4. **Wallet Deployment**: The SDP deploys a smart contract wallet on the Stellar network, controlled by the receiver's passkey
5. **Verification**: The receiver completes identity verification (e.g., entering an OTP or date of birth)
6. **Payment Transfer**: Once verified, the SDP automatically transfers the disbursement funds to the receiver's contract wallet

:::danger

Each link is unique per receiver. Treat it as sensitive: if a link is leaked and you have **no verification** enabled, an attacker could create the receiver’s wallet and claim the funds. Skipping verification should only be done in low-risk scenarios and with small disbursement amounts.

:::

### Behind the Scenes

When a receiver logs in with their passkey, several things happen:

- The frontend uses **WebAuthn** to authenticate the receiver with their biometric or device PIN
- The backend verifies the authentication using the stored public key
- A **wallet-auth JWT** is generated for SDP APIs (e.g., profile and RPC access)
- The SDP **sponsors transactions** on behalf of the receiver, covering all network fees
- Payments are made using **Stellar Asset Contract (SAC)** transfers to the smart contract address

---

## Prerequisites

Before using Embedded Wallets, ensure your SDP instance is properly configured:

1. **Backend Configuration**: Embedded Wallets require specific environment variables to be set. See the [Embedded Wallets Configuration](./advanced-configuration#embedded-wallets-configuration) section in the Advanced Configuration guide.

2. **Frontend HTTPS Requirement**: The frontend dashboard **must** be served over HTTPS for passkeys to work. WebAuthn requires a secure context and will not function over plain HTTP.

3. **Network Selection**: Deploy the SEP-45 contract and the embedded wallet Wasm.

For detailed configuration instructions, see the [Embedded Wallets Configuration](./advanced-configuration#embedded-wallets-configuration) section.

---

## Using Embedded Wallets

### Step 1: Create a Disbursement with Embedded Wallet

When creating a new disbursement, select **"Embedded Wallet"** as the wallet provider in the disbursement details form.

![Creating a disbursement with Embedded Wallet selected](/assets/SDP/SDP46.png)

**What to configure:**

- **Registration Contact Type**: Choose how receivers will be contacted (Email or SMS)
- **Wallet Provider**: Select "Embedded Wallet" from the dropdown
- **Asset**: Choose the asset to disburse (e.g., USDC, XLM)
- **Verification Type**: Select what information receivers must verify (e.g., PIN, date of birth)

:::note

There is also a "None" option, but using it is only recommended for low-risk scenarios due to security concerns (e.g. disbursing small amounts).

:::

Once you've uploaded your disbursement CSV file and submitted the disbursement, the SDP will begin sending invitations to all receivers in the list.

---

### Step 2: Receiver Creates Passkey

Receivers will receive an invitation message (via SMS or email) with a secure link to create their embedded wallet. The link format looks like this:

```j
https://your-tenant.sdp.stellar.org/wallet?asset=native&token=c09bd254-b77a-4685-bc18-377231484267&signature=26b48d7ce...
```

:::danger Reminder

Each link is unique per receiver. Treat it as sensitive: if a link is leaked and you have **no verification** enabled, an attacker could create the receiver’s wallet and claim the funds. Skipping verification should only be done in low-risk scenarios and with small disbursement amounts.

We also recommend enabling verification because it requires users to authenticate via SEP-45 before receiving funds. This confirms their passkey works correctly. This helps avoid cases where accounts are created and funds disbursed, but users are prevented from accessing the wallet due to passkey issues that would have been caught during verification.

:::

When the receiver clicks the link, they'll see a page inviting them to create their wallet account:

![Invitation to create an embedded wallet with passkey](/assets/SDP/SDP47.png)

**The passkey creation process:**

1. The receiver clicks **"Log in with passkey"**
2. Their browser or device prompts them to create a passkey (first-time users) or authenticate with an existing passkey (returning users)
3. For new users, they'll scan their fingerprint, face, or enter their device PIN
4. The browser generates a cryptographic key pair securely on the device

**What happens behind the scenes:**

- The frontend calls `POST /embedded-wallets/passkey/registration/start` with the invitation token
- The backend validates the token and initiates a WebAuthn registration ceremony
- After biometric authentication, the frontend calls `POST /embedded-wallets/passkey/registration/finish` with the credential
- The backend queues a smart contract wallet deployment transaction with the public key
- The Transaction Submission Service (TSS) deploys the contract to the Stellar network
- Once deployed, the receiver's wallet is ready to receive funds

:::tip Returning Users

If a receiver already has a passkey for a different disbursement, they can simply authenticate with their existing passkey instead of creating a new one. The same passkey can be used across multiple disbursements.

:::

---

### Step 3: Complete Verification

After creating their passkey, receivers are prompted to complete verification before they can receive funds:

![Verification prompt after wallet creation](/assets/SDP/SDP48.png)

The verification step ensures that the receiver is who they claim to be. Depending on how you configured the disbursement, receivers may need to:

- Enter an **OTP (One-Time Password)** sent to their email or phone
- Provide their **date of birth**
- Enter a **PIN** that was shared with them
- Provide **national ID** information

**What happens after verification:**

1. The receiver submits their verification information
2. The SDP validates the information against the receiver record
3. If verification succeeds, the receiver wallet status changes from `READY` to `REGISTERED`
4. The SDP automatically initiates the payment to the receiver's contract wallet address

:::info Verification Flow

The verification process uses the SDP's native SEP-24 implementation. The receiver authenticates with a SEP-24 JWT token that's generated during the passkey authentication flow.

For background on SEP-45 (contract-account web authentication), see [SEP-0045](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0045.md).

:::

---

### Step 4: Receiving Funds

Once verification is complete, the SDP automatically transfers the disbursement amount to the receiver's smart contract wallet address.

**Payment Process:**

1. The SDP queues a payment transaction to the receiver's contract address
2. The payment uses a **Stellar Asset Contract (SAC) transfer** to move funds from the distribution account to the contract wallet
3. The transaction is **fee-sponsored** by the distribution account, so the receiver pays nothing
4. Once confirmed on the network, the funds are available in the receiver's embedded wallet

**What receivers see:**

- The embedded wallet interface displays their asset balance
- They can view their wallet address (a Stellar C-address starting with "C")
- They can initiate transactions to send funds or withdraw to fiat

## External Resources

To learn more about the technologies behind Embedded Wallets, check out these resources:

### Passkeys & WebAuthn

- [passkeys.dev](https://passkeys.dev/) - Comprehensive guide to passkeys
- [WebAuthn Specification](https://www.w3.org/TR/webauthn/) - W3C standard for web authentication
- [FIDO Alliance](https://fidoalliance.org/) - The organization behind passkey standards

### Stellar Protocols

- [SEP-24: Hosted Deposit and Withdrawal](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0024.md) - Interactive deposit/withdrawal flow
- [SEP-45: Smart Contract Domain Verification](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0045.md) - Web authentication for smart contracts
- [Stellar Asset Contract (SAC)](https://developers.stellar.org/docs/learn/smart-contract-internals/stellar-asset-contract) - Token standard for Stellar smart contracts

### Smart Contracts

- [Soroban Documentation](https://soroban.stellar.org/) - Stellar's smart contract platform
- [Contract Address Format](https://developers.stellar.org/docs/learn/encyclopedia/contract-development/types/custom-types#addresses) - Understanding C-addresses vs G-addresses
Loading