Deep Dive Into Circle Programmable Wallets

Introduction Circle Programmable Wallets

www.circle.com
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:

post image
  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.

post image

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 and navigate to your user details where you should now observe 2 User-controlled wallets as shown below!

post image

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.

  2. Install the Web3 Services SDKs, which is currently only available for Node.js. (optional)

  3. Set up one of the web, iOS, or Android sample applications locally.

1.Configure and Run the Sample App

Once you have one of the web, iOS, or Android 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 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.

post image

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.

post image

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-SEPOLIAMATIC-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" ] } '
post image

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.

post image

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>'
post image

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 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 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. 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" } '
    
post image

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. 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" } '
post image

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>'
post image

View Wallet Balance

Steps to view the latest wallet balance after the transfer

Head over to your Developer Console 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!

post image

Proceed to click your wallet ID

post image

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

post image

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