Web SDK

Set up the client-side web SDK for user-controlled wallets in your web application.

The Circle web SDK enables your web application to provide user-controlled wallets. By integrating this SDK, your users can securely input sensitive data like PINs or security answers through an iFrame element. The SDK encrypts the request body using an encryption key, protecting your users' information.

📘 The Web and Mobile SDKs preserve the user keyshare with the individual, giving them complete control. You must use the SDKs with the user-controlled wallet product. Additionally, the Web and Mobile SDKs support only the user-controlled wallet product.

At Circle, we understand the importance of end-to-end security for your application and the need to create a tailored and seamless user experience for your end-users. Hence, Circle’s SDK also exposes functionality for you to customize the description and layout: 

  • UI Title and Subtitle Customization: Modify the title and subtitle to reflect your brand identity or provide specific instructions.

  • Custom PIN Code Input Layout: Adjust the layout and styling of the PIN code input field to align with your application's design guidelines.

  • Question List Configuration: Set the list of security questions displayed in the User Wallet UI, allowing users to choose from a predefined set.

  • SDK Initialization: Initialize the Web SDK by setting the endpoint server, ensuring seamless communication between your application and Circle’s services.

  • Predefined Error Messages: Customize the error messages displayed to users, providing a more personalized experience and guidance.

  • ChallengeID Acceptance and Operation Retrieval: Easily accept the challengeID and retrieve any relevant operations within the SDK.

💡Tip: See the Web SDK UI Customization API article to customize the SDK.

Install the SDKs

Install using npm:

npm install @circle-fin/w3s-pw-web-sdk

Sample code

React.js

import React, { useCallback, useEffect, useState } from 'react'
import { ToastContainer, toast } from 'react-toastify'
import TextField from '@mui/material/TextField'
import Button from '@mui/material/Button'
import { W3SSdk } from '@circle-fin/w3s-pw-web-sdk'

let sdk: W3SSdk

function App() {
  useEffect(() => {
    sdk = new W3SSdk()
  }, [])

  const [appId, setAppId] = useState(
    localStorage.getItem('appId') || 'someAppId'
  )
  const [userToken, setUserToken] = useState(
    localStorage.getItem('userToken') || 'someUserToken'
  )
  const [encryptionKey, setEncryptionKey] = useState(
    localStorage.getItem('encryptionKey') || 'someEncryptionKey'
  )
  const [challengeId, setChallengeId] = useState(
    localStorage.getItem('challengeId') || 'someChallengeId'
  )

  const onChangeHandler = useCallback(
    (setState, key) => (e) => {
      const value = e.target.value
      setState(value)
      localStorage.setItem(key, value)
    },
    []
  )

  const onSubmit = useCallback(() => {
    sdk.setAppSettings({ appId })
    sdk.setAuthentication({ userToken, encryptionKey })

    sdk.execute(challengeId, (error, result) => {
      if (error) {
        toast.error(`Error: ${error?.message ?? 'Error!'}`)
        return
      }
      toast.success(`Challenge: ${result?.type}, Status: ${result?.status}`)
    })
  }, [appId, userToken, encryptionKey, challengeId])

  return (
    <div className="p-4">
      <TextField
        label="App Id"
        onChange={onChangeHandler(setAppId, 'appId')}
        value={appId}
      />
      <TextField
        label="User Token"
        onChange={onChangeHandler(setUserToken, 'userToken')}
        value={userToken}
      />
      <TextField
        label="Encryption Key"
        onChange={onChangeHandler(setEncryptionKey, 'encryptionKey')}
        value={encryptionKey}
      />
      <TextField
        label="Challenge Id"
        onChange={onChangeHandler(setChallengeId, 'challengeId')}
        value={challengeId}
      />
      <Button variant="contained" color="primary" onClick={onSubmit}>
        Verify Challenge
      </Button>
      <ToastContainer />
    </div>
  )
}

Vanilla Javascript

// Assume W3SSdk is globally available
let sdk = new W3SSdk()

// Initialize settings
const initSettings = () => {
  sdk.setAppSettings({
    appId: 'someAppId',
  })
  sdk.setAuthentication({
    userToken: 'someUserToken',
    encryptionKey: 'someEncryptionKey',
  })
}

// Handle form submission
const handleSubmit = () => {
  const challengeId = document.getElementById('challengeId').value

  sdk.execute(challengeId, (error, result) => {
    if (error) {
      console.error(`Error: ${error?.message ?? 'Error!'}`)
      return
    }
    console.log(`Challenge: ${result?.type}, Status: ${result?.status}`)
  })
}

// Initialization
initSettings()

// Listen for button click event
document.getElementById('submitBtn').addEventListener('click', handleSubmit)

SDK architecture

You must use Web, iOS, or Android SDKs to access the user-controlled Programmable Wallet product. The SDK secures, manages, and communicates with your server to ensure your user’s keyshare, always stays with them and is not exposed to your servers.

To learn more, see SDK Architecture for User-Controlled Wallets.

SDK API references: enums

The Web SDK supports the API reference enums listed in the following sections.

ChallengeType

Enumerates the types of challenges supported.

enum ChallengeType {
  RESTORE_PIN,
  SET_SECURITY_QUESTIONS,
  CREATE_WALLET,
  CREATE_TRANSACTION,
  ACCELERATE_TRANSACTION,
  CANCEL_TRANSACTION,
  CONTRACT_EXECUTION,
  SIGN_MESSAGE,
  SIGN_TYPEDDATA,
  UNKNOWN,
}

