# Deep Dive Into Circle Programmable Wallets

By [Untitled](https://paragraph.com/@0xd7b5dbe3d6efb312ab1016980b2ffdc47b6f8363) · 2024-04-19

---

**Introduction Circle Programmable Wallets**
============================================

![www.circle.com](https://storage.googleapis.com/papyrus_images/6789afef17caf85d5d065b7d1580910e813e11647fa733e33ed0a66356fbc77f.png)

www.circle.com

This article introduces Circle’s Programmable Wallets, a tool for developers to integrate digital currencies like USDC into their applications.

Here's a breakdown of the key points:

*   **USDC** is a digital dollar stablecoin accessible on public blockchains.
    
*   **Circle's Web3 Services** offer tools to simplify blockchain development, including Programmable Wallets.
    
*   **Programmable Wallets** are a type of Wallet as a Service (WaaS) that simplifies creating and managing Web3 wallets.
    
    Benefits of Programmable Wallets include:
    
    *   User-friendly experience for interacting with USDC.
        
    *   PIN-based authentication instead of complex seed phrases.
        
    *   Enhanced security with Multi-Party Computation (MPC).
        
    
    There are two types of Programmable Wallets:
    
    *   **User-controlled wallets:** Users have full control over their private keys.
        
    *   **Developer-controlled wallets:** Developers manage transactions on behalf of users.
        

**Create New User**
===================

Here's a breakdown of the steps, rephrased to be more general about creating a Circle Web3 Services account:

1.  **Visit the Website:** Click the link mentioned in the article (which presumably leads to the Circle Web3 Services signup page).
    
2.  **Choose Account Type:** Select the option that aligns with your purpose, likely "Build Web3 enabled apps" in this case.
    
3.  **Fill in Account Details:** On the signup form, enter your required information.
    
4.  **Create Account:** Click the button labeled "Create Account" or similar.
    
5.  **Follow Prompts:** The platform might have additional steps for configuring your new account.
    

**Acquire Session Token**
=========================

How to generate a session token and authenticate subsequent requests with session token

**Steps:**

![](https://storage.googleapis.com/papyrus_images/e5e20b6f51d35e7b974443662a45ce6d2c6eb25675e41a66146fe61bea68b08f.png)

1.  **Find the Token Creation Section:** Navigate to the **Users and Pins** tab in your Circle Web3 Services account. Look for a section labeled **Create a user token**, Next, navigate to the "Request Body" section and then copy and paste the provided code snippet into it.
    
        {
          "userId": "REPLACE WITH YOUR USERID value"
        }
        
    
2.  **Send the Request and Get Your Login Token:** Once you've replaced `"userId"` with your ID, click a button like "Send" or "Submit." If successful, the system will respond with a message containing two important values:
    
    *   **userToken:** This is your temporary login token, like a secret key that identifies you for a limited duration.
        
    *   **encryptionKey** (might be called differently): This is an additional security measure used alongside the token.
        

![](https://storage.googleapis.com/papyrus_images/bca8e7b6401f439a85685a245397782b627fe485d963ba44dc9a0f2fd8cca12c.png)

Next, begin to transfer the **userToken** and **encryptionKey** values over to the Android application. With both **userToken** and **encryptionKey** values set, we’re all set to create a SCA wallet!

**Using Your Login Token to Create a Secure Wallet**

Now that you have the login token, you can use it to create a special wallet within your account:

1.  **Find the Wallet Creation Section:** Still in the **Users and Pins** tab, locate the section called something like **Create a PIN challenge and create wallet(s)**.
    
2.  **Attach Your Login Token:** Click on the **Headers** option and paste your **userToken** value in a field labeled something like **X-User-Token**. This tells the system you're authorized to make this request.
    
3.  **Specify Your Wallet Preferences:** head over to the request body option and begin to populate the request body with the following code snippet:
    
        {
          "blockchains": [
            "ETH-SEPOLIA"
          ],
          "accountType": "SCA",
          "idempotencyKey": "{{$guid}}"
        }
        
    
4.  **Send the Request and Get a Challenge:** Click "Send" again. This time, the system will respond with a **challenge ID**.
    
5.  **Transfer the Challenge ID to Your App:** Similar to the login token, you might need to transfer this challenge ID to your Android application.
    
6.  **Complete Wallet Setup:** The instructions mention setting a PIN code and recovery questions. Proceed to enter your PIN to confirm the transaction. Upon entering your PIN, you should be redirected to the application home page representing a successful wallet creation.
    

**Note:** To verify that your user-controlled wallet has been created successfully, head over to your [**Developer Console**](https://console.circle.com/wallets/user/users) and navigate to your user details where you should now observe 2 User-controlled wallets as shown below!

![](https://storage.googleapis.com/papyrus_images/eca5a4d59bf935716017734fba285526d9abdf1aa63265793662d2c20f31ed61.png)

**Initialize The User**
=======================

This guide outlines initializing and creating a user-controlled smart contract account (SCA) wallet by setting their PIN code and security questions.

**Prerequisites**

1.  Create a [developer account and acquire an API key in the console](https://developers.circle.com/w3s/docs/circle-developer-account).
    
2.  Install the [Web3 Services SDKs](https://developers.circle.com/w3s/docs/web3-services-sdks), which is currently only available for Node.js. (_optional_)
    
3.  Set up one of the web, iOS, or Android [sample applications](https://developers.circle.com/w3s/docs/sample-applications) locally.
    

**1.Configure and Run the Sample App**

Once you have one of the web, iOS, or Android [sample applications](https://developers.circle.com/w3s/docs/sample-applications) set up locally, you will then:

1.  Run the sample app and simulator.
    
2.  Obtain your App ID. This can be done by one of two options
    
    1.  Access the developer console and navigate to the [configurator](https://console.circle.com/wallets/user/configurator) within user-controlled wallets. From there, copy the App ID.
        
    2.  Make an API request to `GET /config/entity` and copy the App ID from the response body.
        
3.  Add the App ID to the sample app.
    

![](https://storage.googleapis.com/papyrus_images/82c11541b01e5f79651287b52ef9ec907bd040d8e782475a53c0414233b6bb73.png)

**2\. Create a User**

Make a request to `POST /users` to create a `userId`. This represents the user’s account and all associated wallets, assets, and transactions. The `userId` is recommended to be in the UUID format.

**_Node.js_**

    // Import and configure the user-controlled wallet SDK 
    const { initiateUserControlledWalletsClient } = require('@circle-fin/user-controlled-wallets'); 
    const circleUserSdk = initiateUserControlledWalletsClient({ apiKey: '<API_KEY>' }); const response = await circleUserSdk.createUser({ userId: '2f1dcb5e-312a-4b15-8240-abeffc0e3463' });
    const response = await circleUserSdk.createUser({ userId: '2f1dcb5e-312a-4b15-8240-abeffc0e3463' });
    

> **_cURL_**

    curl --request POST \ 
    --url 'https://api.circle.com/v1/w3s/users' \ 
    --header 'accept: application/json' \ 
    --header 'content-type: application/json' \ --header 'authorization: Bearer <API_KEY>' \ --data ' { "userId": "2f1dcb5e-312a-4b15-8240-abeffc0e3463" 
    } '
    

If the request is successful, you will receive an empty response body.

![](https://storage.googleapis.com/papyrus_images/234f827bd099bf54cf07ab6c4a6c39502ed86e6116cc2940b5feed2f825dc61d.png)

**Note:** We recommend that you maintain a mapping to associate the end-user profile usernames with the `userId` provided to our service/end-point. You can use a local database to maintain this mapping.

**3\. Acquire a Session Token**

Next, you will need to acquire a session token. That we already mentioned this before, quick recap to do this, you will make a request to the `POST /users/token` using the previously created `userId` in Step 2. The `userToken` is a 60-minute session token, which is used to initiate requests that require a user challenge (PIN code entry). After 60 minutes, the session expires, and a new `userToken` must be generated via the same endpoint.

**4\. Initialize the User's Account and Acquire the Challenge ID**

Make a request to `POST /user/initialize` using the `userToken` returned from Step 3. This call returns a Challenge ID, which is used with the Circle Programmable Wallet SDK to have the user set their PIN code and security questions.

Make sure to provide a Testnet blockchain such as `ETH-SEPOLIA`, `MATIC-AMOY`, and `AVAX-FUJI`.

**_Node.js_**

    const response = await circleUserSdk.createUserPinWithWallets({ 
    userToken: '<USER_TOKEN>', accountType: 'SCA', blockchains: ['MATIC-AMOY'] });
    

or

**cURL**

    curl --request POST \ 
    --url 'https://api.circle.com/v1/w3s/user/initialize' \ 
    --header 'accept: application/json' \ 
    --header 'content-type: application/json' \ 
    --header 'authorization: Bearer <API_KEY>' \ 
    --header 'X-User-Token: <USER_TOKEN>' \ 
    --data ' { "idempotencyKey": "49e3f455-60a2-4b5e-9e9e-9400b86e5f34", "accountType": "SCA", "blockchains": [ "MATIC-MUMBAI" ] } '
    "idempotencyKey": "49e3f455-60a2-4b5e-9e9e-9400b86e5f34", "accountType": "SCA", "blockchains": [ "MATIC-MUMBAI" ] } '
    

![](https://storage.googleapis.com/papyrus_images/2daa5ce4f82b081cfd5aa4d04346daffdda7671641de1a36b0c8266a83093629.png)

**5\. Create a Wallet in the Sample App**

At this point, you should be ready to execute your first request through the sample app. Once you’ve entered the required fields indicated in Step 4, click **Execute** to continue.

The sample application takes you through the end user initialization process, which includes setting up the user’s PIN code and security questions and having the user confirm their configuration.

![](https://storage.googleapis.com/papyrus_images/ec34b0b855c459c72a8724f20c522a8c6d8373936760cd0eb57b8f66451e62fe.png)

**6\. Check User Status**

Once you have completed all the steps in the sample app, you can then check the user status by making a request to `GET /user` providing the `userToken` to retrieve the status of the user’s account.

To understand the current state of the user, inspect the following values:

1.  **PIN Status**: This parameter indicates whether the end-user has successfully set a 6-digit PIN. If the user has set the PIN successfully, the `pinStatus` value will be `enabled`.
    
2.  **Security Question Status**: This parameter provides information about the user's recovery method status, specifically related to the defined security questions. If the end-user has successfully established a recovery method by defining their security questions, the `securityQuestionStatus` will be set to `enabled`.
    

**_Node.js_**

    const response = await circleUserSdk.getUserStatus({ userToken: '<USER_TOKEN>' });
    

or

**_cURL_**

    curl --request GET \ 
    --url 'https://api.circle.com/v1/w3s/user' \
    --header 'accept: application/json' \ --header 'content-type: application/json' \ 
    --header 'authorization: Bearer <API_KEY>' \ 
    --header 'X-User-Token: <USER_TOKEN>'
    

![](https://storage.googleapis.com/papyrus_images/48187c487090668a328fceb9b03c46f6835ff1b4e1c20c63b731e463cd042ab3.png)

**Initiate a Transfer**
=======================

Steps to initiate a wallet to wallet transfer

**Send an Outbound Transfer**

**1\. Run Sample App**

Once you have one of the web, iOS, or Android [sample applications](https://developers.circle.com/w3s/docs/sample-applications) set up locally, you will then:

1.  Run the sample app and simulator.
    
2.  Obtain your App ID. This can be done by one of two options
    
    1.  Access the developer console and navigate to the [configurator](https://console.circle.com/wallets/user/configurator) within user-controlled wallets. From there, copy the App ID.
        
    2.  Make an API request to `GET /config/entity` and copy the App ID from the response body.
        
3.  Add the App ID to the sample app.
    
4.  You will start by making a request to `POST /users/token` using a previously created [userId](https://developers.circle.com/w3s/docs/user-controlled-initialization-and-wallet-creation-quickstart). The `userToken` is a 60-minute session token to initiate requests requiring a user challenge (PIN code entry). After 60 minutes, the session expires, and a new `userToken` must be generated via the same endpoint.
    
    From this response, you will acquire the `encryptionKey` and `userToken` which you should provide in the respective sample app fields. Additionally, you will use the `userToken` in Step 3.
    
    **Node.js**
    
        // Import and configure the user-controlled wallet SDK const { initiateUserControlledWalletsClient } = require('@circle-fin/user-controlled-wallets'); 
        const circleUserSdk = initiateUserControlledWalletsClient({ apiKey: '<API_KEY>' }); 
        const response = await circleUserSdk.createUserToken({ userId: '2f1dcb5e-312a-4b15-8240-abeffc0e3463' });
        
    
    or
    
    **_cURL_**
    
        curl --request POST \ 
        --url 'https://api.circle.com/v1/w3s/users/token' \
        --header 'accept: application/json' \ 
        --header 'content-type: application/json' \
        --header 'authorization: Bearer <API_KEY>' \ --data ' { "userId": "2f1dcb5e-312a-4b15-8240-abeffc0e3463" } '
        
    

![](https://storage.googleapis.com/papyrus_images/4d030cf0e39e6c80362c7ed7dfae26aa5aeca9a869b3187ca5c8a8eb5f813380.png)

From this response, you will acquire the `encryptionKey` and `userToken` which you should provide in the respective sample app fields. Additionally, you will use the `userToken` in Step 3.

**Receive an Inbound Transfer**

**1\. Acquire a Session Token**

Make a request to `POST /users/token` using a previously created [userId](https://developers.circle.com/w3s/docs/user-controlled-initialization-and-wallet-creation-quickstart). The `userToken` is a 60-minute session token to initiate requests requiring a user challenge (PIN code entry). After 60 minutes, the session expires, and a new `userToken` must be generated via the same endpoint.

**_Node.js_**

    // Import and configure the user-controlled wallet SDK const { initiateUserControlledWalletsClient } = require('@circle-fin/user-controlled-wallets'); 
    const circleUserSdk = initiateUserControlledWalletsClient({ apiKey: '<API_KEY>' }); const response = await circleUserSdk.createUserToken({ userId: '2f1dcb5e-312a-4b15-8240-abeffc0e3463' });
    

or

**_cURL_**

    curl --request POST \ 
    --url 'https://api.circle.com/v1/w3s/users/token' \ 
    --header 'accept: application/json' \ 
    --header 'content-type: application/json' \ 
    --header 'authorization: Bearer <API_KEY>' \ 
    --data ' { "userId": "2f1dcb5e-312a-4b15-8240-abeffc0e3463" } '
    

![](https://storage.googleapis.com/papyrus_images/79ff9a8ab4ba6b36d9a22fd3400c99c696197a50f90e8a63d3a5a261cade0a4f.png)

**2\. Acquire the Wallet ID**

Make a request to `GET /wallets` using the `userToken` returned in Step 1 to retrieve the wallet information for a given user.

**_Node.js_**

    const response = await circleUserSdk.listWallets({ userToken: '<USER_TOKEN>' });
    

or

**_cURL_**

    curl --request GET \ 
    --url 'https://api.circle.com/v1/w3s/wallets' \ 
    --header 'accept: application/json' \ 
    --header 'content-type: application/json' \
    --header 'authorization: Bearer <API_KEY>' \ 
    --header 'X-User-Token: <USER_TOKEN>'
    

![](https://storage.googleapis.com/papyrus_images/89005ff099fe56a6034f9c6ecd43e9ef7f549e55c7bc07879f24e0ab8b8e8de9.png)

**View Wallet Balance**
=======================

Steps to view the latest wallet balance after the transfer

Head over to your [**Developer Console**](https://console.circle.com/wallets/user/users) account where you should observe the following as shown below where your user’s PIN and Security Question State has been enabled!

Next, click on your user ID to navigate to the user details page where you should observe that you have successfully created a SCA User-Controlled Wallet on the Ethereum Sepolia Testnet as shown below!

![](https://storage.googleapis.com/papyrus_images/27edf4ca4628903e647ebb28d971b4c40327716ffc14a1f839156175805db987.png)

Proceed to click your wallet ID

![](https://storage.googleapis.com/papyrus_images/41b931bfe26548a848e8e39754bad4e7ca3d84c045e7783ab51353028a17ada9.png)

Then you will see your current wallet balance after transfer as shown below!

![](https://storage.googleapis.com/papyrus_images/60c4106b4de5af0c53bf9fb6fcfb60cfc9de56adcd34274a5c0c9edd9e50ab46.png)

**Summarizing the benefits:**

*   Circle Programmable Wallets offer a user-friendly and secure way for developers to integrate USDC into their Web3 applications.
    
*   With PIN-based authentication and MPC security, Programmable Wallets simplify the creation and management of user-controlled and developer-controlled wallets.
    

**Encouraging action:**

*   Get started with Circle Programmable Wallets today and unlock the potential of USDC in your Web3 apps!
    
*   Visit the Circle Web3 Services website to learn more about Programmable Wallets and explore the developer tools available.
    

**Looking to the future:**

*   Circle Programmable Wallets are a powerful tool that will continue to evolve alongside the Web3 ecosystem.
    
*   Stay tuned for further updates and innovations from Circle as they work to make USDC even more accessible for developers and users.
    

**A contribution by adii0409, a member of the StackUp Community**

---

*Originally published on [Untitled](https://paragraph.com/@0xd7b5dbe3d6efb312ab1016980b2ffdc47b6f8363/deep-dive-into-circle-programmable-wallets)*
