SettleMint
Developer guidesCompliance

Collateral requirement

Configure collateral ratios and issue collateral verifications via API. The collateral compliance module ensures assets are backed by verifiable reserves.

This guide explains how to configure the collateral compliance module and issue collateral claims via API, ensuring your tokenized assets are backed by verifiable reserves.

For the web interface approach, see the user guide.

How collateral validation works

When minting new units of an asset with the collateral module enabled, the system:

  1. Checks if the asset's identity has a valid collateral claim
  2. Verifies the claim was issued by an authorized issuer and is not expired
  3. Confirms the collateral amount meets or exceeds the configured ratio based on post-mint total supply

This module only applies to minting operations. Regular transfers between wallets are not affected by collateral requirements.

Configuration parameters

When configuring the collateral module during asset creation, three parameters are required:

ParameterTypeDescriptionValid values
proofTopicBigIntERC-735 claim topic ID for collateral proofsSystem-provided topic ID
ratioBpsnumberRequired backing ratio in basis points (10000 = 100%)0 to 20000
trustedIssuersstring[]Additional trusted issuers for the proof topicEthereum addresses

Understanding collateral ratios

The collateral ratio is specified in basis points (1/100th of a percent): - 10000 = 100% backing (1,000 minted units require 1,000 collateral) - 15000 = 150% over-collateralized (1,000 minted units require 1,500 collateral) - 20000 = 200% maximum ratio (1,000 minted units require 2,000 collateral)

See Example scenario for a minting simulation.

Configure collateral during asset creation

Prerequisites

  • Platform URL (e.g., https://your-platform.example.com)
  • API key from a user with the Token Manager role (see Getting Started for API key setup)
  • Wallet verification method enabled on your account (e.g., pincode or 2FA)

Supply cap and collateral requirement configuration

Get collateral module address

Query the system to get the registered collateral compliance module address:

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

Response:

{
  "complianceModuleRegistry": {
    "complianceModules": [
      {
        "typeId": "collateral",
        "module": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707",
        "name": "Collateral Compliance Module"
      }
      // ... other modules
    ]
  }
}

Save the module address for the typeId: "collateral" entry.

Get collateral topic ID

Query the registered claim topics to find the collateral topic ID:

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

Response:

[
  {
    "id": "0x534b8f03c16c92c70d1da1d2fae43b98352bf3d7...",
    "topicId": "56591694316807385155654796962642700009023257328234168678289712861780104020528",
    "name": "collateral",
    "signature": "uint256 amount, uint256 expiryTimestamp",
    "registry": {
      "id": "0x534b8f03c16c92c70d1da1d2fae43b98352bf3d7"
    }
  }
  // ... other topics
]

Save the topicId value for the topic with name: "collateral".

Create asset with collateral module

Include the collateral module in the initialModulePairs array when creating the asset:

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": "Collateralized Equity",
    "symbol": "COLEQ",
    "decimals": 18,
    "countryCode": "840",
    "priceCurrency": "USD",
    "basePrice": "100",
    "initialModulePairs": [
      {
        "typeId": "collateral",
        "module": "0x5FC8d32690cc91D4c39d9d3abcBD16989F875707",
        "values": {
          "proofTopic": "56591694316807385155654796962642700009023257328234168678289712861780104020528",
          "ratioBps": 10000,
          "trustedIssuers": []
        }
      }
    ],
    "walletVerification": {
      "secretVerificationCode": "YOUR_PINCODE",
      "verificationType": "PINCODE"
    }
  }'

Response:

{
  "id": "0x1234567890AbCdEf1234567890AbCdEf12345678",
  "txHash": "0x8d95bfd5381478d90992d3e2e64c73178e46bb18592bfcbffdf899f2407aee9b"
}

Key fields in initialModulePairs:

FieldDescription
typeIdMust be "collateral" for the collateral module
moduleThe collateral module address from step 1
values.proofTopicThe collateral topic ID from step 2
values.ratioBpsCollateral ratio (10000 = 100%, 15000 = 150%)
values.trustedIssuersAdditional issuers recognized alongside the global registry (not a replacement)

Verify module configuration

Query the asset to confirm the collateral module is configured:

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

Check that complianceModuleConfigs contains an entry with typeId: "collateral".

Issue a collateral claim

After the asset is deployed with the collateral module, a collateral claim must be issued to the asset's identity before minting can occur.

Prerequisites

Collateral claims must be issued by a Trusted issuer for the collateral topic (see Configure trusted issuers)

Who should issue collateral claims?

Most teams delegate collateral attestations to compliance or treasury officers who operate as trusted issuers. Assign the claimIssuer role to those identities and register them for the collateral topic so they can service multiple assets.

Claim fields

FieldDescriptionFormat
amountThe collateral value backing the assetString (in base units)
expiryTimestampWhen the claim expires (must be in the future)ISO 8601 date-time

Issue the collateral claim

The collateral amount must be specified in base units (the smallest unit of the asset). For an asset with 18 decimals, multiply the desired amount by 10^18. For example, to back 100,000 units on an 18-decimal asset, use "100000000000000000000000" (100,000 × 10^18).

You issue collateral claims to the token's OnchainID identity using the system endpoint. You can obtain the targetIdentityAddress from the token creation response (identity.id) or by calling GET /token/{address}.

Use the identity contract address

