diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 0000000..f5821e2 --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,39 @@ +name: Documentation + +on: + push: + branches: [ main ] + paths: + - 'contracts/**' + - 'docs/**' + pull_request: + branches: [ main ] + paths: + - 'contracts/**' + - 'docs/**' + +jobs: + verify-docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - name: Generate Documentation + run: cargo doc --no-deps --all-features + + - name: Verify Markdown Links + uses: gaurav-nelson/github-action-markdown-link-check@v1 + with: + use-quiet-mode: 'yes' + use-verbose-mode: 'no' + folder-path: 'docs' + continue-on-error: true + + - name: Archive documentation + uses: actions/upload-artifact@v4 + with: + name: contract-docs + path: target/doc diff --git a/docs/adr/0001-record-architecture-decisions.md b/docs/adr/0001-record-architecture-decisions.md new file mode 100644 index 0000000..7d3bfb3 --- /dev/null +++ b/docs/adr/0001-record-architecture-decisions.md @@ -0,0 +1,27 @@ +# ADR 1: Record Architecture Decisions + +## Status + +Accepted + +## Context + +We need a way to record architectural decisions made during the development of PropChain smart contracts to ensure that current and future developers understand the "why" behind significant design choices. + +## Decision + +We will use Architecture Decision Records (ADRs) to document significant architectural decisions. ADRs will be stored as markdown files in the `docs/adr/` directory. + +Each ADR will follow a standard template: +- **Title**: A descriptive name for the decision. +- **Status**: Proposed, Accepted, Rejected, Deprecated, or Superseded. +- **Context**: The problem we are trying to solve and the requirements. +- **Decision**: The chosen solution and the rationale. +- **Consequences**: The implications of the decision (positive and negative). + +## Consequences + +- Improved transparency in technical decision-making. +- Better onboarding experience for new developers. +- A historical record of how the project evolved. +- Small additional overhead to document decisions. diff --git a/docs/best-practices.md b/docs/best-practices.md new file mode 100644 index 0000000..ee7f030 --- /dev/null +++ b/docs/best-practices.md @@ -0,0 +1,56 @@ +# Developer Best Practices + +Follow these best practices when developing apps that interact with PropChain smart contracts to ensure security, efficiency, and a great user experience. + +## Security First + +### 1. Mandatory Compliance Checks +Always check if a user is compliant before allowing high-value actions. +```rust +// Contract-side enforcement +compliance_registry.require_compliance(caller)?; + +// Frontend-side proactive check +if (!complianceRegistry.isCompliant(userAccount)) { + showComplianceOnboarding(); +} +``` + +### 2. Multi-Signature for Large Transfers +For significant property movements or high-value pool actions, always use the multisig bridge or escrow mechanisms provided. + +### 3. Handle Errors Gracefully +Never assume a contract call will succeed. Always handle potential error types returned by the contracts. + +## Gas Efficiency + +### 1. Batch Operations +When managing multiple properties or performing bulk transfers, use the `safe_batch_transfer_from` method to reduce gas costs compared to individual transactions. + +### 2. Off-Chain Metadata +Store large documents and heavy metadata on IPFS and only store the CID/hash on-chain. Use the `IpfsMetadataRegistry` for managed access. + +### 3. Minimize State Changes +Avoid frequent updates to property metadata. Batch updates if possible or store non-critical information off-chain. + +## User Experience + +### 1. Real-Time Event Monitoring +Subscribe to contract events (like `PropertyTransferred`, `ClaimSubmitted`, `BridgeStatusUpdated`) to provide users with immediate feedback in your application UI. + +### 2. Proactive Troubleshooting +Use the `calculate_premium` or `estimate_bridge_gas` methods to show users expected costs *before* they initiate a transaction. + +### 3. Transparent Status Tracking +For long-running operations like cross-chain bridging or insurance claim assessment, provide a clear status dashboard using the provided monitoring APIs. + +## Code Quality + +### 1. Use Shared Traits +When writing new contracts that interact with PropChain components, use the trait definitions in `contracts/traits` to ensure interface compatibility. + +### 2. Comprehensive Testing +Always write unit tests for your integration logic, specifically mocking different compliance statuses and contract error states. + +### 3. Documentation +Document any custom business logic or contract extensions clearly, following the patterns established in this documentation suite. diff --git a/docs/contracts.md b/docs/contracts.md index 20c315f..3e203ea 100644 --- a/docs/contracts.md +++ b/docs/contracts.md @@ -2,87 +2,160 @@ ## Overview -PropChain smart contracts provide a comprehensive API for real estate tokenization and management on the blockchain. This document outlines the complete contract interface, methods, and data structures. +PropChain smart contracts provide a comprehensive API for real estate tokenization and management on the blockchain. This document outlines the complete contract interface, methods, and data structures for all core system components. ## Core Contracts -### PropertyRegistry +### PropertyToken (ERC-721/1155) -Manages property registration, ownership tracking, and metadata storage. +The primary token contract for property representation, compatible with ERC-721 and ERC-1155 standards, with added real estate specific features and cross-chain support. #### Methods -##### `new()` -Creates a new PropertyRegistry instance. +##### `register_property_with_token(metadata: PropertyMetadata) -> Result` +Registers a property and mints its corresponding ownership token. -```rust -#[ink(constructor)] -pub fn new() -> Self -``` +##### `balance_of(owner: AccountId) -> u32` +Standard ERC-721 balance check. -##### `register_property(metadata: PropertyMetadata) -> Result` -Registers a new property in the registry. +##### `owner_of(token_id: TokenId) -> Option` +Standard ERC-721 owner query. + +##### `transfer_from(from: AccountId, to: AccountId, token_id: TokenId) -> Result<(), Error>` +Standard ERC-721 transfer with property-specific authorization checks. + +##### `safe_batch_transfer_from(from: AccountId, to: AccountId, ids: Vec, amounts: Vec, data: Vec) -> Result<(), Error>` +Standard ERC-1155 batch transfer support. + +##### `attach_legal_document(token_id: TokenId, document_hash: Hash, document_type: String) -> Result<(), Error>` +Attaches a legal document reference (IPFS hash) to a property token. + +##### `verify_compliance(token_id: TokenId, verification_status: bool) -> Result<(), Error>` +Updates the compliance verification status for a token. + +##### `get_ownership_history(token_id: TokenId) -> Option>` +Retrieves the complete on-chain ownership history for a property. + +--- + +### ComplianceRegistry + +Manages user identity verification (KYC), AML checks, and jurisdiction-specific compliance requirements. + +#### Methods + +##### `submit_verification(account: AccountId, jurisdiction: Jurisdiction, kyc_hash: [u8; 32], risk_level: RiskLevel, document_type: DocumentType, biometric_method: BiometricMethod, risk_score: u8) -> Result<()>` +Submits a user for KYC/AML verification. + +##### `is_compliant(account: AccountId) -> bool` +Checks if an account currently meets all compliance requirements (including GDPR consent). + +##### `require_compliance(account: AccountId) -> Result<()>` +Enforces compliance for contract calls. + +##### `update_aml_status(account: AccountId, passed: bool, risk_factors: AMLRiskFactors) -> Result<()>` +Updates the Anti-Money Laundering status for a user. + +##### `update_sanctions_status(account: AccountId, passed: bool, list_checked: SanctionsList) -> Result<()>` +Updates the sanctions screening status. + +##### `update_consent(account: AccountId, consent: ConsentStatus) -> Result<()>` +Manages GDPR data processing consent. + +--- + +### PropertyBridge + +Enables secure cross-chain property token transfers using a multi-signature bridge architecture. + +#### Methods + +##### `initiate_bridge_multisig(token_id: TokenId, destination_chain: ChainId, recipient: AccountId, required_signatures: u8, timeout_blocks: Option, metadata: PropertyMetadata) -> Result` +Initiates a cross-chain transfer request. -**Parameters:** -- `metadata`: Property metadata including location, size, and legal details +##### `sign_bridge_request(request_id: u64, approve: bool) -> Result<(), Error>` +Allows bridge operators to sign/approve a pending request. -**Returns:** -- `PropertyId`: Unique identifier for the registered property -- `Error`: Registration error if property already exists or invalid data +##### `execute_bridge(request_id: u64) -> Result<(), Error>` +Executes the bridge operation once the required signature threshold is met. -##### `transfer_property(property_id: PropertyId, to: AccountId) -> Result<(), Error>` -Transfers ownership of a property to another account. +##### `estimate_bridge_gas(token_id: TokenId, destination_chain: ChainId) -> Result` +Estimates the gas costs for a cross-chain transfer. -**Parameters:** -- `property_id`: ID of the property to transfer -- `to`: Recipient account address +--- -##### `get_property(property_id: PropertyId) -> Option` -Retrieves property information by ID. +### PropertyInsurance -**Parameters:** -- `property_id`: ID of the property to query +A decentralized insurance platform for properties, managing risk pools, premiums, and automated claims. -**Returns:** -- `PropertyInfo`: Property details if found, `None` otherwise +#### Methods + +##### `create_risk_pool(name: String, coverage_type: CoverageType, max_coverage_ratio: u32, reinsurance_threshold: u128) -> Result` +Creates a new insurance risk pool. + +##### `provide_pool_liquidity(pool_id: u64)` +Allows users to provide capital to risk pools and earn rewards. + +##### `calculate_premium(property_id: u64, coverage_amount: u128, coverage_type: CoverageType) -> Result` +Calculates the insurance premium based on property risk assessment. -##### `update_metadata(property_id: PropertyId, metadata: PropertyMetadata) -> Result<(), Error>` -Updates the metadata for a registered property. +##### `create_policy(property_id: u64, coverage_type: CoverageType, coverage_amount: u128, pool_id: u64, duration_seconds: u64, metadata_url: String) -> Result` +Issues a new insurance policy for a property. -**Parameters:** -- `property_id`: ID of the property to update -- `metadata`: New property metadata +--- -##### `approve(property_id: PropertyId, to: Option) -> Result<(), Error>` -Approves an account to transfer a specific property. +### IpfsMetadataRegistry + +Manages property-related documents and metadata stored on IPFS with integrated access control. + +#### Methods -**Parameters:** -- `property_id`: ID of the property -- `to`: Account to approve (Some) or remove approval (None) +##### `validate_and_register_metadata(property_id: u64, metadata: PropertyMetadata) -> Result<(), Error>` +Validates and registers core property metadata. -##### `get_approved(property_id: PropertyId) -> Option` -Gets the approved account for a property. +##### `register_ipfs_document(property_id: u64, ipfs_cid: IpfsCid, document_type: DocumentType, content_hash: Hash, file_size: u64, mime_type: String, is_encrypted: bool) -> Result` +Registers a document stored on IPFS. -**Parameters:** -- `property_id`: ID of the property +##### `grant_access(property_id: u64, account: AccountId, access_level: AccessLevel) -> Result<(), Error>` +Manages document access permissions. -**Returns:** -- `Option`: Approved account if any +--- -### EscrowContract +### ZkCompliance -Handles secure property transfers with escrow protection. +Advanced privacy-preserving compliance using Zero-Knowledge proofs. #### Methods +##### `submit_zk_proof(proof_type: ZkProofType, public_inputs: Vec<[u8; 32]>, proof_data: Vec, metadata: Vec) -> Result` +Submits a ZK proof for verification. + +##### `verify_zk_proof(account: AccountId, proof_id: u64, approve: bool) -> Result<()>` +Verifies a submitted ZK proof. + +##### `anonymous_compliance_check(account: AccountId, required_proof_types: Vec) -> bool` +Performs a compliance check without revealing any sensitive user data. + +--- + +### Legacy Core Contracts (for Reference) + +#### PropertyRegistry +*Note: PropertyToken replaces many of these functions in newer implementations.* + +##### `new()` +Creates a new PropertyRegistry instance. + +##### `register_property(metadata: PropertyMetadata) -> Result` +Registers a new property. + +#### EscrowContract +*Note: AdvancedEscrow features are now integrated into core flows.* + ##### `create_escrow(property_id: PropertyId, buyer: AccountId, amount: Balance) -> Result` Creates a new escrow for property transfer. -##### `release_escrow(escrow_id: EscrowId) -> Result<(), Error>` -Releases escrow funds to the seller. - -##### `refund_escrow(escrow_id: EscrowId) -> Result<(), Error>` -Refunds escrow funds to the buyer. +--- ### PropertyValuationOracle @@ -91,7 +164,7 @@ Provides real-time property valuations using multiple oracle sources with aggreg #### Methods ##### `get_property_valuation(property_id: PropertyId) -> Result` -Gets the current property valuation from aggregated oracle sources. +Gets the current property valuation. ##### `get_valuation_with_confidence(property_id: PropertyId) -> Result` Gets property valuation with confidence metrics including volatility and confidence intervals. @@ -99,21 +172,6 @@ Gets property valuation with confidence metrics including volatility and confide ##### `update_valuation_from_sources(property_id: PropertyId) -> Result<(), OracleError>` Updates property valuation by aggregating prices from all active oracle sources. -##### `get_historical_valuations(property_id: PropertyId, limit: u32) -> Vec` -Retrieves historical valuations for a property (most recent first). - -##### `get_market_volatility(property_type: PropertyType, location: String) -> Result` -Gets market volatility metrics for specific property types and locations. - -##### `set_price_alert(property_id: PropertyId, threshold_percentage: u32, alert_address: AccountId) -> Result<(), OracleError>` -Sets up price change alerts for property valuation monitoring. - -##### `add_oracle_source(source: OracleSource) -> Result<(), OracleError>` (Admin only) -Adds a new oracle source for price feeds (Chainlink, Pyth, Custom). - -##### `get_comparable_properties(property_id: PropertyId, radius_km: u32) -> Vec` -Gets comparable properties within a specified radius for AVM analysis. - ## Data Structures ### PropertyMetadata @@ -127,268 +185,187 @@ pub struct PropertyMetadata { } ``` -### PropertyInfo +### OwnershipTransfer ```rust -pub struct PropertyInfo { - pub id: PropertyId, - pub owner: AccountId, - pub metadata: PropertyMetadata, - pub registered_at: Timestamp, +pub struct OwnershipTransfer { + pub from: AccountId, + pub to: AccountId, + pub timestamp: u64, + pub transaction_hash: Hash, } ``` -### EscrowInfo +### ComplianceData ```rust -pub struct EscrowInfo { - pub id: EscrowId, - pub property_id: PropertyId, - pub seller: AccountId, - pub buyer: AccountId, - pub amount: Balance, - pub status: EscrowStatus, - pub created_at: Timestamp, +pub struct ComplianceData { + pub status: VerificationStatus, + pub jurisdiction: Jurisdiction, + pub risk_level: RiskLevel, + pub verification_timestamp: Timestamp, + pub expiry_timestamp: Timestamp, + pub kyc_hash: [u8; 32], + pub aml_checked: bool, + pub sanctions_checked: bool, + pub document_type: DocumentType, + pub biometric_method: BiometricMethod, + pub risk_score: u8, } ``` -### Property Valuation Structures - -#### PropertyValuation +### InsurancePolicy ```rust -pub struct PropertyValuation { +pub struct InsurancePolicy { + pub policy_id: u64, pub property_id: u64, - pub valuation: u128, // Current valuation in USD with 8 decimals - pub confidence_score: u32, // Confidence score 0-100 - pub sources_used: u32, // Number of price sources used - pub last_updated: u64, // Last update timestamp - pub valuation_method: ValuationMethod, + pub policyholder: AccountId, + pub coverage_type: CoverageType, + pub coverage_amount: u128, + pub premium_amount: u128, + pub deductible: u128, + pub start_time: u64, + pub end_time: u64, + pub status: PolicyStatus, } ``` -#### ValuationWithConfidence +### IpfsDocument ```rust -pub struct ValuationWithConfidence { - pub valuation: PropertyValuation, - pub volatility_index: u32, // Market volatility 0-100 - pub confidence_interval: (u128, u128), // Min and max valuation range - pub outlier_sources: u32, // Number of outlier sources detected +pub struct IpfsDocument { + pub document_id: u64, + pub property_id: u64, + pub ipfs_cid: String, + pub document_type: DocumentType, + pub content_hash: Hash, + pub file_size: u64, + pub uploader: AccountId, + pub uploaded_at: u64, } ``` -#### PriceData +### ZkProofData ```rust -pub struct PriceData { - pub price: u128, // Price in USD with 8 decimals - pub timestamp: u64, // Timestamp when price was recorded - pub source: String, // Price feed source identifier +pub struct ZkProofData { + pub proof_type: ZkProofType, + pub status: ZkProofStatus, + pub public_inputs: Vec<[u8; 32]>, + pub proof_data: Vec, + pub created_at: Timestamp, + pub expires_at: Timestamp, } ``` -#### VolatilityMetrics -```rust -pub struct VolatilityMetrics { - pub property_type: PropertyType, - pub location: String, - pub volatility_index: u32, // 0-100 scale - pub average_price_change: i32, // Average % change over period - pub period_days: u32, // Analysis period in days - pub last_updated: u64, -} -``` +### Property Valuation Structures -#### ComparableProperty +#### PropertyValuation ```rust -pub struct ComparableProperty { +pub struct PropertyValuation { pub property_id: u64, - pub distance_km: u32, // Distance from subject property - pub price_per_sqm: u128, // Price per square meter - pub size_sqm: u64, // Property size in square meters - pub sale_date: u64, // When it was sold - pub adjustment_factor: i32, // Adjustment factor (+/- percentage) + pub valuation: u128, // Current valuation in USD with 8 decimals + pub confidence_score: u32, // Confidence score 0-100 + pub sources_used: u32, // Number of price sources used + pub last_updated: u64, // Last update timestamp + pub valuation_method: ValuationMethod, } ``` ## Error Types -### Property Registry Errors +### Standard Token Errors ```rust pub enum Error { - PropertyNotFound, + TokenNotFound, Unauthorized, + PropertyNotFound, InvalidMetadata, - EscrowNotFound, - InsufficientBalance, - TransferFailed, + ComplianceFailed, + BridgePaused, + InsufficientSignatures, } ``` -### Oracle Errors +### Compliance Errors ```rust -pub enum OracleError { - PropertyNotFound, - InsufficientSources, - InvalidValuation, - Unauthorized, - OracleSourceNotFound, - InvalidParameters, - PriceFeedError, - AlertNotFound, +pub enum ComplianceError { + NotAuthorized, + NotVerified, + VerificationExpired, + HighRisk, + JurisdictionNotSupported, + ConsentNotGiven, } ``` -## Events - -#[ink(event)] -pub struct PropertyRegistered { - #[ink(topic)] - property_id: PropertyId, - #[ink(topic)] - owner: AccountId, - version: u8, -} - -#[ink(event)] -pub struct PropertyTransferred { - #[ink(topic)] - property_id: PropertyId, - #[ink(topic)] - from: AccountId, - #[ink(topic)] - to: AccountId, -} - -#[ink(event)] -pub struct PropertyMetadataUpdated { - #[ink(topic)] - property_id: PropertyId, - metadata: PropertyMetadata, -} - -#[ink(event)] -pub struct Approval { - #[ink(topic)] - property_id: PropertyId, - #[ink(topic)] - owner: AccountId, - #[ink(topic)] - approved: AccountId, -} - -#[ink(event)] -pub struct EscrowCreated { - #[ink(topic)] - escrow_id: EscrowId, - property_id: PropertyId, - amount: Balance, -} - -#[ink(event)] -pub struct ValuationUpdated { - #[ink(topic)] - property_id: u64, - valuation: u128, - confidence_score: u32, - timestamp: u64, -} - -#[ink(event)] -pub struct PriceAlertTriggered { - #[ink(topic)] - property_id: u64, - old_valuation: u128, - new_valuation: u128, - change_percentage: u32, - alert_address: AccountId, -} - -#[ink(event)] -pub struct OracleSourceAdded { - #[ink(topic)] - source_id: String, - source_type: OracleSourceType, - weight: u32, +### Insurance Errors +```rust +pub enum InsuranceError { + PolicyNotFound, + ClaimNotFound, + InsufficientPremium, + InsufficientPoolFunds, + OracleVerificationFailed, + PropertyNotInsurable, } ``` ## Usage Examples -### Registering a Property +### Registering a Property Token ```rust let metadata = PropertyMetadata { location: "123 Main St, City, State".to_string(), size: 2000, legal_description: "Lot 1, Block 2".to_string(), valuation: 500000, - documents_url: "https://ipfs.io/...".to_string(), + documents_url: "ipfs://Qm...".to_string(), }; -let property_id = contract.register_property(metadata)?; +let token_id = property_token.register_property_with_token(metadata)?; ``` -### Creating an Escrow +### Initiating a Cross-Chain Transfer ```rust -let escrow_id = escrow_contract.create_escrow( - property_id, - buyer_account, - 500000 +let request_id = bridge.initiate_bridge_multisig( + token_id, + destination_chain_id, + recipient_account, + 2, // required signatures + Some(100), // timeout blocks + metadata )?; ``` -### Using the Property Valuation Oracle - -#### Getting Property Valuation +### Creating an Insurance Policy ```rust -// Get current property valuation -let valuation = oracle.get_property_valuation(property_id)?; - -// Get valuation with confidence metrics -let valuation_with_confidence = oracle.get_valuation_with_confidence(property_id)?; -println!("Valuation: ${}", valuation_with_confidence.valuation.valuation); -println!("Confidence: {}%", valuation_with_confidence.valuation.confidence_score); -println!("Volatility: {}%", valuation_with_confidence.volatility_index); -``` - -#### Setting Up Price Alerts -```rust -// Set up 5% price change alert -oracle.set_price_alert(property_id, 5, alert_recipient_address)?; +let policy_id = insurance.create_policy( + property_id, + CoverageType::Comprehensive, + 500000, // coverage amount + pool_id, + 31536000, // 1 year in seconds + "https://metadata.url".to_string() +)?; ``` -#### Adding Oracle Sources +### Verifying Compliance with ZK Proofs ```rust -// Add Chainlink price feed (admin only) -let chainlink_source = OracleSource { - id: "chainlink_usd_feed".to_string(), - source_type: OracleSourceType::Chainlink, - address: chainlink_feed_address, - is_active: true, - weight: 60, - last_updated: timestamp, -}; -oracle.add_oracle_source(chainlink_source)?; +let is_compliant = zk_compliance.anonymous_compliance_check( + user_account, + vec![ZkProofType::IdentityVerification, ZkProofType::FinancialStanding] +); ``` -#### Getting Market Analytics -```rust -// Get market volatility for residential properties in NYC -let volatility = oracle.get_market_volatility( - PropertyType::Residential, - "NYC".to_string() -)?; - -// Get comparable properties within 5km -let comparables = oracle.get_comparable_properties(property_id, 5); -``` +--- ## Gas Optimization Tips 1. Use efficient data structures (e.g., `Mapping` over `Vec`) -2. Batch operations when possible +2. Batch operations when possible (use `safe_batch_transfer_from`) 3. Minimize storage writes 4. Use appropriate visibility modifiers ## Security Considerations 1. Always validate input parameters -2. Implement proper access control -3. Use reentrancy guards where applicable -4. Consider gas limits for loops +2. Implement proper access control using `require_compliance` +3. Use multi-signature verification for high-value operations (Bridge, Escrow) +4. Monitor contract events for anomalies diff --git a/docs/onboarding-checklist.md b/docs/onboarding-checklist.md new file mode 100644 index 0000000..b4eeb41 --- /dev/null +++ b/docs/onboarding-checklist.md @@ -0,0 +1,38 @@ +# Developer Onboarding Checklist + +Welcome to the PropChain development team! Use this checklist to set up your environment and get familiar with our smart contract ecosystem. + +## Environment Setup + +- [ ] **Install Rust**: Follow the instructions in [DEVELOPMENT.md](../DEVELOPMENT.md) to install the Rust toolchain. +- [ ] **Install Substrate Tools**: Ensure you have `cargo-contract` and other necessary Substrate development tools. +- [ ] **Clone the Repository**: `git clone https://github.com/maryjane/PropChain-contract.git` +- [ ] **Verify Build**: Run `cargo build` in the root directory to ensure all contracts compile correctly. +- [ ] **Run Tests**: Run `cargo test` to verify the current state of the codebase. + +## Learning the Architecture + +- [ ] **Read the Overview**: Start with the [README.md](../README.md) for a high-level project summary. +- [ ] **Explore the Contracts**: Read [docs/contracts.md](contracts.md) to understand the core APIs. +- [ ] **Review Tutorials**: + - [ ] [Insurance Integration](tutorials/insurance-integration.md) + - [ ] [Cross-Chain Bridging](tutorials/cross-chain-bridging.md) +- [ ] **Understand Compliance**: Study the `ComplianceRegistry` and `ZkCompliance` contracts to understand how we handle regulatory requirements. + +## Hands-On Exploration + +- [ ] **Deploy to Local Node**: Follow the deployment guide in [DEVELOPMENT.md](../DEVELOPMENT.md) to deploy the `PropertyToken` contract to a local dev node. +- [ ] **Interact with Contracts**: Use the `polkadot-js/api` or `subxt` to call a simple method like `register_property`. +- [ ] **Debug a Transaction**: Use the local node logs to trace a contract call. + +## Contributing + +- [ ] **Read Contribution Guidelines**: Review the guidelines in [README.md](../README.md#contributing). +- [ ] **Setup Pre-commit Hooks**: Follow the instructions in [DEVELOPMENT.md](../DEVELOPMENT.md#pre-commit-hooks). +- [ ] **Create a Feature Branch**: Always work on a separate branch for your changes. +- [ ] **Follow ADRs**: Check existing [Architecture Decision Records](adr/) before making major design choices. + +## Getting Help + +- [ ] **Review FAQ**: Check the [Troubleshooting/FAQ](troubleshooting-faq.md) for common issues. +- [ ] **Join the Dev Channel**: Reach out to the team on our designated discord/slack channel for support. diff --git a/docs/troubleshooting-faq.md b/docs/troubleshooting-faq.md new file mode 100644 index 0000000..11f1291 --- /dev/null +++ b/docs/troubleshooting-faq.md @@ -0,0 +1,55 @@ +# Troubleshooting and FAQ + +This document provides solutions to common issues and answers to frequently asked questions for developers working with PropChain smart contracts. + +## Common Issues + +### 1. Compliance Verification Failure +**Issue:** Submitting a transaction returns `ComplianceFailed` or `ComplianceError::NotVerified`. +**Solution:** +- Ensure the account has undergone KYC/AML verification via the `ComplianceRegistry`. +- Check if the verification has expired using `get_compliance_data`. +- Verify that GDPR consent has been granted via `update_consent`. + +### 2. Bridge Request Timeout +**Issue:** A bridge request has not been executed and the timeout has passed. +**Solution:** +- Bridge operators may be offline or experiencing high network congestion. +- Use `recover_failed_bridge` with `RecoveryAction::UnlockToken` to retrieve your token on the source chain. +- Try re-initiating the bridge with a higher gas estimate or longer timeout. + +### 3. "InsufficientSignatures" Error on Bridge Execution +**Issue:** Calling `execute_bridge` fails with `InsufficientSignatures`. +**Solution:** +- Verify that the required number of bridge operators have signed the request using `monitor_bridge_status`. +- Wait for more signatures if the threshold has not been met. + +### 4. IPFS CID Validation Error +**Issue:** Registering metadata or documents fails with `InvalidIpfsCid`. +**Solution:** +- Ensure the CID format is correct (CIDv0 starts with "Qm", CIDv1 starts with "b"). +- Check if the CID string is exactly 46 characters for CIDv0. + +### 5. Insurance Premium Calculation Discrepancy +**Issue:** The premium calculated off-chain doesn't match the on-chain value. +**Solution:** +- Ensure you are using the exact same risk assessment parameters. +- Check if the `PropertyValuation` has updated since the last calculation. +- On-chain premium calculation factors in real-time pool utilization and reinsurance costs. + +## Frequently Asked Questions + +### Q: Which standards are PropChain tokens compatible with? +A: PropChain property tokens are natively compatible with both ERC-721 (for unique property ownership) and ERC-1155 (for fractionalized or batch operations). + +### Q: How is data privacy handled for compliance? +A: We use a combination of encrypted data hashes in the `ComplianceRegistry` and private Zero-Knowledge proofs in `ZkCompliance` to ensure regulatory requirements are met without exposing sensitive personal information on-chain. + +### Q: Can a property be un-tokenized? +A: Yes, if the business logic allows, a token can be burned, and the property status can be updated to "Unlisted" or "Private" in the registry, effectively removing it from the blockchain lifecycle. + +### Q: What happens if a bridge operator is malicious? +A: The bridge uses a multi-signature threshold. A single malicious operator cannot compromise a bridge request. Operators are authorized through a governance process and can be removed/slashed for bad behavior. + +### Q: How often are property valuations updated? +A: Valuations depend on the `PropertyValuationOracle` configuration. High-volatility markets may have daily updates, while stable assets might be updated monthly or upon request. diff --git a/docs/tutorials/cross-chain-bridging.md b/docs/tutorials/cross-chain-bridging.md new file mode 100644 index 0000000..f864b66 --- /dev/null +++ b/docs/tutorials/cross-chain-bridging.md @@ -0,0 +1,82 @@ +# Tutorial: Cross-Chain Property Bridging + +This tutorial explains how to move property tokens between supported blockchain networks using the PropChain multi-signature bridge. + +## Prerequisites + +- Property token owned on the source chain. +- Sufficient gas for the operation (estimate using `estimate_bridge_gas`). +- Knowledge of the destination chain ID. + +## 1. Estimating Gas Costs + +Before initiating a bridge, it is recommended to estimate the gas costs on the destination chain. + +```rust +let gas_estimate = bridge.estimate_bridge_gas(token_id, destination_chain_id)?; +println!("Estimated destination gas: {} units", gas_estimate); +``` + +## 2. Initiating the Bridge Request + +The bridging process starts with a multisig request. You specify the token, destination, recipient, and the required number of operator signatures. + +```rust +let request_id = bridge.initiate_bridge_multisig( + token_id, + destination_chain_id, + recipient_account, + 2, // Require 2 operator signatures + Some(100), // Timeout after 100 blocks + metadata // Property metadata (for recursive minting) +)?; +``` + +The property token will be **locked** on the source chain during this process. + +## 3. Signature Collection + +Bridge operators (monitored by off-chain services) will verify the request and provide signatures. + +```rust +// This is typically done by authorized operators +bridge.sign_bridge_request(request_id, true)?; +``` + +## 4. Executing the Bridge + +Once the signature threshold is reached, the bridge can be executed to finalize the transfer. + +```rust +bridge.execute_bridge(request_id)?; +``` + +Upon execution, the token will be minted on the destination chain with the preserved metadata. + +## 5. Monitoring Status + +You can track the progress of your bridge operation. + +```rust +let info = bridge.monitor_bridge_status(request_id).unwrap(); +match info.status { + BridgeOperationStatus::Completed => println!("Bridge successful!"), + BridgeOperationStatus::Pending => println!("Needs {} more signatures", info.signatures_required - info.signatures_collected), + BridgeOperationStatus::Failed => println!("Bridge failed: {}", info.error_message.unwrap_or_default()), + _ => println!("Bridge in transit..."), +} +``` + +## 6. Recovery from Failure + +If a bridge request expires or fails, the token can be recovered on the source chain. + +```rust +bridge.recover_failed_bridge(request_id, RecoveryAction::UnlockToken)?; +``` + +## Best Practices + +- Always check `is_bridge_operator` if you are implementing an operator service. +- Set reasonable `timeout_blocks` to prevent forever-locked tokens in case of network issues. +- Use `get_bridge_history` to provide users with a history of their cross-chain transfers. diff --git a/docs/tutorials/insurance-integration.md b/docs/tutorials/insurance-integration.md new file mode 100644 index 0000000..76663cd --- /dev/null +++ b/docs/tutorials/insurance-integration.md @@ -0,0 +1,94 @@ +# Tutorial: Integrating with PropChain Insurance + +This tutorial guides you through the process of integrating your application with the PropChain decentralized insurance platform. + +## Prerequisites + +- Access to a Substrate-based network with PropChain contracts deployed. +- Familiarity with the `PropertyInsurance` contract API. +- A property already registered in the `PropertyToken` contract. + +## 1. Risk Assessment and Premium Calculation + +Before creating a policy, you should calculate the expected premium for the property. + +```rust +// Parameters: property_id, coverage_amount, coverage_type +let premium_calc = insurance.calculate_premium( + property_id, + 500000, // $500,000 coverage + CoverageType::Comprehensive +)?; + +println!("Estimated Premium: ${}", premium_calc.premium_amount); +println!("Deductible: ${}", premium_calc.deductible); +``` + +## 2. Selecting a Risk Pool + +Insurance policies are backed by risk pools. You must select an appropriate pool for your coverage type. + +```rust +// List available risk pools for Comprehensive coverage +let pools = insurance.get_pools_by_coverage(CoverageType::Comprehensive); +let pool_id = pools[0].id; +``` + +## 3. Creating an Insurance Policy + +Once the premium is calculated and a pool is selected, you can issue the policy. + +```rust +let policy_id = insurance.create_policy( + property_id, + CoverageType::Comprehensive, + 500000, + pool_id, + 31536000, // 1 year in seconds + "ipfs://Qm...metadata" +)?; +``` + +Note: The user must have sufficient balance to pay the `premium_amount`. + +## 4. Submitting a Claim + +In the event of a covered loss, a claim can be submitted for the policy. + +```rust +let claim_id = insurance.submit_claim( + policy_id, + 10000, // Claim amount: $10,000 + "Fire damage in the kitchen", + "ipfs://Qm...incident_report" +)?; +``` + +## 5. Claim Processing and Payout + +Claims go through an assessment process (managed by automated oracles or authorized assessors). Once approved, the payout is processed automatically. + +```rust +// Monitor claim status +let claim = insurance.get_claim(claim_id).unwrap(); +match claim.status { + ClaimStatus::Approved => println!("Claim approved, payout incoming!"), + ClaimStatus::Rejected => println!("Claim rejected: {}", claim.rejection_reason), + _ => println!("Claim pending assessment"), +} +``` + +## 6. Providing Liquidity (Optional) + +Users can also participate as liquidity providers for risk pools to earn premiums. + +```rust +// Deposit 10,000 tokens into the risk pool +insurance.provide_pool_liquidity(pool_id, 10000)?; +``` + +## Best Practices + +- Always verify the `PropertyValuation` before setting coverage amounts. +- Ensure the policy duration aligns with the property's legal registration period. +- Regularly monitor `ClaimSubmitted` events for real-time tracking.