Cover photo

Introduction to Circle Web3 Services & Programmable Wallets

➟ Circle is a leading financial technology company that provides internet-native payments and financial infrastructure. Their web3 services include programmable wallets and USDC stable coin integration, allowing developers to build apps and services on public blockchains like Ethereum.

Programmable wallets are multi-signature smart contract-based wallets that enable advanced functionality like automated execution of transactions based on predefined rules or external data triggers. This overcomes the limitations of traditional blockchain wallets that require manual interventions for every transaction.

post image

• What are the Benefits of Circle's Programmable Wallets?

          ✫ Enhanced security through multi-signature requirements.

          ✫ Support for complex transaction rules and automation.

          ✫ Integration with USDC stable coin for value transfers.

          ✫ Ability to interact with external data sources and smart contracts.

          ✫ Greater control and oversight over funds movements.

• How do USDC and Programmable Wallets Help Scale Real-World Solutions?

➟ Circle's USDC is a fully reserve-backed stablecoin pegged to the US dollar, enabling fast and affordable value transfer on public blockchains. When combined with programmable wallets, it unlocks new capabilities:

          ✫ Automated merchant payouts and employee payroll in stablecoin.

          ✫ Programmatic execution of financial contracts and derivatives.

          ✫ Real-time micro-payments and pay-per-use business models.

          ✫ Decentralized finance (DeFi) apps for lending, borrowing, trading.

• The only Step-by-Step Guide you need to Get Started with Programmable Wallets:

     ➟ To get started, you'll first need to install the 'circle-sdk' library by running:

                                             ``` npm install circle-sdk ```

          Once installed, you can integrate programmable wallets and USDC to build           innovative web3 applications with automated execution of financial transactions           and transfers.

