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
103 changes: 103 additions & 0 deletions content/docs/stacks/connect/guides/migration.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
title: 'Migration Guide'
description: 'How to migrate from v7.x.x to v8.x.x of @stacks/connect'
---

import { Steps, Step } from 'fumadocs-ui/components/steps'


For a while now, the Stacks community has been working on a new standard for wallet-to-dapp communication.
Stacks Connect and related projects now use standards like [WBIPs](https://wbips.netlify.app/) and [SIP-030](https://github.com/janniks/sips/blob/main/sips/sip-030/sip-030-wallet-interface.md) to allow wallets to communicate with dapps in a more simplified and flexible way.

<Callout title="Migration Status">
Please be patient during this latest migration.
There has been a long-running effort together with wallets to modernize and move forward the Stacks web ecosystem.
It is now culminating in [SIP-030](https://github.com/janniks/sips/blob/main/sips/sip-030/sip-030-wallet-interface.md) and the new `request` method in Stacks Connect `8.x.x`.
Bear with us during this migration.
Wallets are still working through some bugs, details, and improvements.

_Feel free to continue using Stacks Connect `7.x.x` while things stabilize._
The `7.x.x` version may still be more well supported by some wallets.

For the legacy version of `@stacks/connect` using JWT tokens, you can use:

```sh
npm install @stacks/connect@7.10.1
```

</Callout>

## Deprecations

The following classes, methods, and types are deprecated in favor of the new `request` RPC methods:

- `show...` and `open...` methods
- `authenticate` method
- `UserSession` class and related functionality
- `AppConfig` class
- `SessionOptions` interface
- `SessionData` interface
- `UserData` interface
- `SessionDataStore` class
- `InstanceDataStore` class
- `LocalStorageStore` class

<Callout title="Backwards Compatibility">
To make migrating easier, the familiar `UserSession` & `AppConfig` class still exists and is semi-backwards compatible for the `8.x.x` release.
It will "cache" the user's address in local storage and allow access to it via the `loadUserData` method (as previously done).
</Callout>

## Migration Steps

To update from `<=7.x.x` to latest/`8.x.x`, follow these steps:

<Steps>
<Step title="Update your @stacks/connect version">
```sh
npm install @stacks/connect@latest
```
</Step>

<Step title="Replace Legacy Methods with request">
Switch from `showXyz`, `openXyz`, `doXyz` methods to the `request` method:

- `request` follows the pattern `request(method: string, params: object)`, see [Usage](#usage) for more details
- `request` is an async function, so replace the `onFinish` and `onCancel` callbacks with `.then().catch()` or `try & await`

Examples:
- `showConnect()`, `authenticate()` → `connect()`
- `useConnect().doContractCall({})` → `request("stx_callContract", {})`
- `openContractDeploy()` → `request("stx_deployContract", {})`
</Step>

<Step title="Use Connect Instead of ShowConnect/Authenticate">
Switch from `showConnect` or `authenticate` to `connect()` methods:

- `connect()` is an alias for `request({forceWalletSelect: true}, 'getAddresses')`
- `connect()` by default caches the user's address in local storage
</Step>

<Step title="Update Authentication State Management">
- Switch from `UserSession.isSignedIn()` to `isConnected()`
- Switch from `UserSession.signUserOut()` to `disconnect()`
</Step>

<Step title="Remove Legacy Code">
- Remove code referencing deprecated methods (`AppConfig`, `UserSession`, etc.)
- Remove the `@stacks/connect-react` package
- You may need to manually reload a component to see local storage updates
- No custom hooks are needed to use Stacks Connect anymore
- We are working on a new `@stacks/react` package that will make usage even easier in the future (e.g., tracking transaction status, reloading components when a connection is established, updating the page when the network changes, and more)
</Step>
</Steps>

## Address Access

Previously, the `UserSession` class was used to access the user's addresses and data, which abstracted away the underlying implementation details.
Now, the `request` method is used to directly interact with the wallet, giving developers more explicit control and clarity over what's happening under the hood.
This manual approach makes the wallet interaction more transparent and customizable.
Developers can manually manage the currently connected user's address in e.g. local storage, jotai, etc. or use the `connect()`/`request()` method to cache the address in local storage.

<Callout title="Security Note">
For security reasons, the `8.x.x` release only returns the current network's address (where previously both mainnet and testnet addresses were returned).
</Callout>
2 changes: 2 additions & 0 deletions content/docs/stacks/connect/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"---Stacks Connect---",
"index",
"quickstart",
"support",
"---Guides---",
"guides/migration",
"guides/authenticate-users",
"guides/broadcast-transactions",
"guides/sign-messages",
Expand Down
64 changes: 58 additions & 6 deletions content/docs/stacks/connect/packages/connect.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import { InlineCode } from '@/components/inline-code';

Stacks Connect enables you to authenticate your users and connect your app to their wallet. This reference contains more detailed information on how you can authenticate users, sign and broadcast transactions on their behalf, and enable users to sign messages.

<Callout title="Migration Note">
Please be patient during the migration to version 8.x.x. There has been a long-running effort together with wallets to modernize the Stacks web ecosystem, culminating in [SIP-030](https://github.com/janniks/sips/blob/main/sips/sip-030/sip-030-wallet-interface.md) and the new `request` method in Stacks Connect 8.x.x. For the legacy version of `@stacks/connect` using JWT tokens, please use version 7.10.1. See the [Migration Guide](/docs/stacks/connect/guides/migration) for more details.
</Callout>

### Installation

```package-install
Expand Down Expand Up @@ -72,7 +76,7 @@ const response = await request({ forceWalletSelect: true }, 'getAddresses');
### Available methods

- [getAddresses](#getaddresses)
- [sendTransfer](#sendtransfer)
- [sendTransfer](#sendtransfer)
- [signPsbt](#signpsbt)
- [stx_getAddresses](#stx_getaddresses)
- [stx_getAccounts](#stx_getaccounts)
Expand Down Expand Up @@ -259,11 +263,41 @@ const response = await request('stx_signStructuredMessage', {
// }
```

### Error Handling

The `request` method returns a Promise, allowing you to handle errors using standard Promise-based error handling patterns. You can use either `try/catch` with `async/await` or the `.catch()` method with Promise chains.

#### Using try/catch with async/await

```typescript
import { request } from '@stacks/connect';

try {
const response = await request('stx_transferStx', {
amount: '1000',
recipient: 'SP2MF04VAGYHGAZWGTEDW5VYCPDWWSY08Z1QFNDSN',
});
// SUCCESS
console.log('Transaction successful:', response.txid);
} catch (error) {
// ERROR
console.error('Wallet returned an error:', error);
}
```

### Compatibility

The `request` method by default adds a layer of auto-compatibility for different wallet providers. This is meant to unify the interface where wallet providers may not implement methods and results the same way.

<Callout title="Wallet Support">
For a complete list of wallet compatibility and support status, see the [Wallet Support](/docs/stacks/connect/support) page.
</Callout>

### Advanced Usage

#### request

The request method is called with an optional options object as the first parameter:
The `request` method is called with an optional options object as the first parameter:

```typescript
import { request } from '@stacks/connect';
Expand All @@ -272,10 +306,14 @@ import { request } from '@stacks/connect';
const response = await request(
{
provider?: StacksProvider; // Custom provider to use for the request
defaultProviders?: WbipProvider[]; // Default wallets to display in modal

forceWalletSelect?: boolean; // Force user to select a wallet (default: false)
persistWalletSelect?: boolean; // Persist selected wallet (default: true)
enableOverrides?: boolean; // Enable provider compatibility (default: true)
enableLocalStorage?: boolean; // Store address in local storage (default: true)

defaultProviders?: WbipProvider[]; // Default wallets to display in modal
approvedProviderIds?: string[]; // List of approved provider IDs to show in modal
},
'method',
params
Expand All @@ -285,10 +323,24 @@ const response = await request(
const response = await request('method', params);
```

<Callout type="info">
<Callout title="Provider Compatibility">
The `enableOverrides` option enables automatic compatibility fixes for different wallet providers. For example, it handles converting numeric types between string and number formats as needed by different wallets, and remaps certain method names to match wallet-specific implementations. This ensures consistent behavior across different wallet providers without requiring manual adjustments.
</Callout>

<Callout title="Approved Providers">
The `approvedProviderIds` option allows you to filter which wallet providers are shown in the connect modal. This is useful when you want to limit the available wallet options to specific providers. For example, you might only want to support Leather wallet:

```typescript
connect({ approvedProviderIds: ['LeatherProvider'] });
```

Or multiple specific wallets:

```typescript
connect({ approvedProviderIds: ['LeatherProvider', 'xverse'] });
```
</Callout>

#### requestRaw

The `requestRaw` method provides direct access to wallet providers without the additional features of `request`:
Expand All @@ -299,6 +351,6 @@ import { requestRaw } from '@stacks/connect';
const response = await requestRaw(provider, 'method', params);
```

<Callout type="info">
`requestRaw` bypasses the UI wallet selector and other features that come with `request`, such as automatic compatibility across different providers. Use this when you need more manual control over the wallet interaction process.
<Callout title="Raw Request">
`requestRaw` bypasses the UI wallet selector, automatic provider compatibility fixes, and other features that come with `request`. Use this when you need more manual control over the wallet interaction process.
</Callout>
154 changes: 154 additions & 0 deletions content/docs/stacks/connect/support.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
---
title: 'Wallet Support'
description: 'Compatibility information for different wallet providers'
---

import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow
} from "@/components/ui/table";

This page provides detailed information about which methods and events are supported by different wallet providers in the Stacks ecosystem.

## Method Compatibility

<Table>
<TableHeader>
<TableRow>
<TableHead>Method</TableHead>
<TableHead>Leather</TableHead>
<TableHead>Xverse-like</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell><code>getAddresses</code></TableCell>
<TableCell>🟡 No support for experimental purposes</TableCell>
<TableCell>🟡 Use <code>wallet_connect</code> instead</TableCell>
</TableRow>
<TableRow>
<TableCell><code>sendTransfer</code></TableCell>
<TableCell>🟡 Expects <code>amount</code> as string</TableCell>
<TableCell>🟡 Expects <code>amount</code> as number</TableCell>
</TableRow>
<TableRow>
<TableCell><code>signPsbt</code></TableCell>
<TableCell>🟡 Uses signing index array only</TableCell>
<TableCell>🟡 Uses <code>signInputs</code> record instead of array</TableCell>
</TableRow>
<TableRow>
<TableCell><code>stx_getAddresses</code></TableCell>
<TableCell>🟢</TableCell>
<TableCell>🔴</TableCell>
</TableRow>
<TableRow>
<TableCell><code>stx_getAccounts</code></TableCell>
<TableCell>🔴</TableCell>
<TableCell>🟢</TableCell>
</TableRow>
<TableRow>
<TableCell><code>stx_getNetworks</code></TableCell>
<TableCell>🔴</TableCell>
<TableCell>🔴</TableCell>
</TableRow>
<TableRow>
<TableCell><code>stx_transferStx</code></TableCell>
<TableCell>🟢</TableCell>
<TableCell>🟢</TableCell>
</TableRow>
<TableRow>
<TableCell><code>stx_transferSip10Ft</code></TableCell>
<TableCell>🟢</TableCell>
<TableCell>🔴</TableCell>
</TableRow>
<TableRow>
<TableCell><code>stx_transferSip9Nft</code></TableCell>
<TableCell>🟢</TableCell>
<TableCell>🔴</TableCell>
</TableRow>
<TableRow>
<TableCell><code>stx_callContract</code></TableCell>
<TableCell>🟡 Hex-encoded Clarity values only</TableCell>
<TableCell>🟡 Hex-encoded Clarity values only, no support for <code>postConditions</code></TableCell>
</TableRow>
<TableRow>
<TableCell><code>stx_deployContract</code></TableCell>
<TableCell>🟡 Hex-encoded Clarity values only</TableCell>
<TableCell>🟡 Hex-encoded Clarity values only, no support for <code>postConditions</code></TableCell>
</TableRow>
<TableRow>
<TableCell><code>stx_signTransaction</code></TableCell>
<TableCell>🟡 Hex-encoded Clarity values only</TableCell>
<TableCell>🟡 Hex-encoded Clarity values only</TableCell>
</TableRow>
<TableRow>
<TableCell><code>stx_signMessage</code></TableCell>
<TableCell>🟡 Hex-encoded Clarity values only</TableCell>
<TableCell>🟡 Hex-encoded Clarity values only</TableCell>
</TableRow>
<TableRow>
<TableCell><code>stx_signStructuredMessage</code></TableCell>
<TableCell>🟡 Hex-encoded Clarity values only</TableCell>
<TableCell>🟡 Hex-encoded Clarity values only</TableCell>
</TableRow>
<TableRow>
<TableCell><code>stx_updateProfile</code></TableCell>
<TableCell>🔴</TableCell>
<TableCell>🔴</TableCell>
</TableRow>
</TableBody>
</Table>

## Event Compatibility

<Table>
<TableHeader>
<TableRow>
<TableHead>Event</TableHead>
<TableHead>Leather</TableHead>
<TableHead>Xverse</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell><code>stx_accountChange</code></TableCell>
<TableCell>🔴</TableCell>
<TableCell>🔴</TableCell>
</TableRow>
<TableRow>
<TableCell><code>stx_networkChange</code></TableCell>
<TableCell>🔴</TableCell>
<TableCell>🔴</TableCell>
</TableRow>
</TableBody>
</Table>

**Legend**

- 🔴 No support (yet)
- 🟡 Partial support
- 🟢 Supported

## Compatibility Layer

The `request` method in `@stacks/connect` adds a layer of auto-compatibility for different wallet providers. This helps unify the interface where wallet providers may implement methods and results differently.

| Method | Status | Notes |
| --------------------------- | ------ | ---------------------------------------------------------------------------------------------------- |
| `getAddresses` | 🔵 | Maps to `wallet_connect` for Xverse-like wallets |
| `sendTransfer` | 🔵 | Converts `amount` to number for Xverse, string for Leather |
| `signPsbt` | 🟡 | Transforms PSBT format for Leather (base64 to hex) with lossy restructure of `signInputs` |
| `stx_getAddresses` | 🔵 | Maps to `wallet_connect` for Xverse-like wallets |
| `stx_callContract` | 🔵 | Transforms Clarity values to hex-encoded format for compatibility |
| `stx_deployContract` | 🔵 | Transforms Clarity values to hex-encoded format for compatibility |
| `stx_signTransaction` | 🔵 | Transforms Clarity values to hex-encoded format for compatibility |
| `stx_signMessage` | 🔵 | Transforms Clarity values to hex-encoded format for compatibility |
| `stx_signStructuredMessage` | 🔵 | Transforms Clarity values to hex-encoded format for compatibility |

- 🟢 No overrides needed for any wallet
- 🔵 Has compatibility overrides that maintain functionality
- 🟡 Has breaking overrides that may lose some information