Aller au contenu

⛓️ Blockchain RPC API

Chains: Ethereum, Polygon, Solana, BSC, Arbitrum
Provider: Infura, Alchemy, QuickNode, Helius (Solana)
Status: 🟢 Ready


Übersicht

Blockchain-Integration für: - NFT-basierte Eigentumsnachweise (Property Tokens) - Smart Contract Verification (Verträge on-chain) - Crypto Payments (Miete in USDC/DAI/SOL) - Document Hashing (Exposé-Integrität) - Solana SPL Tokens (Low-cost Transactions)


Use Cases

Use Case Beschreibung Chain
Property NFTs Tokenisierte Immobilien-Anteile Polygon
Rent Payments Stablecoin-Mietzahlungen Polygon/Ethereum
Document Notarization Hash von Verträgen on-chain Ethereum
Fractional Ownership Bruchteilseigentum Polygon

Endpunkte

Read Operations

Methode Endpunkt Beschreibung Cache TTL
GET /api/blockchain/balance/:address ETH/Token Balance 30s
GET /api/blockchain/nft/:contract/:tokenId NFT Metadata 5 min
GET /api/blockchain/nft/:address/owned Owned NFTs 1 min
GET /api/blockchain/tx/:hash Transaction Details 1 min
GET /api/blockchain/block/latest Latest Block 10s

Contract Calls

Methode Endpunkt Beschreibung Cache TTL
POST /api/blockchain/call Read Contract 30s
GET /api/blockchain/contract/:address/abi Contract ABI 24h
GET /api/blockchain/contract/:address/verified Verification Status 1h

Write Operations

Methode Endpunkt Beschreibung Cache TTL
POST /api/blockchain/tx/send Send Transaction -
POST /api/blockchain/tx/estimate Estimate Gas 30s
GET /api/blockchain/gas/price Gas Price 15s

Document Notarization

Methode Endpunkt Beschreibung Cache TTL
POST /api/blockchain/notarize Hash on-chain speichern -
GET /api/blockchain/notarize/:hash Hash verifizieren 24h

Chain Configuration

const chains = {
  // EVM Chains (Infura)
  ethereum: {
    chainId: 1,
    rpc: 'https://mainnet.infura.io/v3/${INFURA_KEY}',
    explorer: 'https://etherscan.io'
  },
  polygon: {
    chainId: 137,
    rpc: 'https://polygon-mainnet.infura.io/v3/${INFURA_KEY}',
    explorer: 'https://polygonscan.com'
  },
  arbitrum: {
    chainId: 42161,
    rpc: 'https://arbitrum-mainnet.infura.io/v3/${INFURA_KEY}',
    explorer: 'https://arbiscan.io'
  },
  // Solana (Helius/Infura)
  solana: {
    cluster: 'mainnet-beta',
    rpc: 'https://mainnet.helius-rpc.com/?api-key=${HELIUS_KEY}',
    // Alternative: 'https://solana-mainnet.infura.io/v3/${INFURA_KEY}'
    explorer: 'https://solscan.io'
  },
  solanaDevnet: {
    cluster: 'devnet',
    rpc: 'https://devnet.helius-rpc.com/?api-key=${HELIUS_KEY}',
    explorer: 'https://solscan.io?cluster=devnet'
  },
  // Testnets
  sepolia: {
    chainId: 11155111,
    rpc: 'https://sepolia.infura.io/v3/${INFURA_KEY}',
    explorer: 'https://sepolia.etherscan.io'
  }
};

Solana-spezifische Endpunkte

Methode Endpunkt Beschreibung Cache TTL
GET /api/solana/balance/:address SOL Balance 30s
GET /api/solana/tokens/:address SPL Token Balances 30s
GET /api/solana/nft/:mint NFT Metadata (Metaplex) 5 min
GET /api/solana/tx/:signature Transaction Details 1 min
POST /api/solana/tx/send Send Transaction -
GET /api/solana/slot/latest Latest Slot 5s

Solana Request-Beispiel

// GET /api/solana/tokens/7xKXtg2CW87...
const response = await fetch('/api/solana/tokens/7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU');

// Response
{
  "address": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
  "native": {
    "symbol": "SOL",
    "balance": "25.5",
    "usd": "2500.00"
  },
  "tokens": [
    {
      "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      "symbol": "USDC",
      "balance": "5000.00",
      "decimals": 6
    },
    {
      "mint": "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
      "symbol": "USDT",
      "balance": "2500.00",
      "decimals": 6
    }
  ]
}

Request-Beispiele

1. Document Hash speichern

