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

# Quickstart: Create a dev-controlled wallet

> Get started with developer-controlled wallets by creating a wallet set and a wallet within it.

A wallet set is a container that groups your developer-controlled wallets under
a single [entity secret](/wallets/dev-controlled/entity-secret-management). All
wallets in a set share the same entity secret, and EVM wallets in the same set
share the [same address](/wallets/unified-wallet-addressing-evm). After
completing this tutorial, you'll have a wallet set and a developer-controlled
wallet. The examples use an
[externally owned account (EOA)](/wallets/account-types#externally-owned-accounts-eoa)
on Arc Testnet, but you can create a
[smart contract account (SCA)](/wallets/account-types#smart-contract-accounts-sca-and-msca)
or use any [supported blockchain](/wallets/supported-blockchains).

## Prerequisites

Before you begin, ensure that you've:

* Obtained an [API key](/api-reference/keys) from the
  [Circle Console](https://console.circle.com/)
* Generated and registered an entity secret using the
  [Circle Console](https://console.circle.com/wallets/dev/configurator/entity-secret)
  or the
  [SDK](/wallets/dev-controlled/register-entity-secret#create-an-entity-secret-using-the-sdk)
* Installed one of the following:
  * [Node.js v22.6 or later](https://nodejs.org/)
  * [Python 3.11 or later](https://www.python.org/)

## Step 1. Set up your project

### 1.1. Install additional dependencies

From the same directory where you set up your entity secret, add a run script
and install the TypeScript development dependencies.

<CodeGroup>
  ```shell Node.js theme={null}
  npm pkg set scripts.create-wallet="node --env-file=.env create-wallet.ts"
  npm install --save-dev typescript @types/node
  ```

  ```shell Python theme={null}
  # The dependencies you installed in the entity secret setup are all you need.
  ```
</CodeGroup>

### 1.2. Configure TypeScript (optional)

<Tip>
  This step is optional. It helps prevent missing types in your IDE or editor.
</Tip>

Create a `tsconfig.json` file:

```shell theme={null}
npx tsc --init
```

Then, update the `tsconfig.json` file:

```shell theme={null}
cat <<'EOF' > tsconfig.json
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "types": ["node"]
  }
}
EOF
```

### 1.3. Verify environment variables

Your `.env` file from the entity secret setup already contains both values you
need. Confirm it includes:

```text .env theme={null}
CIRCLE_API_KEY=YOUR_API_KEY
CIRCLE_ENTITY_SECRET=YOUR_ENTITY_SECRET
```

* `CIRCLE_API_KEY` is your Circle API key.
* `CIRCLE_ENTITY_SECRET` is your registered entity secret.

## Step 2. Create your wallet

Write a script that creates a wallet set and a developer-controlled wallet, then
prints the wallet set ID, wallet ID, and wallet address.

### 2.1. Create the script

In your project directory, create `create-wallet.ts` (Node.js) or
`create_wallet.py` (Python) and add the following code. When run, this code
creates a wallet set first, and then creates a wallet in it:

<CodeGroup>
  ```typescript create-wallet.ts expandable theme={null}
  import { initiateDeveloperControlledWalletsClient } from "@circle-fin/developer-controlled-wallets";

  const client = initiateDeveloperControlledWalletsClient({
    apiKey: process.env.CIRCLE_API_KEY!,
    entitySecret: process.env.CIRCLE_ENTITY_SECRET!,
  });

  async function main() {
    const walletSetResponse = await client.createWalletSet({
      name: "My First Dev-Controlled Wallet Set",
    });

    const walletSet = walletSetResponse.data?.walletSet;
    if (!walletSet?.id) {
      throw new Error("Wallet set creation failed: no ID returned");
    }

    const walletResponse = await client.createWallets({
      walletSetId: walletSet.id,
      blockchains: ["ARC-TESTNET"], // Can be any supported blockchain
      count: 1,
      accountType: "EOA", // Can be EOA or SCA
    });

    console.log("Wallet set response:", walletSetResponse.data);
    console.log("Wallet response:", walletResponse.data);
  }

  main().catch((err) => {
    console.error("Error:", err.message || err);
    process.exit(1);
  });
  ```

  ```python create_wallet.py expandable theme={null}
  from circle.web3 import utils, developer_controlled_wallets
  from dotenv import load_dotenv
  import os
  import json

  load_dotenv()

  client = utils.init_developer_controlled_wallets_client(
      api_key=os.getenv("CIRCLE_API_KEY"),
      entity_secret=os.getenv("CIRCLE_ENTITY_SECRET")
  )

  wallet_sets_api = developer_controlled_wallets.WalletSetsApi(client)
  wallets_api = developer_controlled_wallets.WalletsApi(client)

  try:
      wallet_set = wallet_sets_api.create_wallet_set(
          developer_controlled_wallets.CreateWalletSetRequest.from_dict({
              "name": "My First Dev-Controlled Wallet Set"
          })
      )

      wallet = wallets_api.create_wallet(
          developer_controlled_wallets.CreateWalletRequest.from_dict({
              "walletSetId": wallet_set.data.wallet_set.actual_instance.id,
              "blockchains": ["ARC-TESTNET"],
              "count": 1,
              "accountType": "EOA"
          })
      )

      print(json.dumps(json.loads(wallet_set.model_dump_json()), indent=2))
      print(json.dumps(json.loads(wallet.model_dump_json()), indent=2))
  except developer_controlled_wallets.ApiException as e:
      print("Exception when calling the Circle Wallets API: %s\n" % e)
  ```
</CodeGroup>

<Note>
  If you are calling the API directly instead of using the SDK, you need two
  requests: one to [create the wallet
  set](/api-reference/wallets/developer-controlled-wallets/create-wallet-set)
  and one to [create the
  wallet](/api-reference/wallets/developer-controlled-wallets/create-wallet).
  Replace the entity secret ciphertext and idempotency key in your request. The
  SDKs handle this automatically.
</Note>

### 2.2. Run the script

Run the script from your project directory:

<CodeGroup>
  ```shell Node.js theme={null}
  npm run create-wallet
  ```

  ```shell Python theme={null}
  python create_wallet.py
  ```
</CodeGroup>

The output looks similar to:

<CodeGroup>
  ```text Node.js theme={null}
  Wallet set response: {
    walletSet: {
      id: "9d4f..."
    }
  }
  Wallet response: {
    wallets: [
      {
        id: "1f29...",
        address: "0x1234...",
        blockchain: "ARC-TESTNET"
      }
    ]
  }
  ```

  ```text Python theme={null}
  {
    "data": {
      "wallet_set": {
        "id": "9d4f..."
      }
    }
  }
  {
    "data": {
      "wallets": [
        {
          "id": "1f29...",
          "address": "0x1234...",
          "blockchain": "ARC-TESTNET"
        }
      ]
    }
  }
  ```
</CodeGroup>

Save the wallet ID and address for future wallet operations such as transferring
tokens or checking balances.

## Step 3. Add more wallets to your set (optional)

To add more wallets to the same blockchain or to add wallets on a different
blockchain, call `createWallets` again on the same wallet set. Pass your
existing wallet set ID as `walletSetId`. The `count` parameter is the number of
wallets created per blockchain.

Add the following inside your `main()` function from Step 2:

<CodeGroup>
  ```typescript create-wallet.ts expandable theme={null}
  const arcWalletResponse = await client.createWallets({
    walletSetId: "your-wallet-set-id", // wallet set ID from Step 2
    blockchains: ["ARC-TESTNET"],
    count: 1,
  });

  console.log("Arc wallet:", arcWalletResponse.data);
  ```

  ```python create_wallet.py expandable theme={null}
  arc_wallet = wallets_api.create_wallet(
      developer_controlled_wallets.CreateWalletRequest.from_dict({
          "walletSetId": "your-wallet-set-id",  # wallet set ID from Step 2
          "blockchains": ["ARC-TESTNET"],
          "count": 1,
      })
  )

  print(json.dumps(json.loads(arc_wallet.model_dump_json()), indent=2))
  ```
</CodeGroup>

This creates an EOA wallet by default. To create an SCA wallet instead, add
`accountType: "SCA"` to the request.

To add a wallet on a different blockchain, pass a different value for
`blockchains`—for example, `"SOL-DEVNET"` for Solana Devnet.

You can also pass multiple blockchains in a single call—`createWallets` creates
`count` wallets per blockchain. All wallets created this way belong to the same
wallet set and share the same entity secret.

## Next steps

Now that you have a developer-controlled wallet, you can:

* **Fund the wallet**: Get testnet USDC from the
  [Circle Faucet](https://faucet.circle.com/).
* **[Send tokens across wallets](/wallets/dev-controlled/transfer-tokens-across-wallets)**:
  Transfer USDC from one developer-controlled wallet to another.
* **Build payment workflows with [Arc App Kit](https://docs.arc.io/app-kit)**:
  Use the
  [Circle Wallets adapter](https://docs.arc.io/app-kit/tutorials/adapter-setups#circle-wallets)
  to add token transfers, swaps, bridging, and chain-agnostic unified balances
  to your app without building each integration yourself.
