Skip to main content
Smart sessions are the core capability that makes embedded wallets practical for payment products. They let your app submit transactions on behalf of a user within a strictly defined permission window, without prompting the user every time. For a payment app, this means a user can authorize a recurring payment, a batch settlement, or a multi-step checkout once, and the app handles the rest without interruption.

The problem smart sessions solve

Standard wallet UX requires the user to approve every transaction. For payment flows such as subscriptions, multi-step checkouts, and bulk disbursements, this creates unacceptable friction. Smart sessions replace per-transaction approvals with a scoped, time-limited permission grant.

Two session types

Implicit sessions

Implicit sessions are cryptographically locked to your app’s domain. Once the user is signed in, your app can transact without any additional approval, as long as the transactions stay within your app’s own contracts and the user’s gas is sponsored. When to use: In-app payment flows, recurring transfers within a single product. Constraints:
  • Transactions must interact only with contracts your app controls.
  • Your app must sponsor gas (users cannot pay gas directly in implicit sessions).
  • Locked to your domain; another site cannot use the session.

Explicit sessions

Explicit sessions are user-approved, rule-based permissions. The user reviews and signs a permission set that defines exactly what your app can do: which contracts it can call, which methods, maximum token amounts, and an expiry time. When to use: Interactions with external DeFi protocols, stablecoin transfers with spending limits, any flow where the user should explicitly authorize scope. Example permission set:
import {
  createConfig,
  createContractPermission,
  createExplicitSession,
} from "@0xsequence/connect";

const config = createConfig({
  projectAccessKey: process.env.NEXT_PUBLIC_PROJECT_ACCESS_KEY,
  // ...other config
  session: createExplicitSession({
    permissions: [
      createContractPermission({
        contractAddress: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", // USDC on Polygon
        methods: ["transfer"],
        valueLimit: "100000000", // 100 USDC (6 decimals)
      }),
    ],
    expiry: Math.floor(Date.now() / 1000) + 86400, // 24 hours
  }),
});
The user approves this session once. Your app can then transfer up to 100 USDC per session period without prompting again.

Combining session types

Most payment products use both:
  1. Implicit session for in-app UI interactions (status checks, balance reads, small in-app transfers).
  2. Explicit session for external transfers or protocol interactions requiring user-scoped approval.

Security guarantees

Smart sessions are enforced onchain. Transactions that exceed the defined scope are rejected at the contract level; your app cannot exceed what the user approved, even accidentally. The session rules are part of the wallet’s Merkleized configuration, meaning they are cryptographically verifiable without trusting any off-chain service.

Further reading

Smart sessions overview

Full documentation on session types, permissions, and onchain enforcement.

Permissions deep dive

Advanced permission configuration and examples.