Web

This document contains the Programmable Wallets SDK reference for web app development.

The User Wallet offers Web SDK so that customers can integrate our services seamlessly into their web applications. The Web SDK secures the process through the iFrame element when users input their secret data, such as PIN and security answers. Also, the SDK ensures additional security by encrypting the request body with the encryption key.

At Circle, we understand the importance of end-to-end security for your application and also the need to create a tailored and seamless user experience for your end-users. Hence, our 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 our 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:

To use the SDK in the most flexible way, combine this SDK reference with the Web SDK UI Customization API article.

SDK Installation

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

Enums

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,
}

Interfaces

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

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

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)