Here's a sequence showing how to create a user, wallet and initiate transfers using Circle's APIs:

  1. Creating a New User:

    import Circle from 'circle-sdk'
    
    const client = new Circle({ 
      host: 'https://api-sandbox.circle.com', // Or production host
      spin: process.env.SPIN_AUTH_TOKEN // SPIN Auth Token
    })
    
    const createUserResponse = await client.createUser({
      firstName: 'Cristiano',
      lastName: 'Ronaldo'
    })
    
    const userId = createUserResponse.data.id
    

    Explanation of the above code:

    import Circle from 'circle-sdk'
    

    Importing the Circle SDK library, which provides the functionality to interact with Circle's APIs.

    const client = new Circle({ host: 'https://api-sandbox.circle.com', // Or production host spin: process.env.SPIN_AUTH_TOKEN // SPIN Auth Token })  
    

    Here, we create a new instance of the Circle client by passing in an object with two properties:

    • host: This is the URL of the Circle API endpoint you want to connect to. In this case, it's the sandbox environment, but you can use the production host for a live environment.

    • spin: This is the SPIN Auth Token, which is required for authentication. It's being read from an environment variable process.env.SPIN_AUTH_TOKEN.

      const createUserResponse = await client.createUser({
        firstName: 'Cristiano',
        lastName: 'Ronaldo'
      })
      

      This line calls the createUser method on the Circle client instance. It's an asynchronous operation, so we use the await keyword to wait for the response.

      The createUser method takes an object with two properties:

      • firstName: The first name of the user you want to create.

      • lastName: The last name of the user you want to create.

    The response from the createUser method is stored in the createUserResponse constant.

    const userId = createUserResponse.data.id
    

    This line extracts the id of the newly created user from the createUserResponse object. The id is typically used in subsequent API calls to identify the user.

  2. Acquire Session Token:

    const getSessionResponse = await client.getNewUserSession({   userId: userId  })  
    const sessionToken = getSessionResponse.data.sessionToken
    


    Explanation of the above code:

    1. const getSessionResponse declares a new variable to store the response from the getNewUserSession method.

    2. await is used because getNewUserSession is an asynchronous operation, so we need to wait for it to complete before proceeding.

    3. client.getNewUserSession is a method provided by the Circle SDK that creates a new session for the user with the specified userId.

    4. { userId: userId } is an object passed as an argument to the getNewUserSession method, where userId is the value of the userId variable (which was obtained from the step of Creating a new user[Step-1]).

    5. const sessionToken declares a new variable to store the session token extracted from the response.

    6. getSessionResponse.data.sessionToken accesses the sessionToken property within the data object of the getSessionResponse. This is where the actual session token value is expected to be present in the response.

  3. Initialize the User:

    const initializeUserResponse = await client.initializeUser({
      userId: userId,
      sessionToken: sessionToken
    })
    
    const walletId = initializeUserResponse.data.wallet.id
    

    Explanation of the code:

    • const initializeUserResponse declares a new variable to store the response from the initializeUser method.

    • await is used because initializeUser is an asynchronous operation, so we need to wait for it to complete before proceeding.

    • client.initializeUser is a method provided by the Circle SDK that initializes the user's account and creates a wallet for them.

    • { userId: userId, sessionToken: sessionToken } is an object passed as an argument to the initializeUser method, where:

      • userId is the value of the userId variable (which was obtained from the step of Creating a new user[Step-1]).

      • sessionToken is the value of the sessionToken variable (obtained from the previous step of Acquiring a session token[Step-2]).

    • const walletId declares a new variable to store the wallet ID extracted from the response.

    • initializeUserResponse.data.wallet.id accesses the id property within the wallet object, which is nested inside the data object of the initializeUserResponse. This is where the ID of the newly created wallet is expected to be present in the response.

  4. Initiating a Transfer:

    const initiateTransferResponse = await client.initiateWalletTransfer({
      walletId: walletId, 
      destination: {
        value: '0x...', // Destination wallet address
        currency: 'USDC'  
      },
      amount: {
        value: '10',
        currency: 'USDC'
      }
    })
    

    Explanation of the above code:

    • const initiateTransferResponse declares a new variable to store the response from the initiateWalletTransfer method.

    • client.initiateWalletTransfer is a method provided by the Circle SDK that initiates a transfer of funds from the user's wallet to another wallet.

    • walletId: walletId is a key-value pair in the object, where the key is walletId, and the value is the walletId variable (Obtained from the initializing the user's wallet[Step-3]).

    • destination is a key in the object, and its value is another object with two key-value pairs:

      • value: '0x...' represents the destination wallet address where the funds will be transferred. In this example, it's a placeholder value ('0x...'), but it should be replaced with an actual wallet address.

      • currency: 'USDC' specifies the currency of the transfer, which is USDC (USD Coin) in this case.

    • amount is a key in the object, and its value is another object with two key-value pairs:

      • value: '10' represents the amount to be transferred. In this example, it's '10', which means a transaction of 10 USDC is being performed.

      • currency: 'USDC' specifies the currency of the transfer amount, which is USDC (USD Coin) in this case.

  5. Viewing your Wallet Balance:

    const walletBalanceResponse = await client.getWalletBalance({
      walletId: walletId
    })
    
    console.log(walletBalanceResponse.data.balance.amount)
    

    Explanation of the above code:

    • const walletBalanceResponse declares a new variable to store the response from the getWalletBalance method.

    • client.getWalletBalance is a method provided by the Circle SDK that retrieves the current balance of the specified wallet.

    • { walletId: walletId } is an object passed as an argument to the getWalletBalance method, where walletId is the value of the walletId variable (presumably obtained from the previous step of initializing the user's wallet).

    • console.log is a function in JavaScript that prints the specified value to the console (for debugging or logging purposes).

    • walletBalanceResponse.data.balance.amount accesses the amount property within the balance object, which is nested inside the data object of the walletBalanceResponse. This is where the actual balance amount is expected to be present in the response.

      ❄ This is how the Transactions take place within Circle:

Flowchart of the process of transaction performed by Circle
Flowchart of the process of transaction performed by Circle

• Conclusion:

     ➟ With the help of this write-up, developers should have a clear understanding of           how to get started with Circle's programmable wallets and leverage their           capabilities along with to build web3 applications.