Collateral claims are issued to the token's identity contract, not the token address or an operator wallet. Always pass the identity.id value as targetIdentityAddress.

curl -X POST "https://your-platform.example.com/api/system/identity/claim/issue" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "targetIdentityAddress": "0x20ADDd5023c494eA1594282ab6E94fA5A658C4f2",
    "claim": {
      "topic": "collateral",
      "data": {
        "amount": "100000000000000000000000",
        "expiryTimestamp": "2025-12-31T23:59:59Z"
      }
    },
    "walletVerification": {
      "secretVerificationCode": "YOUR_PINCODE",
      "verificationType": "PINCODE"
    }
  }'

Response:

{
  "txHash": "0x9f85bfd5381478d90992d3e2e64c73178e46bb18592bfcbffdf899f2407aee9b",
  "success": true,
  "claimTopic": "collateral",
  "targetIdentity": "0x20ADDd5023c494eA1594282ab6E94fA5A658C4f2"
}

Amount formatting

Asset amounts depend on the asset's decimal configuration. See Asset Decimals for formatting guidance.

With this collateral claim of 100,000 units and the 100% ratio configured above, you can mint up to 100,000 tokens. See Example scenario for a detailed minting simulation.

Verify the claim

Query the asset to confirm the collateral claim was issued:

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": "Collateralized Equity",
  "symbol": "COLEQ",
  "identity": {
    "id": "0x20ADDd5023c494eA1594282ab6E94fA5A658C4f2",
    "claims": [
      {
        "name": "collateral",
        "revoked": false,
        "values": [
          { "key": "amount", "value": "100000000000000000000000" },
          { "key": "expiryTimestamp", "value": "1767225599" }
        ],
        "isTrusted": false
      }
    ]
  },
  "complianceModuleConfigs": [
    {
      "complianceModule": {
        "typeId": "collateral"
      }
    }
  ]
}

Key fields to verify:

  • identity.claims contains the collateral claim with amount and expiry
  • identity.claims[].revoked is false (claim is active)

Plan for renewal

Collateral claims have an expiry date. Renew claims before they expire to avoid blocking future minting operations.

Example scenario

Using the configuration from this guide, a company issues equity shares with 100% collateral backing.

Configuration

  • Collateral ratio: 100% (10000 basis points)
  • Proof topic: System default (collateral)
  • Trusted issuers: Empty (using global registry)

Collateral claim

  • Amount: 100,000 units
  • Expiry: December 31, 2025

Minting simulation

OperationCurrent supplyMint amountPost-mint supplyRequired collateral (100%)AvailableResult
Initial mint050,00050,00050,000100,000✅ Allowed
Second mint50,00050,000100,000100,000100,000✅ Allowed
Third mint100,00010,000110,000110,000100,000❌ Blocked

Why the third mint fails

The third mint is blocked because:

  • Post-mint supply would be 110,000 units
  • At 100% ratio, required collateral = 110,000
  • Current collateral claim only covers 100,000
  • A new collateral claim with a higher amount is needed

To unblock

  1. Issue a new collateral claim with amount ≥ 110,000 (see Issue a collateral claim)
  2. Retry the minting operation

Request parameters

Collateral module configuration

ParameterTypeRequiredDescription
typeIdstringYesMust be "collateral"
modulestringYesCollateral module contract address (from system query)
values.proofTopicstringYesERC-735 claim topic ID (from claim topics query)
values.ratioBpsnumberYesCollateral ratio in basis points (0-20000)
values.trustedIssuersstring[]NoAdditional issuers recognized alongside the global registry (not a replacement)

Collateral claim issuance

ParameterTypeRequiredDescription
targetIdentityAddressstringYesToken identity address receiving the claim
claim.topicstringYesMust be "collateral"
claim.data.amountstringYesCollateral amount as string (in base units)
claim.data.expiryTimestampstringYesClaim expiry in ISO 8601 format (must be in the future)
walletVerificationobjectYesWallet verification (pincode or TOTP)

Wallet verification object

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

Best practices

Collateral ratio planning

  • Start with 100% (10000 basis points) for standard backing requirements
  • Use 150% (15000 basis points) or higher for over-collateralization when extra security is needed
  • Consider market volatility when setting ratios for assets backed by volatile collateral

Claim renewal

To renew a collateral claim, issue a new claim using the steps in Issue a collateral claim with an updated expiryTimestamp set to a future date.

  • Monitor collateral claim expiry dates and renew before they expire
  • Set calendar reminders or automated alerts for upcoming expirations
  • Allow buffer time for renewal to avoid blocking minting operations

Trusted issuers

  • Leave trustedIssuers empty to rely solely on the global registry
  • Adding addresses to trustedIssuers extends the global registry—it does not replace it
  • Use this array for issuers not registered globally but authorized for this specific asset
  • Verify issuer addresses carefully before adding them

Troubleshooting

IssueSolution
401 UnauthorizedAPI key is invalid, expired, or disabled
403 USER_NOT_AUTHORIZEDEnsure the caller has the required role: tokenManager for asset creation, or claimIssuer and trusted issuer status for claim issuance
Collateral module not foundQuery /system/default to get the correct module address
Invalid topic IDQuery /system/claim-topics to get the correct collateral topic ID
Insufficient collateralIssue a collateral claim with sufficient amount before minting
Collateral verification expiredIssue a new collateral claim with a future expiry date
ratioBps out of rangeValue must be between 0 and 20000

On this page