Deep dive into Post-Conditions

This guide explains how to use Post-Conditions to secure your smart contracts.

You will learn how to:

  • Prompt users to sign transactions using the @stacks/connect package
  • Broadcast signed transactions to the Stacks blockchain for execution
  • Handle transaction results, including success and error states
  • Work with different types of transactions: STX transfers, contract deployments, and contract executions

Install dependencies

These are the three main packages we'll use to authenticate users and build our transactions for broadcasting to the Stacks blockchain network.

npm install @stacks/connect @stacks/network @stacks/transactions

Initiate a userSession with specific permission scopes

After installing the @stacks/connect package, the next step is to initiate a userSession with specific permission scopes.

import { AppConfig, UserSession } from '@stacks/connect';

const appConfig = new AppConfig(['store_write', 'publish_data']);
const userSession = new UserSession({ appConfig });
ScopeDefinition
store_writeRead and write data to the user's Gaia hub in an app-specific storage bucket.
publish_dataPublish data so other users of the app can discover and interact with the user.
Note
We recommend you initiate the userSession object just once in your app then reference it using imports where needed.

Trigger the authentication flow with the showConnect function

Let's create an authenticate function that will call showConnect, triggering the popup that initiates the authentication process for users, one in which they'll authenticate with a Secret Key that's used to encrypt their private data.

function authenticate() {
  showConnect({
    appDetails: {
      name: 'My App',
      icon: window.location.origin + '/my-app-logo.svg',
    },
    redirectTo: '/',
    onFinish: () => {
      let userData = userSession.loadUserData();
    },
    userSession: userSession,
  });
}

Once the user confirms, they will be redirected to the installed web wallet to authenticate with the authRequest token.

Handle Pending Authentication

After the authentication process is initiated, it's crucial to handle cases where the user hasn't completed the authentication flow. This involves managing the pending authentication state when the user is redirected back to the app without having confirmed their authentication in the popup window.

import { AppConfig, UserSession, showConnect } from '@stacks/connect';

const appConfig = new AppConfig(['store_write', 'publish_data']);
const userSession = new UserSession({ appConfig });

window.onload = function () {
  if (userSession.isSignInPending()) {
    userSession.handlePendingSignIn().then(userData => {
      // Save or otherwise utilize userData post-authentication
    });
  } else if (userSession.isUserSignedIn()) {
    // Handle case in which user is already authenticated
  }
};

The isSignInPending method checks if there's a pending sign-in to process. If so, handlePendingSignIn processes the pending sign-in, allowing you to save or use the user's data post-authentication. For users already signed in, you can directly access their session information or proceed with your app's flow.

Note
Implementing handlePendingSignIn is particularly important in mobile app contexts to ensure a smooth user experience across all device types.

Next step: Add unit tests with the Clarinet SDK

The Clarinet SDK allows you to write unit tests for your Clarity smart contracts. You can theoretically use any JavaScript test framework, but the SDK supports Vitest out of the box.

More resources

Last updated on