SettleMint
Compliance

Identity verification

Configure the identity verification compliance module to require verified OnchainID claims for all asset transfers. Build logical expressions combining multiple claim requirements.

The identity verification compliance module requires OnchainID claim topics before regulated asset operations can complete. Pass the module address and a postfix claim expression in initialModulePairs during asset creation.

On-chain identity registry for market participants

For the full module reference, including the runtime flow, trusted issuer path, failure modes, and expression semantics, see Identity Verification reference. For the underlying wallet, OnchainID, claim-topic, and trusted issuer model, see Claims and identity. For the web interface approach, see the compliance overview.

Prerequisites

You need a Platform URL (for example https://your-platform.example.com) and an API key from a user with the Token Manager role. See Getting Started for API key setup.

You also need a token factory for your desired asset type deployed to the network, and a wallet verification method enabled on your account (pincode or 2FA).

How identity verification works

Integrators and auditors both need to understand this gate. When you add this module, the blockchain validates every transfer by checking the recipient's OnchainID claims against the token's configured postfix expression. A claim counts only when the topic exists, the recipient wallet resolves to an accepted identity, the wallet is not marked as lost, and a trusted issuer validates the claim signature and data.

  1. Recipient check: The receiving wallet must resolve to an accepted OnchainID that is not marked as lost.
  2. Claim check: That OnchainID must hold a valid claim for every topic the expression requires.
  3. Trusted issuer: A registered claim signer in the asset's issuer registry must have signed each claim.

The module evaluates the recipient only. It does not check the sender. If the expression evaluates to false, the transfer reverts with RecipientNotVerified before execution.

Configuration parameters

Pass these parameters when you attach the compliance module during asset creation. All three fields are required.

ParameterTypeDescription
typeIdstringMust be "identity-verification"
modulestringIdentity verification module contract address (from system query)
valuesarrayPostfix expression nodes defining the required claim logic

Expression nodes

The values array contains postfix expression nodes that define which claims the module requires. Each node has two fields to configure:

FieldTypeDescription
nodeTypenumberOperation type: 0 = TOPIC, 1 = AND, 2 = OR, 3 = NOT
valuestringFor TOPIC nodes: the claim topic ID (BigInt). For operators: "0"

The expression can contain up to 32 nodes. A non-empty expression must leave exactly one boolean value on the stack after evaluation. Topic ID 0 is invalid. An empty expression skips claim-topic evaluation, but the recipient wallet still needs a registered identity and must not be marked as lost.

Configuring identity verification during asset creation

Get the module address

Query the system to retrieve the registered module address. You need this address for the initialModulePairs payload in step 3.

curl -X GET "https://your-platform.example.com/api/system/default" \
  -H "X-Api-Key: YOUR_API_KEY"

Response:

{
  "complianceModuleRegistry": {
    "complianceModules": [
      {
        "typeId": "identity-verification",
        "module": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F",
        "name": "Identity Verification Module"
      }
      // ... other modules
    ]
  }
}

Copy the module address for the typeId: "identity-verification" entry. You will pass it in step 3.

Choose claim topics

Select the topics you want to enforce. The platform computes each topic ID as keccak256(topicName). Record the ID for every claim type you plan to require.

The tables below group topics by context. Collect the IDs for all claims your asset requires.

Investor-level claims apply to the wallets transacting with the asset.

TopicTopic ID (BigInt)
knowYourCustomer26984799302505749158794800959285050858086405868089409909048783980951278841746
antiMoneyLaundering66602700950116947137359654609674923607788815289970476259958745144319039408766
qualifiedInstitutionalInvestor39526553109170329799339511574661256630735485618560740361645615581310848276505
professionalInvestor82180795564044264154236077867753775185787185513502198122023755895636360079450
accreditedInvestor15733030998618876990024220391915773205162379317494393310546829862321881862123
accreditedInvestorVerified59850607985445873266538496619638148123529590973767384129725397368921421733377
regulationS110498984792486559366779193967170177172527553783122289566437277521370918941833

Issuer-level claims capture regulatory standing for the token issuer. Use these when the asset's rules require the issuing entity to hold specific licenses or filings.

TopicTopic ID (BigInt)
issuerProspectusFiled66024707054635888688268119510009865452443315877106845614779928773130009296293
issuerProspectusExempt108155241138976356337931447616840292633551902984574900198960811245767215772826
issuerLicensed4159646717597184831767716799371953881543937679636133282035549426319534456864
issuerReportingCompliant63974049055435959798075765549996859356159125666706735332156257908409531829710
issuerJurisdiction22945659622044541592208660721714212954694094425401272022345597464077438219436

Asset-level claims describe attributes of the regulated asset itself. Attach these when the asset's on-chain record must carry provenance, pricing, or classification data.

TopicTopic ID (BigInt)
collateral56591694316807385155654796962642700009023257328234168678289712861780104020528
uniqueIdentifier114741468009595078276449793420639789199829227967433767091939592755701866581418
assetClassification24450086974696203741514129497527543680077858637075869492686262873957363087146
basePrice57654513796690178928725925529203455242162418455779606444866766669020006213509
assetIssuer59193974906477606357781697605998854609236670153591542535032894715512537823578
assetLocation8432405482680553454773023573904831382358253771058496665012951440405906006611

General claims apply across participant and asset contexts. They cover generic identity markers and custom extensions that do not fit the other categories.

TopicTopic ID (BigInt)
contractIdentity43841672744129833047570617593608746101743408532017342577134968204499777399068
custom4204500278131556441620930517354114011833808539324421779944429921463295225973

Create the asset with identity verification

Include the module in the initialModulePairs array when creating your asset. The example below creates an equity asset that requires the knowYourCustomer claim on every transfer.

curl -X POST "https://your-platform.example.com/api/token/create" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "equity",
    "name": "KYC Protected Equity",
    "symbol": "KYCE",
    "decimals": 18,
    "countryCode": 840,
    "priceCurrency": "USD",
    "basePrice": "100",
    "initialModulePairs": [
      {
        "typeId": "identity-verification",
        "module": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F",
        "values": [
          {
            "nodeType": 0,
            "value": "26984799302505749158794800959285050858086405868089409909048783980951278841746"
          }
        ]
      }
    ],
    "walletVerification": {
      "secretVerificationCode": "YOUR_PINCODE",
      "verificationType": "PINCODE"
    }
  }'