ChallengeStatus

Enumerates the possible statuses for a challenge.

enum ChallengeStatus {
  COMPLETE,
  EXPIRED,
  FAILED,
  IN_PROGRESS,
  PENDING,
}

QuestionType

Enumerates the types of security questions.

enum QuestionType {
  DATE,
  TEXT,
}

ErrorCode

Enumerates the types of error code.

enum ErrorCode {
  unknown = -1,
  success = 0,
  apiParameterMissing = 1,
  apiParameterInvalid = 2,
  forbidden = 3,
  unauthorized = 4,
  retry = 9,
  customerSuspended = 10,
  pending = 11,
  invalidSession = 12,
  invalidPartnerId = 13,
  invalidMessage = 14,
  invalidPhone = 15,
  userAlreadyExisted = 155101,
  userNotFound = 155102,
  userTokenNotFound = 155103,
  userTokenExpired = 155104,
  invalidUserToken = 155105,
  userWasInitialized = 155106,
  userHasSetPin = 155107,
  userHasSetSecurityQuestion = 155108,
  userWasDisabled = 155109,
  userDoesNotSetPinYet = 155110,
  userDoesNotSetSecurityQuestionYet = 155111,
  incorrectUserPin = 155112,
  incorrectDeviceId = 155113,
  incorrectAppId = 155114,
  incorrectSecurityAnswers = 155115,
  invalidChallengeId = 155116,
  invalidApproveContent = 155117,
  invalidEncryptionKey = 155118,
  userPinLocked = 155119,
  securityAnswersLocked = 155120,
  notEnoughFunds = 155201,
  notEnoughBalance = 155202,
  exceedWithdrawLimit = 155203,
  minimumFundsRequired = 155204,
  invalidTransactionFee = 155205,
  rejectedOnAmlScreening = 155206,
  tagRequired = 155207,
  gasLimitTooLow = 155208,
  transactionDataNotEncodedProperly = 155209,
  fullNodeReturnedError = 155210,
  walletSetupRequired = 155211,
  lowerThenMinimumAccountBalance = 155212,
  rejectedByBlockchain = 155213,
  droppedAsPartOfReorg = 155214,
  operationNotSupport = 155215,
  amountBelowMinimum = 155216,
  wrongNftTokenIdNumber = 155217,
  invalidDestinationAddress = 155218,
  tokenWalletChainMismatch = 155219,
  wrongAmountsNumber = 155220,
  walletIsFrozen = 155501,
  maxWalletLimitReached = 155502,
  walletSetIdMutuallyExclusive = 155503,
  metadataUnmatched = 155504,
  userCanceled = 155701,
  launchUiFailed = 155702,
  pinCodeNotMatched = 155703,
  insecurePinCode = 155704,
  hintsMatchAnswers = 155705,
  networkError = 155706,
  biometricsSettingNotEnabled = 155708,
  deviceNotSupportBiometrics = 155709,
  biometricsKeyPermanentlyInvalidated = 155710,
  biometricsUserSkip = 155711,
  biometricsUserDisableForPin = 155712,
  biometricsUserLockout = 155713,
  biometricsUserLockoutPermanent = 155714,
  biometricsUserNotAllowPermission = 155715,
  biometricsInternalError = 155716,
  walletIdNotFound = 156001,
  tokenIdNotFound = 156002,
  transactionIdNotFound = 156003,
  entityCredentialNotFound = 156004,
  walletSetIdNotFound = 156005,
}

SDK API references: interfaces

The Web SDK supports the interfaces listed in the following sections.

AppSettings

Holds application settings.

  • appId <string> Application ID, retrieved from Circle Web3 Services Console

Authentication

Holds authentication information.

Challenge

Holds information about a challenge.

SignMessageResult

Holds the result of a sign message or sign typed-data challenge.

  • signature <string> Signature result after signing

ChallengeResult

Holds the result of a challenge.

SecurityQuestion

Holds information about a custom security question.

Error

Holds error information.

Localizations

Holds localization settings.

Common

Holds localization settings for common texts.

ConfirmPincode

Holds localization settings for ConfirmInitPincode or ConfirmNewPincode screen.

EnterPincode

Holds localization settings for EnterPincode screen.

NewPincode

Holds localization settings for InitPincode or NewPincode screen.

RecoverPincode

Holds localization settings for RecoverPincode screen.

SecurityConfirm

Holds localization settings for SecurityConfirm screen.

SecurityIntros

Holds localization settings for SecurityIntros screen.

SecurityQuestions

Holds localization settings for SecurityQuestions screen.

SecuritySummary

Holds localization settings for SecuritySummary screen.

ThemeColor

Holds customization color settings.

Resources

Holds resource urls and properties, such as images or font-family settings. These resource properties should be hosted on a public server. SDK will load these resources from the urls provided.

CustomLinks

Holds custom links.

Class Definition

The WEB SDK supports the class definitions listed in the following sections.

W3SSdk

Constructor

Initializes a new instance of W3SSdk.

Methods

execute

Executes a challenge.

setAppSettings

Sets the application settings.

setAuthentication

Sets the authentication information.

setCustomSecurityQuestions

Sets custom security questions.

setLocalizations

Sets custom localizations

setResources

Sets custom resources

setThemeColor

Sets custom theme colors

setCustomLinks

Sets custom links

setOnForgotPin

Sets callback function for ForgotPin button click event