> ## 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.

# Portal setup guide

> Provision API keys, paymasters, and gas policies in the SCS Portal.

The [SCS Portal](https://portal.scs.startale.com) is where you mint the credentials the AA SDK needs at runtime: a bundler URL, a paymaster URL, and one or more `paymasterId`s. This page walks through each step end to end.

<Frame>
  <img src="https://mintcdn.com/startalegroup/JA93ZUTN8GTWYV3B/images/portal-login.png?fit=max&auto=format&n=JA93ZUTN8GTWYV3B&q=85&s=cb42b9a3dff36f7b18b25c63187d9cd1" alt="Startale Cloud Services sign-in page" width="2880" height="1800" data-path="images/portal-login.png" />
</Frame>

<Note>
  Account abstraction features require the **Growth plan** or higher. You can sign up for a free plan first and upgrade later from the Billing tab.
</Note>

## What you will leave with

By the end of this guide you should have:

* A bundler RPC URL for Soneium Minato or Mainnet.
* A paymaster RPC URL.
* A `paymasterId` for **each** paymaster you create (managed or self-funded).
* One or more gas policies attached to that paymaster.

You will plug all four values into [`createSmartAccountClient`](/aa-sdk/getting-started/quick-start) and [`createSCSPaymasterClient`](/aa-sdk/getting-started/quick-start).

## 1. Issue an API key

<Steps>
  <Step title="Open the API Keys tab">
    Sign in to the SCS Portal and open the **API Keys** section in the left navigation.
  </Step>

  <Step title="Create a key per environment">
    Create separate keys for development and production so you can rotate or revoke them independently.
  </Step>

  <Step title="Copy the bundler and paymaster URLs">
    Each key exposes both a `bundlerUrl` and a `paymasterUrl`. They look like this:

    ```bash theme={null}
    https://soneium-minato.bundler.scs.startale.com?apikey=YOUR_API_KEY
    https://paymaster.scs.startale.com/v1?apikey=YOUR_API_KEY
    ```
  </Step>
</Steps>

## 2. Create a paymaster

The Portal supports two paymaster modes. **Both modes return a `paymasterId`** that you pass through `paymasterContext` at runtime; the difference is purely how the paymaster is funded.

<Tabs>
  <Tab title="Self-funded (prepaid)">
    You top up an ETH balance on the paymaster contract from a sponsor account you control. Gas is debited from that balance until it is empty, at which point the paymaster will reject UserOperations.

    **When to choose this mode**

    * You want a hard, predictable cap on how much gas you can spend.
    * You prefer to settle in crypto rather than fiat.
    * You operate the paymaster from a treasury wallet you already manage.

    **Configuration**

    1. Choose a sponsor account address on the target network.
    2. Send ETH to the paymaster contract address shown in the Portal.
    3. The Portal issues a `paymasterId` for the paymaster you just funded.
  </Tab>

  <Tab title="Managed (postpaid)">
    SCS fronts gas for your UserOperations and bills you in fiat on a monthly cycle. There is no sponsor wallet to top up.

    **When to choose this mode**

    * You prefer accounting in fiat over treasury management.
    * You want SCS to absorb short-term spikes in gas price.
    * You are launching to production and need predictable invoicing.

    **Configuration**

    1. Confirm your billing details in the Portal.
    2. The Portal issues a `paymasterId` for the managed paymaster.
  </Tab>
</Tabs>

<Warning>
  **Both managed and self-funded paymasters return a `paymasterId`.** The id is what you pass through `paymasterContext.paymasterId` in the SDK. The paymaster mode only affects funding and billing; the call site looks identical.
</Warning>

```ts theme={null}
paymasterContext: {
  paymasterId: "<YOUR_PAYMASTER_ID>", // works for both managed and self-funded
}
```

## 3. Configure gas policies

Gas policies are the rules that the paymaster applies before agreeing to sponsor a UserOperation. A paymaster with no policies will sponsor everything until it runs out of funds; in production you almost always want at least one policy.

| Policy scope | What it limits                                                 | Typical use                            |
| ------------ | -------------------------------------------------------------- | -------------------------------------- |
| **Global**   | Every UserOperation that hits the paymaster.                   | A safety net you set once.             |
| **User**     | UserOperations from a specific sender address.                 | Per-user free-tier limits, allowlists. |
| **Contract** | UserOperations targeting a specific contract. *(Coming soon.)* | Restrict sponsorship to your own dapp. |

Each policy has a **rate limit type**:

| Rate limit type     | Counts                                           | Example                                            |
| ------------------- | ------------------------------------------------ | -------------------------------------------------- |
| **Amount**          | Total gas (in native units) used in the window.  | Sponsor up to `0.1 ETH` of gas every 7 days.       |
| **User operations** | Number of UserOperations executed in the window. | Sponsor up to `100 UserOps` per user every 7 days. |

<Info>
  Policy windows currently reset every **7 days**. The reset cadence is fixed at the platform level; you choose the rate limit value, not the window length.
</Info>

## 4. Plug the values into the SDK

Put the four values you collected into your environment file:

```bash .env theme={null}
BUNDLER_URL="https://soneium-minato.bundler.scs.startale.com?apikey=YOUR_API_KEY"
PAYMASTER_URL="https://paymaster.scs.startale.com/v1?apikey=YOUR_API_KEY"
PAYMASTER_ID="pm_..."
```

Then build the clients:

```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!,
  },
})
```

## Next steps

<CardGroup cols={2}>
  <Card title="Installation and setup" icon="wrench" href="/aa-sdk/tutorials/installation">
    Install the SDK and pick a signer for your stack.
  </Card>

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

  <Card title="ERC-20 paymaster" icon="coins" href="/aa-sdk/tutorials/erc20-payment">
    Charge users in tokens instead of native gas.
  </Card>

  <Card title="Quickstart" icon="rocket" href="/aa-sdk/getting-started/quick-start">
    Verify the credentials with a one-file Node.js script.
  </Card>
</CardGroup>