Response:

{
  "id": "0x1234567890AbCdEf1234567890AbCdEf12345678",
  "type": "equity",
  "createdAt": "2025-01-15T10:30:00.000Z",
  "name": "KYC Protected Equity",
  "symbol": "KYCE",
  "decimals": 18,
  "basePrice": "[\"100\",0]",
  "basePriceCurrencyCode": "USD",
  "totalSupply": "[\"0\",0]",
  "pausable": {
    "paused": true
  }
}

The response includes the full asset object (including identity, accessControl, complianceModuleConfigs, userPermissions, and stats). The asset starts paused by default.

The table below lists the key fields, each mapping to the initialModulePairs entry structure in the Request parameters section.

FieldDescription
typeIdMust be "identity-verification" for this module
moduleThe identity verification module address from step 1
valuesArray of postfix expression nodes defining required claims
values[].nodeType0 for claim topics, 1 for AND, 2 for OR, 3 for NOT
values[].valueTopic ID (BigInt string) for topics, "0" for operators

Confirm the configuration

Query the token to verify the platform activated the module. The complianceModuleConfigs array lists every active compliance module for that token.

curl -X GET "https://your-platform.example.com/api/token/0x1234567890AbCdEf1234567890AbCdEf12345678" \
  -H "X-Api-Key: YOUR_API_KEY"

Response (relevant fields):

{
  "id": "0x1234567890AbCdEf1234567890AbCdEf12345678",
  "type": "equity",
  "name": "KYC Protected Equity",
  "symbol": "KYCE",
  "complianceModuleConfigs": [
    {
      "complianceModule": {
        "typeId": "identity-verification",
        "module": "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F"
      }
    }
  ]
}

Check that complianceModuleConfigs contains an entry with typeId: "identity-verification". Once confirmed, the module is active and the asset enforces identity verification on every transfer.

Expression examples

The examples below show how to construct the values array for common compliance scenarios. Each example demonstrates one pattern; combine them as your asset's regulatory requirements demand. For the full expression semantics, operator precedence, and node type reference, see the Identity Verification reference.

Single requirement (KYC only)

For most regulated assets, a single KYC check is sufficient. The values array contains one TOPIC node. The recipient wallet must hold a valid knowYourCustomer claim from a trusted issuer.

{
  "values": [
    {
      "nodeType": 0,
      "value": "26984799302505749158794800959285050858086405868089409909048783980951278841746"
    }
  ]
}

KYC and AML combined

