Skip to content

Commit abe528b

Browse files
authored
Merge pull request #966 from hirosystems/develop
2 parents de33bf7 + 8966a88 commit abe528b

17 files changed

+638
-1296
lines changed

app/layout.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ export default function RootLayout({
4141
<Provider>
4242
<Banner
4343
id="hiro-hacks"
44-
cta="Learn more"
44+
cta="See February's challenge"
4545
url="/stacks/hacks/recipes"
4646
startDate="2025-02-19"
4747
endDate="2025-02-25T23:59:59.999Z"
4848
mobileText="Hiro Hacks is live!"
4949
>
50-
Get started with this month's theme: Hiro Cookbook
50+
Join Hiro Hacks and compete in monthly coding challenges
5151
</Banner>
5252
{children}
5353
<Footer />

components/code/connect-wallet-button.tsx

+19-25
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,37 @@
11
"use client";
22

33
import React from "react";
4-
import { AppConfig, UserSession, showConnect } from "@stacks/connect";
4+
import { isConnected, connect, disconnect } from "@stacks/connect";
55
import { cn } from "@/lib/utils";
66
import { Button } from "@/components/ui/button";
77

8-
const appConfig = new AppConfig(["store_write", "publish_data"]);
9-
const userSession = new UserSession({ appConfig });
10-
118
export const ConnectWalletButton: React.FC = () => {
129
const [isSignedIn, setIsSignedIn] = React.useState(false);
13-
const [session, setSession] = React.useState({}) as any;
1410

15-
const authenticate = () => {
16-
showConnect({
17-
appDetails: {
18-
name: "My App",
19-
icon: window.location.origin + "/my-app-logo.svg",
20-
},
21-
redirectTo: "/",
22-
onFinish: () => {
23-
const userData = userSession.loadUserData();
24-
setIsSignedIn(true);
25-
setSession(userSession);
26-
console.log(userData);
27-
},
28-
userSession: userSession,
29-
});
30-
};
11+
async function authenticate() {
12+
try {
13+
const response = await connect();
14+
setIsSignedIn(true);
15+
console.log(response);
16+
} catch (error) {
17+
console.error("Authentication failed:", error);
18+
setIsSignedIn(false);
19+
}
20+
}
3121

32-
const logout = () => {
33-
session.signUserOut();
34-
setIsSignedIn(false);
22+
const logout = async () => {
23+
try {
24+
disconnect();
25+
setIsSignedIn(false);
26+
} catch (error) {
27+
console.error("Disconnect failed:", error);
28+
}
3529
};
3630

3731
return (
3832
<Button
3933
className={cn("px-5 py-2 text-sm leading-5 font-semibold z-10 shadow-lg")}
40-
onClick={isSignedIn ? logout : authenticate}
34+
onClick={isSignedIn ? () => void logout() : authenticate}
4135
>
4236
{isSignedIn ? "Log out" : "Connect wallet"}
4337
</Button>

content/docs/guides/build-a-decentralized-kickstarter.mdx

+3-3
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,8 @@ By following this guide, you have created a basic NFT marketplace that allows us
296296
description="Learn how to authenticate users using the Connect package in Stacks.js."
297297
/>
298298
<Card
299-
href="/stacks/connect/guides/sign-transactions"
300-
title="Sign transactions"
301-
description="Learn how to sign transactions using Stacks.js."
299+
href="/stacks/connect/guides/broadcast-transactions"
300+
title="Broadcast transactions"
301+
description="Learn how to sign and broadcast transactions."
302302
/>
303303
</Cards>

content/docs/guides/build-an-nft-marketplace.mdx

+3-3
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,8 @@ By following this guide, you have created a basic NFT marketplace that allows us
296296
description="Learn how to authenticate users using the Connect package in Stacks.js."
297297
/>
298298
<Card
299-
href="/stacks/connect/guides/sign-transactions"
300-
title="Sign transactions"
301-
description="Learn how to sign transactions using Stacks.js."
299+
href="/stacks/connect/guides/broadcast-transactions"
300+
title="Broadcast transactions"
301+
description="Learn how to sign and broadcast transactions."
302302
/>
303303
</Cards>

content/docs/stacks/connect/concepts/providers.mdx

-34
This file was deleted.

content/docs/stacks/connect/guides/authenticate-users.mdx

+61-68
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
---
22
title: Authenticate users
3-
description: Connect to user wallets and authenticate your users using Stacks.js.
3+
description: Connect to user wallets and authenticate your users using @stacks/connect.
44
---
55

66
import { ConnectWalletButton } from '@/components/code/connect-wallet-button';
77
import { ContentBackground } from '@/components/ui/icon';
88

99
Authentication is a fundamental part of many web applications, ensuring that users are who they claim to be and that their data is secure. With the Stacks blockchain, user authentication involves connecting to users' wallets and managing their sessions securely.
1010

11-
The `@stacks/connect` package from Stacks.js provides the tools needed to integrate this functionality seamlessly into your web app.
11+
The `@stacks/connect` package provides the tools needed to integrate this functionality seamlessly into your web app.
1212

1313
In this guide, you will learn how to:
1414

1515
1. [Install the `@stacks/connect` package](#install-the-stacksconnect-package).
16-
2. [Initiate a `UserSession` with specific permission scopes](#initiate-a-usersession).
17-
3. [Trigger the authentication flow with the `showConnect` function](#trigger-the-authentication-flow-with-the-showconnect-function).
18-
4. [Handle pending authentication states and manage user data](#handle-pending-authentication).
16+
2. [Connect to a user's wallet](#connect-to-a-users-wallet).
17+
3. [Manage authentication state](#manage-authentication-state).
18+
4. [Access user data](#access-user-data).
1919

2020
{/* <Callout>To see this guide in action, check out a full example [here](https://github.com/hiro-so/stacks-connect-example).</Callout> */}
2121

@@ -27,32 +27,19 @@ In this guide, you will learn how to:
2727
@stacks/connect
2828
```
2929

30-
## Initiate a UserSession
30+
## Connect to a user's wallet
3131

32-
After installing the `@stacks/connect` package, initiate a `userSession` with the following permission scopes.
32+
After installing the `@stacks/connect` package, you can use the `connect` function to initiate a wallet connection. This will trigger a popup that allows users to select and connect their wallet.
3333

3434
```ts
35-
import { AppConfig, UserSession } from '@stacks/connect';
35+
import { connect } from '@stacks/connect';
3636

37-
const appConfig = new AppConfig(['store_write', 'publish_data']);
38-
const userSession = new UserSession({ appConfig });
37+
async function authenticate() {
38+
const response = await connect();
39+
// response contains the user's addresses
40+
}
3941
```
4042

41-
<Callout>We recommend you initiate the `userSession` object just once in your app, then reference it using imports where needed.</Callout>
42-
43-
Apps may request any of the following scopes:
44-
45-
| Scope | Definition |
46-
| -------------- | ------------------------------------------------------------------------------- |
47-
| `store_write` | Read and write data to the user's Gaia hub in an app-specific storage bucket. |
48-
| `publish_data` | Publish data so other users of the app can discover and interact with the user. |
49-
50-
For more detailed information on these scopes and other API references, visit the [Connect API](/stacks/connect/packages/connect) reference page.
51-
52-
## Trigger the authentication flow with the showConnect function
53-
54-
Create an `authenticate` function that will call `showConnect`, triggering the popup that initiates the authentication process for users. They will authenticate with a [secret key](/stacks/stacks.js/concepts/private-keys) that's used to encrypt their private data.
55-
5643
<div className="not-prose relative overflow-hidden">
5744
<div className="relative bg-card rounded-lg border border-border/50 overflow-auto p-8 h-auto">
5845
<div className="absolute inset-x-0 bottom-0">
@@ -64,66 +51,72 @@ Create an `authenticate` function that will call `showConnect`, triggering the p
6451
</div>
6552
</div>
6653

67-
```ts
68-
function authenticate() {
69-
showConnect({
70-
appDetails: {
71-
name: 'My App',
72-
icon: window.location.origin + '/my-app-logo.svg',
73-
},
74-
redirectTo: '/',
75-
onFinish: () => {
76-
let userData = userSession.loadUserData();
77-
},
78-
userSession,
79-
});
80-
}
81-
```
82-
83-
The `showConnect` function accepts an object with the following properties:
54+
The `connect` function stores the user's addresses in local storage by default, making it easy to persist the user's session across page reloads and browser sessions.
8455

85-
- The app's `name` and `icon`: provided as strings comprising the `appDetails` object property.
86-
- The `redirectTo` string: used to provide a URL to which the user should be redirected upon successful authentication.
87-
- The `onFinish` callback serves a similar purpose by handling successful authentication within a context of a popup window.
88-
- The `userSession` object initiated above.
56+
<Callout>You can customize the connection behavior by passing options to the `connect` function, such as forcing wallet selection or specifying default providers. See the [advanced usage](/stacks/connect/packages/connect#advanced-usage) section for more details.</Callout>
8957

90-
## Handle pending authentication
58+
## Manage authentication state
9159

92-
After initiating the authentication process, you will most likely need to handle cases where the user hasn't completed the authentication flow.
60+
You can manage the user's authentication state using the following functions:
9361

94-
1. Check if there is a pending sign-in using the `isSignInPending` method of the `userSession` object.
95-
2. If there is a pending sign-in, handle it by calling `handlePendingSignIn` which processes the sign-in and then utilizes the `userData` returned in a promise.
62+
```ts
63+
import { connect, disconnect, isConnected } from '@stacks/connect';
9664

97-
```tsx
98-
import { AppConfig, UserSession, showConnect } from '@stacks/connect';
65+
// Check if user is connected
66+
const authenticated = isConnected();
9967

100-
const appConfig = new AppConfig(['store_write', 'publish_data']);
101-
const userSession = new UserSession({ appConfig });
68+
// Connect to wallet
69+
await connect();
10270

103-
window.onload = function () {
104-
if (userSession.isSignInPending()) {
105-
userSession.handlePendingSignIn().then(userData => {
106-
// Save or otherwise utilize userData post-authentication
107-
});
108-
} else if (userSession.isUserSignedIn()) {
109-
// Handle case in which user is already authenticated
110-
}
111-
};
71+
// Disconnect user
72+
disconnect(); // clears local storage and selected wallet
11273
```
11374

114-
For users already signed in, you can directly access their session information and proceed with your app's flow.
75+
## Access user data
76+
77+
Once connected, you can access the user's data using the `getLocalStorage` function or make specific requests using the `request` method:
78+
79+
```ts
80+
import { getLocalStorage, request } from '@stacks/connect';
81+
82+
// Get stored user data
83+
const userData = getLocalStorage();
84+
// {
85+
// "addresses": {
86+
// "stx": [
87+
// { "address": "SP2MF04VAGYHGAZWGTEDW5VYCPDWWSY08Z1QFNDSN" },
88+
// ],
89+
// "btc": [
90+
// { "address": "bc1pp3ha248m0mnaevhp0txfxj5xaxmy03h0j7zuj2upg34mt7s7e32q7mdfae" },
91+
// ]
92+
// }
93+
// }
94+
95+
// Get detailed account information
96+
const accounts = await request('stx_getAccounts');
97+
// {
98+
// "addresses": [
99+
// {
100+
// "address": "SP2MF04VAGYHGAZWGTEDW5VYCPDWWSY08Z1QFNDSN",
101+
// "publicKey": "02d3331cbb9f72fe635e6f87c2cf1a13cd...",
102+
// "gaiaHubUrl": "https://hub.hiro.so",
103+
// "gaiaAppKey": "0488ade4040658015580000000dc81e3a5..."
104+
// }
105+
// ]
106+
// }
107+
```
115108

116-
<Callout title="Note">Implementing `handlePendingSignIn` is particularly important in mobile app contexts to ensure a smooth user experience across all device types.</Callout>
109+
<Callout title="Note">For a list of all available methods, see the [reference](/stacks/connect/packages/connect) page.</Callout>
117110

118111
---
119112

120113
## Next steps
121114

122115
<Cards>
123116
<Card
124-
href="/stacks/connect/guides/sign-transactions"
125-
title="Sign transactions"
126-
description="Learn how to interact with your smart contracts using Stacks.js."
117+
href="/stacks/connect/guides/broadcast-transactions"
118+
title="Broadcast transactions"
119+
description="Learn how to sign and broadcast transactions."
127120
/>
128121
<Card
129122
href="/stacks/stacks.js/guides/post-conditions"

0 commit comments

Comments
 (0)