We refreshed our doc site!
Bookmarked links may have changed
Read release notesLearn how to initialize and create a user-controlled wallet using the email. To create a wallet with social logins, see Create Your First Wallet with Social Logins.
This quickstart utilizes Circle’s sample application in combination with API requests that can be sent using cURL requests or Circle's API references. cURL requests are provided inline while API references call the API endpoints. For more on how to use API references to make calls, see Testing API References.
You can create both Smart Contract Accounts (SCA) and Externally Owned Accounts (EOA) wallets. To learn more, see the Account Type guide.
Before you begin:
This guide walks you through steps on how to create a wallet and perform transactions or signatures, and provides sample code. You can use Circle's sample app on web or set it up locally.
You can view the sample app source code on GitHub:
If you want to test in the iOS or Android environment, you can check our Github repo for iOS sample app and Android sample app. React Native sample app is coming soon.
GET
request to the /config/entity
endpoint and copy the appId
from the response body.The sample app generates and pre-populates the device ID. During actual implementation, you must retrieve it by calling the SDK method getDeviceId
.
Include your API key, deviceId
, and email address in a POST
request to the /users/email/token
endpoint.
curl --location 'https://api.circle.com/v1/w3s/users/email/token' \
--header 'Content-Type: application/json' \
--header `Authorization: Bearer ${your api key}` \
--data '{
"idempotencyKey": "3eeacdee-786c-4777-854d-6e457a060782",
"deviceId": "your device id"
}'
Copy deviceToken
, deviceEncryptionKey
, and otpToken
from the response and enter them into the sample app.
{
deviceToken: string
deviceEncryptionKey: string
otpToken?: string // For email authentication method only
}
On the sample app, select Login with Email. This takes you through the OTP email flow:
An email containing an OTP is sent to the email address specified in your request to /users/email/token
.
The sample app prompts you with a UI to enter the OTP to verify identity, which corresponds to the SDK method verifyOTP
.
Once the OTP is verified, you are redirected back to the main page of the sample app. The "Execute Challenge" section is now visible.
Select Execute Challenge.
Both encryptionKey
and userToken
are pre-populated since these parameters are required for the next step, which is to initialize the user.
The sample app pre-populates the encryptionKey
and userToken
for you. During the actual development, the client-side SDK returns userId
, userToken
, encryptionKey
, and refreshToken
to you.
userToken
copied from the previous step in a POST
request to the /user/initialize
endpoint.challengeId
from the response and enter it into the sample app.To create an SCA wallet, provide a Testnet blockchain such as ETH-SEPOLIA, MATIC-AMOY, and AVAX-FUJI.
The following code samples show how to create an SCA wallet on Amoy and the response.
const response = await circleUserSdk.createUserPinWithWallets({
userToken: '<USER_TOKEN>',
accountType: 'SCA',
blockchains: ['MATIC-AMOY']
});
{
"data": {
"challengeId": "0d1b5f41-1381-50af-983b-f54691415158"
}
}
The following code samples show how to create an EOA wallet on Solana and the response.
const response = await circleUserSdk.createUserPinWithWallets({
userToken: '<USER_TOKEN>',
accountType: 'EOA',
blockchains: ['SOL-DEVNET']
});
{
"data": {
"challengeId": "0d1b5f41-1381-50af-983b-f54691415158"
}
}
To execute a challenge during actual implementation, you must call the Web SDK API execute
with the challengeId
returned from Circle. Also, make sure you have an active userToken
, encryptionKey
for any challenge executions.
Once you have created a wallet in the sample app, you can check the user and wallet status.
To check the user's account status:
userToken
in a GET
request to the /user
endpoint to retrieve the status of the user’s account.const response = await circleUserSdk.getUserStatus({
userToken: '<USER_TOKEN>'
});
{
"data": {
"id": "2f1dcb5e-312a-4b15-8240-abeffc0e3463",
"status": "ENABLED",
"createDate": "2023-07-26T15:27:32Z",
"pinStatus": "ENABLED",
"pinDetails": {
"failedAttempts": 0
},
"securityQuestionStatus": "ENABLED",
"securityQuestionDetails": {
"failedAttempts": 0
}
}
}
To check the status of the user’s new wallet.
userToken
in a GET
request to the /wallets
endpoint to retrieve the user’s new wallet.const response = await circleUserSdk.listWallets({
userToken: '<USER_TOKEN>'
});
{
"data": {
"wallets": [
{
"id": "01899cf2-d415-7052-a207-f9862157e546",
"state": "LIVE",
"walletSetId": "01899cf2-d407-7f89-b4d9-84d63573f138",
"custodyType": "ENDUSER",
"userId": "2f1dcb5e-312a-4b15-8240-abeffc0e3463",
"address": "0x075e62c80e55d024cfd8fd4e3d1184834461db57",
"addressIndex": 0,
"blockchain": "MATIC-AMOY",
"accountType": "SCA",
"updateDate": "2023-07-28T14:41:47Z",
"createDate": "2023-07-28T14:41:47Z"
}
]
}
}
{
"data": {
"wallets": [
{
"id": "8a79c80b-4d4f-4032-971a-8bb9f9b0254f",
"state": "LIVE",
"walletSetId": "c43221d3-9db1-4cbf-8b18-e1dcae16b55d",
"custodyType": "ENDUSER",
"userId": "d8c8f832-5d4f-4123-9a7f-60120c2da5f0",
"address": "8UFfxP3zzSeqdkZ5iLTmUGzpHPRGnydZ1Vnq5GkzKTep",
"addressIndex": 0,
"blockchain": "SOL-DEVNET",
"accountType": "EOA",
"updateDate": "2023-07-28T14:43:48Z",
"createDate": "2023-07-28T14:43:48Z"
}
]
}
}
You can also view the User ID, Auth Method, and Wallet status on the Circle Developer Console: