π§΅ Deploy ERC3643 Token with Diamond Standard (ERC-2535)
Welcome to the complete guide for deploying an ERC3643 token with Diamond Standard (ERC-2535) using the Token City Blockchain API.
π Objective: Deploy a modular and upgradeable tokenized security that combines the compliance features of ERC-3643 with the flexibility of the Diamond standard.
π OpenAPI Documentationβ
β¨ Workflow Summaryβ
This workflow automates the process of deploying an ERC3643 Diamond token:
- πΉ Generate EIP712 typed data for the deployment signature.
- πΉ Sign the EIP712 typed data with your custodian account.
- πΉ Deploy the ERC3643 Diamond token with the signature.
- πΉ Monitor deployment status via webhook (TX_MINED or TX_FAILED).
π Workflow Steps Tableβ
| Step | API Operation | Method | Parameters | Outputs | Description |
|---|---|---|---|---|---|
| Generate typed data for token deployment | POST /v2/factory/erc3643-diamond/eip712-typed-data | POST | Token Deployment Data | Structured EIP712 TypedData | Generates the necessary typed data for ERC3643 Diamond token deployment |
| Sign the typed data | POST /accounts/:accountId/signEip712 (v1.8.1) | POST | Structured EIP712 TypedData | EIP712 Signature | Signs the previously generated structured EIP712 typed data |
| Deploy ERC3643 Diamond Token | POST /v2/factory/erc3643-diamond | POST | TokenDeploymentData + EIP712 Signature | txUUID, tokenId, tokenAddress | Submits the deployment transaction to blockchain, check webhook TX_MINED for confirmation |
π¨ Workflow Visualizationsβ
π Mermaid Sequence Diagramβ
π Step-by-Step Implementationβ
Step 1: Generate EIP712 Typed Dataβ
Generate the typed data required for the deployment signature.
Endpoint: POST /v2/factory/erc3643-diamond/eip712-typed-data
Request Body:
{
"name": "Security Token Diamond",
"symbol": "STD",
"decimals": 18,
"erir": "0x0290FB167208Af455bB137780163b7B7a9a10C16",
"issuer": "0x123456A9571241e97cDb61E3FfD1937D885454dd",
"operator": "0x123456A9571241e97cDb61E3FfD1937D885454dd",
"maxSupply": 1000000,
"modules": ["OnlyIntegerTransferModule", "USDCInterestBearingModule"]
}
Response:
{
"domain": {
"name": "OwnerMulticallDeployer",
"version": "1.0.0",
"chainId": 137,
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"DeployDiamondToken": [
{ "name": "salt", "type": "string" },
{ "name": "name", "type": "string" },
{ "name": "symbol", "type": "string" },
{ "name": "decimals", "type": "uint8" },
{ "name": "_erir", "type": "address" },
{ "name": "issuer", "type": "address" },
{ "name": "operator", "type": "address" },
{ "name": "maxSupply", "type": "uint256" },
{ "name": "isTransferable", "type": "bool" }
]
},
"primaryType": "DeployDiamondToken",
"message": {
"salt": "ERC3643-TEST STD",
"name": "Security Token Diamond",
"symbol": "STD",
"decimals": 18,
"_erir": "0x0290FB167208Af455bB137780163b7B7a9a10C16",
"issuer": "0x123456A9571241e97cDb61E3FfD1937D885454dd",
"operator": "0x123456A9571241e97cDb61E3FfD1937D885454dd",
"maxSupply": 1000000,
"isTransferable": true
}
}
Step 2: Sign the EIP712 Typed Dataβ
Sign the typed data using your custodian account.
Endpoint: POST /accounts/:accountId/signEip712 (from v1.8.1)
Request Body:
{
"typedData": {
"domain": {
"name": "OwnerMulticallDeployer",
"version": "1.0.0",
"chainId": 137,
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"DeployDiamondToken": [
{ "name": "salt", "type": "string" },
{ "name": "name", "type": "string" },
{ "name": "symbol", "type": "string" },
{ "name": "decimals", "type": "uint8" },
{ "name": "_erir", "type": "address" },
{ "name": "issuer", "type": "address" },
{ "name": "operator", "type": "address" },
{ "name": "maxSupply", "type": "uint256" },
{ "name": "isTransferable", "type": "bool" }
]
},
"primaryType": "DeployDiamondToken",
"message": {
"salt": "ERC3643-TEST STD",
"name": "Security Token Diamond",
"symbol": "STD",
"decimals": 18,
"_erir": "0x0290FB167208Af455bB137780163b7B7a9a10C16",
"issuer": "0x123456A9571241e97cDb61E3FfD1937D885454dd",
"operator": "0x123456A9571241e97cDb61E3FfD1937D885454dd",
"maxSupply": 1000000,
"isTransferable": true
}
}
}
Response:
{
"signature": "0xea8a0fb12ebadd4574b9fc1677ebfbede47f51d6afe352c625a4032b5f8e190d6ea64ee83e4eaf5d380ec1505d2f35cdcf80f38e66d677eea1ed45a3158c285c1b"
}
Step 3: Deploy the ERC3643 Diamond Tokenβ
Deploy the token with the signed data.
Endpoint: POST /v2/factory/erc3643-diamond
Request Body:
{
"name": "Security Token Diamond",
"symbol": "STD",
"decimals": 18,
"erir": "0x0290FB167208Af455bB137780163b7B7a9a10C16",
"issuer": "0x123456A9571241e97cDb61E3FfD1937D885454dd",
"operator": "0x123456A9571241e97cDb61E3FfD1937D885454dd",
"maxSupply": 1000000,
"modules": ["OnlyIntegerTransferModule", "USDCInterestBearingModule"],
"signature": "0xea8a0fb12ebadd4574b9fc1677ebfbede47f51d6afe352c625a4032b5f8e190d6ea64ee83e4eaf5d380ec1505d2f35cdcf80f38e66d677eea1ed45a3158c285c1b"
}
Response:
{
"result": {
"id": "6585b5fb-8de8-452d-aa96-8e5de0f1ca09",
"contractId": "75ec20f7-3de4-4fd1-bc7d-d6475f82d57c",
"message": "Deployment transaction sent, wait for webhook confirmation",
"contractAddress": "0xC593e77451cE7009209Ea4e7F62d64F2355D71ff"
}
}
Step 4: Monitor Deployment Statusβ
Subscribe to webhooks to receive deployment status updates.
Webhook Events:
TX_MINED: Transaction successfully minedTX_FAILED: Transaction failed
TX_MINED Webhook:
{
"type": "TX_MINED",
"event": {
"txUUID": "6585b5fb-8de8-452d-aa96-8e5de0f1ca09",
"txHash": "0xb5c8bd9430b6cc87a0e2fe110ece6bf527fa4f170a4bc8cd032f768fc5219838",
"blockNumber": 12345678,
"timestamp": 1634567890
}
}
TX_FAILED Webhook:
{
"type": "TX_FAILED",
"event": {
"txUUID": "6585b5fb-8de8-452d-aa96-8e5de0f1ca09",
"reason": "Insufficient gas",
"timestamp": 1634567890
}
}
π‘ Key Conceptsβ
What is Diamond Standard (ERC-2535)?β
The Diamond standard allows for:
- Modularity: Add, replace, or remove functionality without redeploying the entire contract
- Unlimited Contract Size: Bypass the 24KB contract size limit
- Transparent Upgrades: Upgrade contract logic while preserving state
- Gas Efficiency: Share code between contracts to reduce deployment costs
ERC3643 + Diamond Benefitsβ
Combining ERC-3643 with Diamond provides:
- β Full compliance features for tokenized securities
- β Modular architecture for custom compliance rules
- β Future-proof upgradeability
- β Reduced gas costs for complex deployments
β οΈ Important Notesβ
- ERIR Address: The ERIR wallet address must be valid. Use zero address (0x0000000000000000000000000000000000000000) if you don't have one yet.
- Issuer Account: The issuer wallet must be the one signing the EIP712 typed data
- Operator Account: The operator manages daily token operations and can be the same as the issuer
- Max Supply: Define the maximum amount of tokens that can be issued
- Modules: Choose compliance modules that fit your token requirements:
UntransferableModule: Makes tokens non-transferableOnlyIntegerTransferModule: Restricts transfers to whole token amountsUSDCInterestBearingModule: Adds USDC-based interest featuresEUROeInterestBearingModule: Adds EUROe-based interest features
- Signature: The EIP712 signature must be from the issuer account specified in the deployment request
π Related Endpointsβ
π Troubleshootingβ
Deployment Failedβ
If deployment fails, check:
- β ERIR, issuer, and operator addresses are valid Ethereum addresses
- β Selected modules are valid (check available modules list)
- β Max supply is a positive number
- β Sufficient gas is available
- β Issuer account has deployment permissions
Signature Invalidβ
If signature validation fails:
- β Typed data structure matches exactly the response from Step 1
- β Signer address matches the issuer address in the deployment request
- β EIP712 domain parameters are correct (chainId, verifyingContract)
- β The signature was generated using the correct typed data