# Quickstart

> Get started with Wallet APIs infrastructure

> For the complete documentation index, see [llms.txt](/docs/llms.txt).

In this guide, you'll wire up viem's bundler client to Alchemy's bundler with a Modular Account V2 from `@alchemy/smart-accounts` and send a user operation. This is the advanced path; if you don't need this level of control, use [`@alchemy/wallet-apis`](/docs/wallets/quickstart) instead.

## Prerequisites

* API key from your [dashboard](https://dashboard.alchemy.com/apps)
* TypeScript 5+ and the packages below

**Installation**

<CodeBlocks>
  ```bash yarn
  yarn add @alchemy/common @alchemy/aa-infra @alchemy/smart-accounts viem
  ```

  ```bash npm
  npm i @alchemy/common @alchemy/aa-infra @alchemy/smart-accounts viem
  ```
</CodeBlocks>

## Create a Gas Manager policy

If you want to sponsor gas, create a policy in the Gas Manager dashboard.

A gas manager policy is a set of rules that define which transactions are eligible for gas sponsorship. Control which transactions are eligible for sponsorship by defining rules:

* **Spending rules**: limit the amount of money or the number of transactions that this policy can sponsor
* **Allowlist**: restrict wallet addresses that are eligible for sponsorship. The policy only sponsors gas for transactions sent by addresses on this list.
* **Blocklist**: ban certain addresses from receiving sponsorship under this policy
* **Policy duration**: define the duration of your policy and the sponsorship expiry period. This is the period for which the gas sponsorship data remains valid once generated.

To learn more about policy configuration, refer to the guide on [setting up a gas manager policy](https://alchemy.com/docs/setup-a-gas-manager-policy/?a=ak-docs).

Once you have decided on policy rules for your app, [create a policy](https://dashboard.alchemy.com/gas-manager/policy/create/?a=ak-docs) in the Gas Manager dashboard.

You should now have a gas policy created with a policy ID you can use to sponsor gas.

![Policy ID](https://alchemyapi-res.cloudinary.com/image/upload/v1764187315/docs/aa-sdk/images/policy-id.png)


## Create a client

<Warning>
  Replace `YOUR_API_KEY` and `POLICY_ID` with the values from the steps above.
</Warning>

<CodeBlocks>
  ```ts title="config.ts"
  import { sepolia } from "viem/chains";

  export const chain = sepolia;
  export const ALCHEMY_API_KEY = "<YOUR_API_KEY>";
  export const policyId = "<POLICY_ID>";
  ```

  ```ts title="client.ts"
  import { createBundlerClient, createPaymasterClient } from "viem/account-abstraction";
  import { createClient } from "viem";
  import { privateKeyToAccount, generatePrivateKey } from "viem/accounts";
  import { alchemyTransport } from "@alchemy/common";
  import { toModularAccountV2 } from "@alchemy/smart-accounts";
  import { estimateFeesPerGas } from "@alchemy/aa-infra";
  import { chain, ALCHEMY_API_KEY, policyId } from "./config";

  const transport = alchemyTransport({ apiKey: ALCHEMY_API_KEY });

  const rpcClient = createClient({ chain, transport });

  export async function getClient() {
    const owner = privateKeyToAccount(generatePrivateKey());
    const account = await toModularAccountV2({ client: rpcClient, owner });

    return createBundlerClient({
      account,
      client: rpcClient,
      chain,
      transport,
      // Drop the next two lines if you don't want gas sponsorship.
      paymaster: createPaymasterClient({ transport }),
      paymasterContext: { policyId },
      userOperation: { estimateFeesPerGas },
    });
  }
  ```
</CodeBlocks>


## Send a user operation

<CodeBlocks>
  ```ts example.ts
  import { getClient } from "./client";

  const client = await getClient();

  const hash = await client.sendUserOperation({
    calls: [
      {
        to: "0x0000000000000000000000000000000000000000",
        value: 0n,
        data: "0x",
      },
    ],
  });

  const receipt = await client.waitForUserOperationReceipt({ hash });
  console.log("Mined:", receipt.receipt.transactionHash);
  ```
</CodeBlocks>