➟ 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.

• 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:
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.idExplanation 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 variableprocess.env.SPIN_AUTH_TOKEN.const createUserResponse = await client.createUser({ firstName: 'Cristiano', lastName: 'Ronaldo' })This line calls the
createUsermethod on the Circle client instance. It's an asynchronous operation, so we use theawaitkeyword to wait for the response.The
createUsermethod 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
createUsermethod is stored in thecreateUserResponseconstant.const userId = createUserResponse.data.idThis line extracts the
idof the newly created user from thecreateUserResponseobject. Theidis typically used in subsequent API calls to identify the user.Acquire Session Token:
const getSessionResponse = await client.getNewUserSession({ userId: userId }) const sessionToken = getSessionResponse.data.sessionToken
Explanation of the above code:const getSessionResponsedeclares a new variable to store the response from thegetNewUserSessionmethod.awaitis used becausegetNewUserSessionis an asynchronous operation, so we need to wait for it to complete before proceeding.client.getNewUserSessionis a method provided by the Circle SDK that creates a new session for the user with the specifieduserId.{ userId: userId }is an object passed as an argument to thegetNewUserSessionmethod, whereuserIdis the value of theuserIdvariable (which was obtained from the step of Creating a new user[Step-1]).const sessionTokendeclares a new variable to store the session token extracted from the response.getSessionResponse.data.sessionTokenaccesses thesessionTokenproperty within thedataobject of thegetSessionResponse. This is where the actual session token value is expected to be present in the response.
Initialize the User:
const initializeUserResponse = await client.initializeUser({ userId: userId, sessionToken: sessionToken }) const walletId = initializeUserResponse.data.wallet.idExplanation of the code:
const initializeUserResponsedeclares a new variable to store the response from theinitializeUsermethod.awaitis used becauseinitializeUseris an asynchronous operation, so we need to wait for it to complete before proceeding.client.initializeUseris 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 theinitializeUsermethod, where:userIdis the value of theuserIdvariable (which was obtained from the step of Creating a new user[Step-1]).sessionTokenis the value of thesessionTokenvariable (obtained from the previous step of Acquiring a session token[Step-2]).
const walletIddeclares a new variable to store the wallet ID extracted from the response.initializeUserResponse.data.wallet.idaccesses theidproperty within thewalletobject, which is nested inside thedataobject of theinitializeUserResponse. This is where the ID of the newly created wallet is expected to be present in the response.
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 initiateTransferResponsedeclares a new variable to store the response from theinitiateWalletTransfermethod.client.initiateWalletTransferis a method provided by the Circle SDK that initiates a transfer of funds from the user's wallet to another wallet.walletId: walletIdis a key-value pair in the object, where the key iswalletId, and the value is thewalletIdvariable (Obtained from the initializing the user's wallet[Step-3]).destinationis 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.
amountis 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.
Viewing your Wallet Balance:
const walletBalanceResponse = await client.getWalletBalance({ walletId: walletId }) console.log(walletBalanceResponse.data.balance.amount)Explanation of the above code:
const walletBalanceResponsedeclares a new variable to store the response from thegetWalletBalancemethod.client.getWalletBalanceis 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 thegetWalletBalancemethod, wherewalletIdis the value of thewalletIdvariable (presumably obtained from the previous step of initializing the user's wallet).console.logis a function in JavaScript that prints the specified value to the console (for debugging or logging purposes).walletBalanceResponse.data.balance.amountaccesses theamountproperty within thebalanceobject, which is nested inside thedataobject of thewalletBalanceResponse. This is where the actual balance amount is expected to be present in the response.❄ This is how the Transactions take place within 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.