Use an AND node to require both knowYourCustomer and antiMoneyLaundering. List the first TOPIC node, then the AND operator node, then the second TOPIC node:

{
  "values": [
    {
      "nodeType": 0,
      "value": "26984799302505749158794800959285050858086405868089409909048783980951278841746"
    },
    { "nodeType": 1, "value": "0" },
    {
      "nodeType": 0,
      "value": "66602700950116947137359654609674923607788815289970476259958745144319039408766"
    }
  ]
}

Alternative requirements (KYC OR accreditedInvestor)

Use an OR node to accept either knowYourCustomer or accreditedInvestor. This pattern suits assets where different investor types qualify under different rules:

{
  "values": [
    {
      "nodeType": 0,
      "value": "26984799302505749158794800959285050858086405868089409909048783980951278841746"
    },
    { "nodeType": 2, "value": "0" },
    {
      "nodeType": 0,
      "value": "15733030998618876990024220391915773205162379317494393310546829862321881862123"
    }
  ]
}

Complex expression with grouping

Use grouping to require (KYC AND AML) OR qualifiedInstitutionalInvestor. Add the literal strings "(" and ")" as array elements around the sub-expression:

{
  "values": [
    {
      "nodeType": 0,
      "value": "26984799302505749158794800959285050858086405868089409909048783980951278841746"
    },
    { "nodeType": 1, "value": "0" },
    {
      "nodeType": 0,
      "value": "66602700950116947137359654609674923607788815289970476259958745144319039408766"
    },
    { "nodeType": 2, "value": "0" },
    {
      "nodeType": 0,
      "value": "39526553109170329799339511574661256630735485618560740361645615581310848276505"
    }
  ]
}

Request parameters

Use these fields when constructing the module configuration. The values array drives on-chain evaluation, so every node must be valid before you submit the request.

Identity verification module configuration

Fields for the identity verification entry in initialModulePairs. The values field accepts node objects and "(" / ")" grouping markers.

ParameterTypeRequiredDescription
typeIdstringYesMust be "identity-verification"
modulestringYesModule contract address, retrieved from the system query
valuesarrayYesPostfix expression array containing topic nodes, operator nodes, and optional grouping markers
values[]object or stringYesUse an expression node object, or the literal strings "(" and ")" for grouping
values[].nodeTypenumberFor node objects0 = TOPIC, 1 = AND, 2 = OR, 3 = NOT
values[].valuestringFor node objectsTopic ID for TOPIC nodes, "0" for operators

Wallet verification object

Include a wallet verification object in every mutation request to authorize the on-chain write. The secretVerificationCode must match your configured method: a 6-digit code for PINCODE, a backup code for SECRET_CODES, or a TOTP for OTP.

FieldTypeDescription
secretVerificationCodestring6-digit pincode or TOTP code
verificationTypestring"PINCODE" (default), "SECRET_CODES", or "OTP"

If you omit verificationType, the platform defaults to "PINCODE". Use "OTP" for TOTP-based authenticators, or "SECRET_CODES" for backup code authentication.

Best practices

Claim selection

Choose claims that match your regulatory context. Start with knowYourCustomer for basic compliance, then layer additional claims as your rules require. The combination determines the strictness of the gate for every transfer on that asset.

Add antiMoneyLaundering for enhanced due diligence. Use accreditedInvestor or qualifiedInstitutionalInvestor for securities with investor restrictions. Combine claims with AND for stricter requirements, or with OR for flexibility.

Expression design

Keep expressions simple: a single topic is sufficient in most cases. Test complex expressions in a non-production environment and document the logic for compliance audits. Use OR with accreditation claims to support different investor types.

Trusted issuers

  • Confirm all claim issuers appear in the trusted issuer registry before enabling the module.
  • Verify each issuer's credentials before adding them.
  • Review issuer permissions on a regular schedule.

Troubleshooting

Use the table below to identify the cause and corrective step for each error.

IssueSolution
401 UnauthorizedAPI key is invalid, expired, or disabled
403 USER_NOT_AUTHORIZEDEnsure your account has tokenManager role
Module not foundQuery /system/default to get the correct module address
Invalid expressionCheck that every operator has the required operand, that parentheses balance, and that each node uses a valid nodeType
Invalid topic IDVerify topic ID matches the keccak256 hash of the claim topic name
RecipientNotVerifiedThe expression evaluated to false for the recipient. Check identity registration, claims, topic IDs, and trusted issuer registrations. See the Identity Verification reference for the full failure mode matrix.

On this page