// POST /api/blockchain/notarize
const response = await fetch('/api/blockchain/notarize', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token}`
  },
  body: JSON.stringify({
    documentHash: '0x1234...abcd', // SHA-256 des Dokuments
    documentType: 'PURCHASE_CONTRACT',
    propertyId: 'prop-123',
    chain: 'polygon',
    metadata: {
      parties: ['seller-address', 'buyer-address'],
      timestamp: Date.now()
    }
  })
});

// Response
{
  "success": true,
  "txHash": "0xabc123...",
  "blockNumber": 12345678,
  "chain": "polygon",
  "explorerUrl": "https://polygonscan.com/tx/0xabc123...",
  "gasCost": {
    "eth": "0.001",
    "usd": "2.50"
  }
}

2. Property NFT abrufen

// GET /api/blockchain/nft/0x1234.../42
const response = await fetch('/api/blockchain/nft/0x1234567890abcdef/42');

// Response
{
  "tokenId": "42",
  "contract": "0x1234567890abcdef",
  "owner": "0xowner...",
  "metadata": {
    "name": "Property Token #42 - Musterstraße 1",
    "description": "Fractional ownership of property at Musterstraße 1, Munich",
    "image": "ipfs://QmXyz...",
    "attributes": [
      { "trait_type": "Location", "value": "Munich" },
      { "trait_type": "Size", "value": "150 sqm" },
      { "trait_type": "Share", "value": "1%" },
      { "trait_type": "Annual Yield", "value": "4.5%" }
    ]
  },
  "tokenUri": "ipfs://QmAbc...",
  "chain": "polygon"
}

3. Stablecoin Balance prüfen

// GET /api/blockchain/balance/0xwallet?token=USDC
const response = await fetch('/api/blockchain/balance/0xwallet123?token=USDC&chain=polygon');

// Response
{
  "address": "0xwallet123",
  "chain": "polygon",
  "native": {
    "symbol": "MATIC",
    "balance": "15.5",
    "usd": "12.40"
  },
  "tokens": [
    {
      "symbol": "USDC",
      "contract": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
      "balance": "5000.00",
      "decimals": 6
    },
    {
      "symbol": "DAI",
      "contract": "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
      "balance": "2500.00",
      "decimals": 18
    }
  ]
}

TypeScript Types

interface BlockchainConfig {
  chainId: number;
  name: string;
  rpc: string;
  explorer: string;
  nativeCurrency: { name: string; symbol: string; decimals: number };
}

interface NFTMetadata {
  tokenId: string;
  contract: string;
  owner: string;
  metadata: {
    name: string;
    description: string;
    image: string;
    attributes: { trait_type: string; value: string | number }[];
  };
  tokenUri: string;
  chain: string;
}

interface NotarizeRequest {
  documentHash: string;
  documentType: 'PURCHASE_CONTRACT' | 'LEASE_AGREEMENT' | 'EXPOSE' | 'ENERGY_CERT';
  propertyId?: string;
  chain: 'ethereum' | 'polygon' | 'arbitrum';
  metadata?: Record<string, unknown>;
}

interface NotarizeResult {
  success: boolean;
  txHash: string;
  blockNumber: number;
  chain: string;
  explorerUrl: string;
  gasCost: { eth: string; usd: string };
}

interface TokenBalance {
  symbol: string;
  contract: string;
  balance: string;
  decimals: number;
  usdValue?: string;
}

interface TransactionRequest {
  to: string;
  value?: string;
  data?: string;
  gasLimit?: string;
  chain: string;
}

Smart Contract: PropertyToken (Example)

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract PropertyToken is ERC1155, Ownable {
    struct Property {
        string uri;
        uint256 totalShares;
        uint256 pricePerShare;
        bool active;
    }

    mapping(uint256 => Property) public properties;
    uint256 public propertyCount;

    event PropertyCreated(uint256 indexed tokenId, uint256 totalShares);
    event SharesPurchased(uint256 indexed tokenId, address buyer, uint256 shares);

    function createProperty(
        string memory _uri,
        uint256 _totalShares,
        uint256 _pricePerShare
    ) external onlyOwner returns (uint256) {
        uint256 tokenId = ++propertyCount;
        properties[tokenId] = Property(_uri, _totalShares, _pricePerShare, true);
        _mint(address(this), tokenId, _totalShares, "");
        emit PropertyCreated(tokenId, _totalShares);
        return tokenId;
    }

    function purchaseShares(uint256 _tokenId, uint256 _shares) external payable {
        Property storage prop = properties[_tokenId];
        require(prop.active, "Property not active");
        require(msg.value >= prop.pricePerShare * _shares, "Insufficient payment");

        _safeTransferFrom(address(this), msg.sender, _tokenId, _shares, "");
        emit SharesPurchased(_tokenId, msg.sender, _shares);
    }
}

Rate Limits

Provider Free Tier Paid
Infura 100k/day 10M/day
Alchemy 300M CU/month Unlimited
QuickNode 10M/month Unlimited

Gas Estimation

// Typical gas costs (Polygon)
const gasCosts = {
  notarize: '~50,000 gas (~$0.01)',
  nftTransfer: '~80,000 gas (~$0.02)',
  erc20Transfer: '~65,000 gas (~$0.01)',
  contractDeploy: '~2,000,000 gas (~$0.50)'
};

Infura/Alchemy API Key erforderlich