Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6af05eb
Add Freighter developer documentation
piyalbasu Apr 9, 2026
2d87af7
Address PR review feedback: fix broken links, wrong paths, and browse…
piyalbasu Apr 9, 2026
90e6545
Fix error type: error is FreighterApiError object, not string
piyalbasu Apr 9, 2026
a01ff40
Fix mobile signing docs to match freighter-mobile source
piyalbasu Apr 9, 2026
558da0b
Rewrite introduction and add Stellar Wallets Kit integration
piyalbasu Apr 10, 2026
a96a02a
Note that Stellar Wallets Kit is desktop-only
piyalbasu Apr 10, 2026
fe49492
Fix missed error.message in reading-data.md and docsify CDN 404
piyalbasu Apr 10, 2026
aef2f2a
Update README.md
piyalbasu Apr 10, 2026
8cea352
Update developer-guide/signing.md
piyalbasu Apr 10, 2026
af12890
Rename developer-guide/ to extension/
piyalbasu Apr 10, 2026
968bb1f
Reduce redundant non-custodial/user-control messaging in intro
piyalbasu Apr 10, 2026
c5600a3
Emphasize in-app browser WalletConnect flow over QR code scanning
piyalbasu Apr 10, 2026
5484389
Fix Stellar Wallets Kit description: it supports mobile via WalletCon…
piyalbasu Apr 10, 2026
6392634
Rewrite Why Freighter to differentiate vs other Stellar wallets
piyalbasu Apr 10, 2026
e29fa23
Replace "Choose Your Integration" with straightforward Get Started links
piyalbasu Apr 10, 2026
bcc4c36
Remove recommendation label from requestAccess()
piyalbasu Apr 10, 2026
cbee6f2
Add context for why dapps need addToken
piyalbasu Apr 10, 2026
2c68084
Align token terminology with Stellar developer docs
piyalbasu Apr 10, 2026
be3d988
Rename extension overview title to Extension Integration
piyalbasu Apr 10, 2026
ded2da6
Move import examples from extension overview to installation page
piyalbasu Apr 10, 2026
b033a73
Move dual-integration guidance to Get Started, remove inaccurate details
piyalbasu Apr 10, 2026
14fcca7
Add hint that isConnected can detect desktop vs mobile
piyalbasu Apr 10, 2026
53048a9
Fix inconsistencies between extension and mobile docs
piyalbasu Apr 10, 2026
3bcf747
Fix isConnected hint and mobile full example requiredNamespaces
piyalbasu Apr 10, 2026
7ececcd
Apply Cassio's review feedback on WalletConnect docs
piyalbasu Apr 13, 2026
91e848f
Migrate mobile docs to @walletconnect/universal-provider (#2)
CassioMG Apr 13, 2026
70a7b75
Address Jake's review feedback
piyalbasu Apr 14, 2026
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
5 changes: 5 additions & 0 deletions .gitbook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
root: ./

structure:
readme: README.md
summary: SUMMARY.md
58 changes: 56 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,56 @@
# freighter-developer-docs
Freighter wallet developer documentation
# Welcome to Freighter

Freighter is a non-custodial wallet for the Stellar network, available as a browser extension and a mobile app. Non-custodial means your users hold their own keys — your dapp never sees or stores private keys. This guide walks you through integrating Freighter so your users can connect their wallets, sign transactions, and interact with Soroban smart contracts.

## What You Can Build

With Freighter, your dapp can connect a user's wallet with a single call — no signup form, no password, just a familiar wallet popup and an immediate public key. From there you can read their active network, hand off transactions for signing, and submit to the network.

For dapps that integrate with smart contracts, Freighter also handles authorization entry signing for smart contract calls and arbitrary message signing for account verification.

## How It Works

The integration model is simple: your dapp talks to the wallet, and the wallet talks to the user.

For **desktop browsers**, you integrate with the Freighter extension through a lightweight JavaScript library. It injects itself into the page, and your dapp calls methods like "is the wallet connected?", "what's the user's address?", and "please sign this transaction."

For **mobile**, the integration works over WalletConnect v2. When a user opens your dapp in a mobile browser, WalletConnect presents a modal where they select Freighter as their wallet and approve the connection. On desktop, the same flow can display a QR code for the user to scan. Either way, a secure relay session is established and signing requests flow through the same pattern — your dapp proposes, the user reviews and approves in the wallet.

Both paths produce the same output: signed transactions you can submit to the Stellar network. So your backend and submission logic stay the same regardless of whether your user connected from a laptop or a phone.

If you want to support multiple Stellar wallets — not just Freighter — take a look at [Stellar Wallets Kit](https://stellarwalletskit.dev/). It provides a unified interface across Stellar wallets, including browser extensions and WalletConnect-based mobile wallets, so your users can connect with whichever wallet they prefer.

> **Note:** Stellar Wallets Kit's WalletConnect module currently only exposes `stellar_signXDR` and `stellar_signAndSubmitXDR`. If your dapp needs `stellar_signMessage` or `stellar_signAuthEntry` against Freighter Mobile, integrate WalletConnect directly for now (tracked in [stellar/freighter-mobile#815](https://github.com/stellar/freighter-mobile/issues/815)).

## Why Freighter

**Built and maintained by SDF.** Freighter is developed by the Stellar Development Foundation, the same team behind the core Stellar protocol and SDKs.

**Complete Stellar support.** Transaction signing, Soroban authorization entry signing with contract invocation inspection, SEP-53 message signing, contract token management, and Blockaid transaction scanning.

**Desktop and mobile.** Browser extension for desktop, WalletConnect for mobile. Both paths produce the same signed output, so your dapp supports both with minimal branching.

## Get Started

**Desktop** — integrate with the Freighter browser extension using `@stellar/freighter-api`. See the [Extension Guide](extension/installation.md).

**Mobile** — connect to Freighter Mobile over WalletConnect v2. See the [Mobile Guide](mobile/README.md).

**Both** — if your dapp needs to support desktop and mobile users, use both integration paths. Both produce the same output (signed XDR), so your submission logic stays the same regardless of how the user connected.

## Quick links

| I want to... | Extension | Mobile |
| ------------------------------------- | -------------------------------------------------- | ---------------------------------------------------- |
| Install / set up | [Installation](extension/installation.md) | [Installation](mobile/installation.md) |
| Connect to Freighter | [Connecting](extension/connecting.md) | [Connecting](mobile/connecting.md) |
| Sign a transaction | [Signing](extension/signing.md) | [Signing](mobile/signing.md) |
| Add a token | [Token Management](extension/token-management.md) | — |

## Resources

- [GitHub — Freighter Extension](https://github.com/stellar/freighter)
- [GitHub — Freighter Mobile](https://github.com/stellar/freighter-mobile)
- [Chrome Extension Store](https://chromewebstore.google.com/detail/freighter/bcacfldlkkdogcmkkibnjlakofdplcbk)
- [Stellar Developer Docs](https://developers.stellar.org)
- [WalletConnect v2 Docs](https://docs.walletconnect.network/app-sdk/overview)
24 changes: 24 additions & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Table of contents

* [Introduction](README.md)

## Extension (freighter-api)

* [Installation](extension/installation.md)
* [Overview](extension/README.md)
* [Connecting](extension/connecting.md)
* [Reading Data](extension/reading-data.md)
* [Signing](extension/signing.md)
* [Token Management](extension/token-management.md)
* [Watching Changes](extension/watching-changes.md)

## Mobile (WalletConnect)

* [Installation](mobile/installation.md)
* [Overview](mobile/README.md)
* [Connecting](mobile/connecting.md)
* [Signing](mobile/signing.md)

## Integrations

* [Third-Party Integrations](integrations/README.md)
27 changes: 27 additions & 0 deletions extension/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Extension Integration

Integrate Freighter into your web application using `@stellar/freighter-api`. This library lets you send and receive data from a user's Freighter extension.

`@stellar/freighter-api` adheres to the [SEP-43](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0043.md) standard for wallet interfaces on Stellar, and also offers additional methods beyond the spec such as `getNetworkDetails`, `addToken`, and `WatchWalletChanges`.

## Error Type

All methods return an optional `error` field of type `FreighterApiError`:

```typescript
interface FreighterApiError {
code: number;
message: string;
ext?: string[];
}
```

## API Reference

| Category | Description |
| --- | --- |
| [Connecting](connecting.md) | Detect Freighter, check permissions, request access |
| [Reading Data](reading-data.md) | Get the user's address and network configuration |
| [Signing](signing.md) | Sign transactions, auth entries, and messages |
| [Token Management](token-management.md) | Add contract tokens to the user's wallet |
| [Watching Changes](watching-changes.md) | Monitor wallet state changes in real time |
101 changes: 101 additions & 0 deletions extension/connecting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Connecting to Freighter

Detect whether a user has Freighter installed, check if your app is authorized, and request access to the user's public key.

## Detecting Freighter

### `isConnected()`

Check if the user has Freighter installed in their browser.

**Returns:** `Promise<{ isConnected: boolean } & { error?: FreighterApiError }>`

```typescript
import { isConnected } from "@stellar/freighter-api";

const result = await isConnected();

if (result.isConnected) {
console.log("Freighter is installed");
}
```

{% hint style="info" %}
`isConnected()` checks whether the Freighter extension is installed. Note that it returns `false` for any user without the extension — not just mobile users. To detect Freighter Mobile's in-app browser specifically, check for `window.stellar?.platform === "mobile"`.
{% endhint %}

## Checking Authorization

### `isAllowed()`

Check if the user has previously authorized your app to receive data from Freighter.

**Returns:** `Promise<{ isAllowed: boolean } & { error?: FreighterApiError }>`

```typescript
import { isAllowed } from "@stellar/freighter-api";

const result = await isAllowed();

if (result.isAllowed) {
console.log("App is on the Allow List");
}
```

## Requesting Authorization

### `setAllowed()`

Prompt the user to authorize your app and add it to Freighter's **Allow List**. Once approved, the extension can provide user data without additional prompts.

**Returns:** `Promise<{ isAllowed: boolean } & { error?: FreighterApiError }>`

```typescript
import { setAllowed } from "@stellar/freighter-api";

const result = await setAllowed();

if (result.isAllowed) {
console.log("App added to Allow List");
}
```

{% hint style="info" %}
If the user has already authorized your app, `setAllowed()` resolves immediately with `{ isAllowed: true }`.
{% endhint %}

## Requesting Access

### `requestAccess()`

Prompt the user to add your dapp to Freighter's Allow List and return their public key in one call. This is the recommended way to connect — it combines authorization and data retrieval in a single step.

**Returns:** `Promise<{ address: string } & { error?: FreighterApiError }>`

If the user has previously authorized your app, the public key is returned immediately without a popup.

```typescript
import { isConnected, requestAccess } from "@stellar/freighter-api";

// Always check isConnected first
const connectResult = await isConnected();
if (!connectResult.isConnected) {
console.error("Freighter is not installed");
return;
}

const accessResult = await requestAccess();
if (accessResult.error) {
console.error("Access denied:", accessResult.error.message);
} else {
console.log("Public key:", accessResult.address);
}
```

{% hint style="warning" %}
Always check `isConnected()` before calling `requestAccess()` to ensure the extension is available.
{% endhint %}

## Next steps

Once connected, you can [read the user's address and network](reading-data.md) or [sign transactions](signing.md).
85 changes: 85 additions & 0 deletions extension/installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Installation

Get up and running with Freighter by installing the browser extension and choosing the right integration method for your app.

## Prerequisites

1. Install the [Freighter browser extension](https://chromewebstore.google.com/detail/freighter/bcacfldlkkdogcmkkibnjlakofdplcbk) from the Chrome Web Store.
2. Choose an integration method below based on your project setup.

## Choose Your Integration

### npm / yarn

Use this when building with a bundler (Webpack, Vite, etc.) in a React, Next.js, or other modern JS framework.

**Ideal for:**

- React, Vue, Svelte, or Angular applications
- Server-side rendered apps (Next.js, Nuxt)
- Any project using a JavaScript bundler

```bash
npm install @stellar/freighter-api
```

```bash
yarn add @stellar/freighter-api
```

Then import in your code. You can import the entire library:

```javascript
import freighterApi from "@stellar/freighter-api";
```

Or import only what you need:

```javascript
import {
isConnected,
getAddress,
signAuthEntry,
signTransaction,
signMessage,
addToken,
} from "@stellar/freighter-api";
```

> See the [Extension Integration](../extension/) for the full API reference.

### CDN (script tag)

Use this for plain HTML pages or projects without a build step. The library is loaded directly in the browser.

**Ideal for:**

- Static HTML sites
- Prototypes and quick experiments
- Projects without a bundler

Add to your `<head>`:

```html
<script src="https://unpkg.com/@stellar/freighter-api/build/index.min.js"></script>
```

This always loads the latest version automatically. To pin a specific version:

```html
<script src="https://unpkg.com/@stellar/freighter-api@6.0.1/build/index.min.js"></script>
```

Then access the API via `window.freighterApi`:

```javascript
const { address } = await window.freighterApi.requestAccess();
```

## Next steps

| I want to... | Go to |
| ------------------------------------- | -------------------------------------------------------- |
| Connect my app to Freighter | [Connecting](../extension/connecting.md) |
| Sign a transaction | [Signing](../extension/signing.md) |
| Add a token | [Token Management](../extension/token-management.md) |
71 changes: 71 additions & 0 deletions extension/reading-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Reading Data

Retrieve the user's public key and network configuration from Freighter.

{% hint style="info" %}
These methods require that the user has previously authorized your app via [`requestAccess()`](connecting.md#requesting-access) or [`setAllowed()`](connecting.md#requesting-authorization).
{% endhint %}

## Getting the User's Address

### `getAddress()`

A lightweight way to retrieve the user's public key. Unlike `requestAccess()`, this will **not** prompt the user — it returns an empty string if the app isn't authorized or Freighter isn't connected.

**Returns:** `Promise<{ address: string } & { error?: FreighterApiError }>`

```typescript
import { getAddress } from "@stellar/freighter-api";

const { address, error } = await getAddress();

if (error) {
console.error(error.message);
} else {
console.log("Public key:", address);
}
```

## Getting the Network

### `getNetwork()`

Get the name and passphrase of the network the user has selected in Freighter.

**Returns:** `Promise<{ network: string; networkPassphrase: string } & { error?: FreighterApiError }>`

Possible `network` values: `PUBLIC`, `TESTNET`, `FUTURENET`, or `STANDALONE` (custom networks).

```typescript
import { getNetwork } from "@stellar/freighter-api";

const { network, networkPassphrase, error } = await getNetwork();

if (!error) {
console.log("Network:", network); // e.g., "TESTNET"
console.log("Passphrase:", networkPassphrase);
}
```

### `getNetworkDetails()`

Get comprehensive network configuration including the Horizon URL, passphrase, and Soroban RPC URL.

**Returns:** `Promise<{ network: string; networkUrl: string; networkPassphrase: string; sorobanRpcUrl?: string } & { error?: FreighterApiError }>`

```typescript
import { getNetworkDetails } from "@stellar/freighter-api";

const details = await getNetworkDetails();

if (!details.error) {
console.log("Network:", details.network); // e.g., "TESTNET"
console.log("Horizon:", details.networkUrl); // e.g., "https://horizon-testnet.stellar.org"
console.log("Passphrase:", details.networkPassphrase);
console.log("Soroban RPC:", details.sorobanRpcUrl); // e.g., "https://soroban-testnet.stellar.org"
}
```

{% hint style="info" %}
Use `getNetworkDetails()` instead of `getNetwork()` when working with Soroban smart contracts or when you need specific network endpoints.
{% endhint %}
Loading