Integra Architecture for Developers
Integra Architecture for Developers
Section titled “Integra Architecture for Developers”Understanding how Integra’s smart contracts work together to enable document tokenization and management.
Overview
Section titled “Overview”Integra provides a layered architecture for tokenizing real-world documents on the blockchain, enabling developers to build applications that bridge traditional legal agreements with decentralized finance and NFT ecosystems. The system’s modular design separates concerns across distinct layers, with immutable foundation contracts providing security and identity, a flexible application layer handling tokenization and communication, and extensible resolver patterns enabling custom business logic without modifying core infrastructure. As a developer, you’ll interact with contracts across different layers depending on your use case, from simple document registration to complex multi-party agreements with automated workflows.
Integra’s unique architecture permanently binds ERC tokens to real-world documents through a two-layer system that combines the Document Registry Layer for immutable document identity with cryptographic proof of content, and the Tokenizer Layer for standard ERC tokens (ERC-721, ERC-1155, ERC-20) that are cryptographically bound to document identity. This fundamental innovation means that tokens aren’t just NFTs with metadata - they’re cryptographically verifiable representations of real-world assets such as property deeds, rental agreements, and business contracts that work seamlessly with any ERC-compatible wallet, marketplace, or DeFi protocol while maintaining permanent linkage to their source documents. The bidirectional binding ensures every token knows its document and every document knows its token(s), creating an immutable audit trail that proves ownership and authenticity.
Contract Layers
Section titled “Contract Layers”Foundation Layer: Core Registries
Section titled “Foundation Layer: Core Registries”These immutable contracts provide the security and capability framework. You’ll reference these when verifying permissions and looking up components.
Key Contracts:
- CapabilityNamespace_Immutable - Defines permission capabilities (CORE_CLAIM, CORE_TRANSFER, etc.)
- IntegraRegistry_Immutable - Unified registry for all infrastructure components:
- PROVIDER type: Attestation providers (EAS, VC, ZK, DIDs)
- VERIFIER type: ZK proof verifiers (Groth16, PLONK, Poseidon)
- RESOLVER type: Document resolvers (lifecycle, compliance, custom)
- TOKENIZER type: Token implementations (registered for validation)
When you’ll use them:
- Checking if a user has specific capabilities
- Looking up attestation providers, verifiers, resolvers, or tokenizers
- Registering custom components
- Validating component authenticity via code hash verification
Document Layer: Identity & Services
Section titled “Document Layer: Identity & Services”These contracts manage document identity and attach services to documents.
Key Contracts:
- IntegraDocumentRegistry_Immutable - Core document registry (one per chain)
- TokenClaimResolver - Validates token claim attestations (prevents unauthorized claims)
- SimpleContactResolver - Encrypted contact information resolver
When you’ll use them:
- Registering new documents
- Querying document ownership
- Creating claim attestations for token recipients
- Adding resolvers to documents
Application Layer: Tokenization & Communication
Section titled “Application Layer: Tokenization & Communication”These are the contracts you’ll interact with most frequently.
Tokenizer Contracts (11 types):
- OwnershipTokenizer - Simple NFT ownership
- RentalTokenizer - Rental agreements with expiration
- SharesTokenizer - Fractional ownership
- RoyaltyTokenizer - Revenue sharing
- MultiPartyTokenizer - Multi-party agreements
- And 6 more specialized tokenizers
Communication Contracts:
- IntegraMessage - Document-related messaging
- IntegraSignal - Payment requests and signals
Execution Contracts:
- IntegraExecutor - Gasless meta-transactions
When you’ll use them:
- Minting tokens for documents
- Transferring ownership
- Handling rental payments
- Distributing royalties
- Sending messages between parties
How Contracts Work Together
Section titled “How Contracts Work Together”Document Registration Flow
Section titled “Document Registration Flow”// 1. User registers a documentIntegraDocumentRegistry.registerDocument( documentHash, // SHA-256 of document referenceHash, // IPFS CID or other reference tokenizer, // Which tokenizer to use executor, // For gasless transactions processHash, // Workflow identifier identityExtension, // Additional identity data primaryResolverId, // Main resolver additionalResolvers // Extra resolvers)
// Returns: integraHash (unique document ID)What happens:
- Document Registry validates inputs
- Generates unique
integraHashfor the document - Stores document metadata on-chain
- Calls resolver hooks if configured
- Emits
DocumentRegisteredevent
Token Claim Flow
Section titled “Token Claim Flow”// 1. User claims a token for a registered documentOwnershipTokenizer.claimToken( integraHash, // Document ID tokenId, // Token number attestationUID, // Proof of permission (from EAS) processHash // Workflow context)What happens:
- Tokenizer verifies the document uses this tokenizer
- Checks if caller has permission via attestation
- Validates attestation through AttestationProvider
- Mints NFT to claimant
- Emits
TokenClaimedevent
Attestation Verification
Section titled “Attestation Verification”All privileged operations require attestations (cryptographic proofs of permission):
// Modifier used internallymodifier requiresCapability(bytes32 integraHash, bytes32 capability) { // 1. Get attestation provider for this document // 2. Verify attestation proves the capability // 3. Revert if verification fails _;}What this means for you:
- Users need valid attestations to claim tokens, transfer, etc.
- Attestations are issued off-chain by authorized issuers
- Attestations contain capability bits (what the user can do)
- You’ll use the Integra API to request attestations for users
Common Development Patterns
Section titled “Common Development Patterns”Pattern 1: Simple Document Registration
Section titled “Pattern 1: Simple Document Registration”// Minimal document registrationbytes32 integraHash = documentRegistry.registerDocument( keccak256(documentContent), // Document hash ipfsCid, // Reference to full document address(ownershipTokenizer), // Use ownership tokenizer address(0), // No executor needed bytes32(0), // No process bytes32(0), // No identity extension bytes32(0), // No primary resolver new bytes32[](0) // No additional resolvers);Pattern 2: Document with Resolver
Section titled “Pattern 2: Document with Resolver”// Register document with contact resolverbytes32 integraHash = documentRegistry.registerDocument( documentHash, referenceHash, address(ownershipTokenizer), address(0), bytes32(0), bytes32(0), CONTACT_RESOLVER_ID, // Primary resolver new bytes32[](0));
// Now users can look up contact info via unified registryaddress contactResolver = integraRegistry.getComponent(CONTACT_RESOLVER_ID);bytes memory contactData = IDocumentResolver(contactResolver).resolve(integraHash);Pattern 3: Rental Token
Section titled “Pattern 3: Rental Token”// Use rental tokenizer for subscription/rentalRentalTokenizer rentalTokenizer = RentalTokenizer(tokenizerAddress);
// Pay rent (tenant calls this monthly)rentalTokenizer.payRent{value: monthlyRent}(tokenId);
// Check if rental is activebool isActive = rentalTokenizer.isRentalActive(tokenId);if (isActive) { // Grant access to tenant}Pattern 4: Royalty Distribution
Section titled “Pattern 4: Royalty Distribution”// Use royalty tokenizer for revenue sharingRoyaltyTokenizer royaltyTokenizer = RoyaltyTokenizer(tokenizerAddress);
// Distribute revenue to token holdersroyaltyTokenizer.distributeRoyalties{value: revenue}(integraHash);
// Token holders can claim their shareuint256 pending = royaltyTokenizer.pendingRoyalties(tokenHolder);if (pending > 0) { royaltyTokenizer.claimRoyalties();}Pattern 5: Multi-Party Agreement
Section titled “Pattern 5: Multi-Party Agreement”// Use multi-party tokenizer for contracts with multiple partiesMultiPartyTokenizer multiParty = MultiPartyTokenizer(tokenizerAddress);
// Each party claims their tokenmultiParty.claimToken(integraHash, tokenId1, attestationUID1, processHash);multiParty.claimToken(integraHash, tokenId2, attestationUID2, processHash);
// Check if all parties have claimeduint256 partiesClaimed = multiParty.getClaimedParties(integraHash);uint256 requiredParties = multiParty.getRequiredParties(integraHash);
if (partiesClaimed == requiredParties) { // Agreement fully executed // Trust credentials issued automatically}Pattern 6: Token Claim Attestations with TokenClaimResolver
Section titled “Pattern 6: Token Claim Attestations with TokenClaimResolver”// Use TokenClaimResolver for secure, gas-efficient claim attestations
// 1. As document owner, create a claim attestationIEAS eas = IEAS(easAddress);
bytes memory attestationData = abi.encode( integraHash, tokenId, 1 << 1 // CAPABILITY_CLAIM_TOKEN);
AttestationRequest memory request = AttestationRequest({ schema: claimSchemaUID, // Schema using TokenClaimResolver data: AttestationRequestData({ recipient: userAddress, // Who can claim expirationTime: 0, // No expiration revocable: true, // Can be revoked refUID: bytes32(0), data: attestationData, value: 0 })});
bytes32 attestationUID = eas.attest(request);// TokenClaimResolver validates BEFORE creating the attestation// Only valid attestations get created
// 2. User claims with the pre-validated attestationtokenizer.claimToken(integraHash, tokenId, attestationUID, processHash);// Cheaper gas cost because attestation is already validatedBenefits:
- Security: Only document owners/executors can create claim attestations
- Gas Efficiency: 30-50% cheaper claims (validation happens once, not per claim)
- Clean System: Invalid attestations never get created
See: TokenClaimResolver Documentation
Key Concepts for Developers
Section titled “Key Concepts for Developers”1. IntegraHash
Section titled “1. IntegraHash”Every document gets a unique integraHash identifier:
integraHash = keccak256(abi.encodePacked( documentHash, referenceHash, msg.sender, block.timestamp));Use this hash to reference documents across all contracts.
2. Capabilities
Section titled “2. Capabilities”Permissions are represented as bit flags:
bytes32 CORE_CLAIM = 0x0000...0001; // Can claim tokensbytes32 CORE_TRANSFER = 0x0000...0002; // Can transferbytes32 CORE_REVOKE = 0x0000...0004; // Can revokebytes32 CORE_ADMIN = 0x8000...0000; // Admin (has all)Attestations grant one or more capabilities.
3. Attestations
Section titled “3. Attestations”Cryptographic proofs issued by authorized parties:
// Attestation contains:- schema: Which capability schema- recipient: Who receives the capability- data: Capability bits + document hash- expirationTime: When it expires- revocable: Can it be revokedYou’ll get attestations via the Integra API, not by calling contracts directly.
4. Resolvers
Section titled “4. Resolvers”Services that attach to documents:
interface IDocumentResolver { function resolve(bytes32 integraHash) external view returns (bytes memory);}Create custom resolvers to add functionality without modifying core contracts.
Integration Checklist
Section titled “Integration Checklist”When integrating with Integra:
- Understand your use case - Which tokenizer fits your needs?
- Get contract addresses - Use the chain registry or documentation
- Set up attestation issuance - Integrate with Integra API for attestations
- Handle events - Listen for DocumentRegistered, TokenClaimed, etc.
- Test on testnet first - Deploy to Polygon Amoy or Base Sepolia
- Implement error handling - Handle reverts gracefully
- Monitor gas costs - Batch operations when possible
Contract Addresses
Section titled “Contract Addresses”Use the Integra Chain Registry to get current contract addresses:
import { Tabs } from ‘nextra/components’
<Tabs items={[‘curl’, ‘TypeScript’, ‘Python’]}>
<Tabs.Tab>
bash # Get contract addresses for a specific chain curl https://integra-chain-registry-worker.dfisher-3f3.workers.dev/v1/chains/polygon/contracts
</Tabs.Tab>
<Tabs.Tab>
```typescript
// Via API
const addresses = await fetch(
‘https://integra-chain-registry-worker.dfisher-3f3.workers.dev/v1/chains/polygon/contracts’
).then(r => r.json());
// Or via SDKimport { getContractAddresses } from '@integra/sdk';const addresses = await getContractAddresses('polygon');```</Tabs.Tab> <Tabs.Tab> ```python import requests
# Get contract addresses for a specific chainresponse = requests.get( 'https://integra-chain-registry-worker.dfisher-3f3.workers.dev/v1/chains/polygon/contracts')addresses = response.json()
# Or using the SDK (if available)# from integra_sdk import get_contract_addresses# addresses = get_contract_addresses('polygon')```</Tabs.Tab>
Next Steps
Section titled “Next Steps”- Integration Guide → - Step-by-step integration instructions
- Testing Guide → - How to test your integration
- Security Guide → - Security best practices
- Tokenizer Comparison → - Choose the right tokenizer
Need Help?
Section titled “Need Help?”- Documentation: You’re here!
- Examples: Check the integration guide for code samples
- Support: security@integra.io