> ## Documentation Index
> Fetch the complete documentation index at: https://docs.startale.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Smart account setup

> Create a Startale smart account, initialize the account client, and persist it across renders.

This page is the bridge between [Installation](/aa-sdk/tutorials/installation) and the feature tutorials. By the end you will have a smart account, an account client wired to the SCS bundler and paymaster, and a place to keep them in your app's state.

<Note>
  Source: [`StartaleGroup/scs-aa-sdk`](https://github.com/StartaleGroup/scs-aa-sdk). Every symbol on this page is exported from `@startale-scs/aa-sdk` or `viem`.
</Note>

## What you will build

```mermaid theme={null}
flowchart LR
  Signer["Signer<br/>(viem / EIP-1193 / ethers)"] --> Acct
  Acct["StartaleSmartAccount<br/>(toStartaleSmartAccount)"] --> Client
  Paymaster["SCSPaymasterClient<br/>(createSCSPaymasterClient)"] --> Client
  Client["StartaleAccountClient<br/>(createSmartAccountClient)"] --> App[Your dApp]
```

`StartaleAccountClient` is the object you actually call `sendUserOperation` and ERC-7579 module actions on. The smart account and paymaster clients are wired into it once at setup time.

## Account creation

```ts theme={null}
import { http, createPublicClient } from "viem"
import { soneiumMinato } from "viem/chains"
import { toStartaleSmartAccount } from "@startale-scs/aa-sdk"

const publicClient = createPublicClient({ chain: soneiumMinato, transport: http() })

const account = await toStartaleSmartAccount({
  signer,
  chain: soneiumMinato,
  transport: http(),
  index: 0n,
})
```

| Parameter                                                            | Required | Source                 | Notes                                                                                                                                                                                |
| -------------------------------------------------------------------- | -------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `signer`                                                             | yes      | your auth provider     | `LocalAccount`, viem `WalletClient`, EIP-1193 `EthereumProvider`, or `EthersWallet`. See [Installation](/aa-sdk/tutorials/installation#pick-a-signer).                               |
| `chain`                                                              | yes      | `viem/chains`          | Use `soneiumMinato` for testnet and `soneium` for mainnet.                                                                                                                           |
| `transport`                                                          | yes      | `viem`                 | RPC transport used internally for chain reads (nonces, code).                                                                                                                        |
| `index`                                                              | optional | your code              | A `bigint` salt that determines the counterfactual address. Different `index` values with the same signer produce different accounts.                                                |
| `accountAddress`                                                     | optional | your code              | Pin a known smart account address. Useful for [EIP-7702 delegation](/aa-sdk/eip7702) and for skipping address derivation.                                                            |
| `validators`, `executors`, `prevalidationHooks`, `hook`, `fallbacks` | optional | `@startale-scs/aa-sdk` | ERC-7579 modules to install at deployment time. See [Smart sessions](/aa-sdk/tutorials/smart-sessions) and [Social recovery](/aa-sdk/tutorials/social-recovery) for module examples. |

<Tip>
  **Why `index` matters.** Smart accounts are deployed via CREATE2, so the `(signer, index)` pair determines the account address before deployment. Use a stable `index` per user (often `0n`) to keep one account per signer; vary it when you intentionally want sub-accounts under the same signer.
</Tip>

## Account client (sponsored gas)

Wrap the account, the paymaster, and the bundler transport in a single client:

```ts theme={null}
import { http } from "viem"
import {
  createSCSPaymasterClient,
  createSmartAccountClient,
} from "@startale-scs/aa-sdk"

const paymasterClient = createSCSPaymasterClient({
  transport: http(process.env.PAYMASTER_URL!),
})

const smartAccountClient = createSmartAccountClient({
  account,
  transport: http(process.env.BUNDLER_URL!),
  client: publicClient,
  paymaster: paymasterClient,
  paymasterContext: {
    paymasterId: process.env.PAYMASTER_ID!,
  },
})
```

| Symbol                         | Source                 | Role                                                                                         |
| ------------------------------ | ---------------------- | -------------------------------------------------------------------------------------------- |
| `createSCSPaymasterClient`     | `@startale-scs/aa-sdk` | Connects to the SCS Paymaster RPC. Returns a `SCSPaymasterClient`.                           |
| `createSmartAccountClient`     | `@startale-scs/aa-sdk` | Builds a `StartaleAccountClient` with bundler, paymaster, and ERC-7579 module actions.       |
| `paymasterContext.paymasterId` | SCS Portal             | The id of the paymaster you provisioned. Both managed and self-funded paymasters return one. |

## Account client (ERC-20 gas)

To accept ERC-20 tokens as gas instead of sponsoring, swap the `paymasterId` field for a `token` address:

```ts theme={null}
const tokenAccountClient = createSmartAccountClient({
  account,
  transport: http(process.env.BUNDLER_URL!),
  client: publicClient,
  paymaster: paymasterClient,
  paymasterContext: {
    token: "0xfF0CBFbA43a1Ce2B8d72B2f3121558BcBd4B03a6", // USDC on Soneium Minato
  },
})
```

The supported tokens per network are listed in [Supported networks](/aa-sdk/resources/supported-networks). The full token paymaster flow, including quotes and approvals, is covered in the [ERC-20 paymaster tutorial](/aa-sdk/tutorials/erc20-payment).

## Persisting the client in a React app

A common pattern is to lift the smart account and clients into a context provider so they survive component remounts and are available everywhere in the tree.

```tsx StartaleProvider.tsx theme={null}
import { createContext, useContext, useEffect, useState, type ReactNode } from "react"
import { http, createPublicClient } from "viem"
import { soneiumMinato } from "viem/chains"
import {
  createSCSPaymasterClient,
  createSmartAccountClient,
  toStartaleSmartAccount,
  type StartaleSmartAccount,
  type StartaleAccountClient,
} from "@startale-scs/aa-sdk"

type StartaleContextValue = {
  account?: StartaleSmartAccount
  sponsoredClient?: StartaleAccountClient
  tokenClient?: StartaleAccountClient
  isReady: boolean
  error?: string
}

const StartaleContext = createContext<StartaleContextValue>({ isReady: false })

export function StartaleProvider({ signer, children }: { signer: unknown; children: ReactNode }) {
  const [value, setValue] = useState<StartaleContextValue>({ isReady: false })

  useEffect(() => {
    if (!signer) return

    let cancelled = false
    ;(async () => {
      try {
        const publicClient = createPublicClient({ chain: soneiumMinato, transport: http() })

        const account = await toStartaleSmartAccount({
          signer: signer as never,
          chain: soneiumMinato,
          transport: http(),
          index: 0n,
        })

        const paymasterClient = createSCSPaymasterClient({
          transport: http(process.env.NEXT_PUBLIC_PAYMASTER_URL!),
        })

        const sponsoredClient = createSmartAccountClient({
          account,
          transport: http(process.env.NEXT_PUBLIC_BUNDLER_URL!),
          client: publicClient,
          paymaster: paymasterClient,
          paymasterContext: {
            paymasterId: process.env.NEXT_PUBLIC_PAYMASTER_ID!,
          },
        })

        const tokenClient = createSmartAccountClient({
          account,
          transport: http(process.env.NEXT_PUBLIC_BUNDLER_URL!),
          client: publicClient,
          paymaster: paymasterClient,
          paymasterContext: {
            token: process.env.NEXT_PUBLIC_GAS_TOKEN_ADDRESS as `0x${string}`,
          },
        })

        if (!cancelled) setValue({ account, sponsoredClient, tokenClient, isReady: true })
      } catch (err) {
        if (!cancelled) setValue({ isReady: false, error: (err as Error).message })
      }
    })()

    return () => {
      cancelled = true
    }
  }, [signer])

  return <StartaleContext.Provider value={value}>{children}</StartaleContext.Provider>
}

export const useStartale = () => useContext(StartaleContext)
```

| Hook / type             | Source                 | Role                                                              |
| ----------------------- | ---------------------- | ----------------------------------------------------------------- |
| `StartaleSmartAccount`  | `@startale-scs/aa-sdk` | Type alias for the account returned by `toStartaleSmartAccount`.  |
| `StartaleAccountClient` | `@startale-scs/aa-sdk` | Type alias for the client returned by `createSmartAccountClient`. |

<Info>
  Environment variables in this snippet use a framework-agnostic placeholder. The SDK does not require any specific prefix; pick whichever your framework expects (`process.env.X`, `import.meta.env.X`, runtime config, etc.).
</Info>

## Useful account methods

Once you have the account, you can call these without building a UserOperation first:

```ts theme={null}
account.address                              // counterfactual address
await account.getAddress()                   // resolved onchain address (deploys if needed)
await account.getNonce({ key: 0n })          // ERC-7579 two-dimensional nonce
await account.isDelegated()                  // EIP-7702 delegation check
await account.unDelegate()                   // EIP-7702 reset
```

## Next steps

<CardGroup cols={2}>
  <Card title="Contract interactions" icon="layer-group" href="/aa-sdk/tutorials/contract-interactions">
    Send single and batched calls through `sendUserOperation`.
  </Card>

  <Card title="Sponsored paymaster" icon="gas-pump" href="/aa-sdk/tutorials/sponsored-tx">
    Send sponsored UserOperations end to end with policies.
  </Card>

  <Card title="ERC-20 paymaster" icon="coins" href="/aa-sdk/tutorials/erc20-payment">
    Charge users in ASTR, USDC, or other tokens.
  </Card>

  <Card title="Smart sessions" icon="key-skeleton" href="/aa-sdk/tutorials/smart-sessions">
    Reduce signature friction with scoped session keys.
  </Card>
</CardGroup>
