Docs / Getting Started

Getting Started

Everything you need to install, configure, and run ChainEstate locally β€” or just use the live app on Arbitrum Sepolia right now.

Option A β€” Use the Live App

No setup needed. Everything is already deployed on Arbitrum Sepolia.

1

Open the live app

Go to chain-estate-rouge.vercel.app

2

Connect MetaMask

Click "Connect Wallet" β€” MetaMask will prompt you to switch to Arbitrum Sepolia (chainId 421614). The app adds the network automatically.

3

Get ETH for gas

Need Sepolia ETH first? Claim from Google Cloud Web3 Faucet β†’ bridge to Arbitrum Sepolia via portal.arbitrum.io.

4

Claim testnet tokens

Visit /faucet β€” claim 1,000 USDT and 2,400 CEST. One claim per address per 24h.

5

Buy a property token

Go to /properties β†’ pick a property β†’ enter amount β†’ click "πŸ”’ Encrypt & Buy with USDT". The iExec TEE task runs automatically.

Option B β€” Run Locally

Prerequisites

Node.js20+node --version
npm10+npm --version
MetaMaskBrowser extensionmetamask.io
Arbitrum Sepolia ETHFor gas feesGoogle Cloud Faucet β†’ Arbitrum Bridge

1. Clone & Install

git clone https://github.com/ntfound-dev/ChainEstate-
cd ChainEstate
npm install

2. Environment Variables

cp .env.example .env.local
VariableRequiredDescription
PRIVATE_KEYYesWallet private key β€” signs iExec request orders server-side. Needs RLC on Bellecour (0.1 RLC/task).
IEXEC_IAPP_ADDRESSYes0xB11bC7288eE239F6536829E410d22Eb514C5E282 β€” the deployed Intel TDX iApp
ARBITRUM_SEPOLIA_RPCYesServer-side RPC β€” use PublicNode or Infura (https://arbitrum-sepolia-rpc.publicnode.com)
NEXT_PUBLIC_RPC_URLYesClient-side RPC β€” same value as ARBITRUM_SEPOLIA_RPC
NEXT_PUBLIC_ARBITRUM_SEPOLIA_RPCYesMetaMask fallback RPC β€” same value
CHAINGPT_API_KEYOptionalChainGPT API key for the AI assistant β€” get at chaingpt.org

3. Run Development Server

npm run dev
# Open http://localhost:3000

Then visit /faucet to claim testnet USDT and CEST.

4. Run Tests

npm run test          # 73 passing
npx hardhat coverage  # Coverage report

Privacy Architecture β€” iExec TEE Flow

Raw token amounts never touch the blockchain in plaintext. Every buy flows through an Intel TDX TEE (Trusted Execution Environment) before any value reaches Arbitrum Sepolia.

// TEE buy flow

Browser
   β”‚
   β–Ό  POST /api/iexec-buy  { tokenAmount, contractAddress, buyerAddress }
   β”‚
Next.js API (Server)
   β”‚  iExec SDK: fetchAppOrderbook β†’ fetchWorkerpoolOrderbook
   β”‚             β†’ createRequestorder β†’ matchOrders
   β”‚  Returns: { taskid }
   β”‚
   β–Ό  Browser polls GET /api/iexec-poll?taskid=...  every 5s
   β”‚
iExec Network β€” Intel TDX TEE Worker (Bellecour)
   β”‚  iApp receives args inside verified hardware enclave
   β”‚  β†’ POST Nox Gateway: { value: uint256Hex, solidityType,
   β”‚                         applicationContract, owner }
   β”‚  ← Nox Gateway returns: { handle: bytes32, handleProof: bytes }
   β”‚  iApp writes result.json β†’ IPFS
   β”‚
   β–Ό  /api/iexec-poll: downloads result β†’ returns { handle, handleProof }
   β”‚
Browser β€” MetaMask
   β”‚  1. USDT.approve(propertyContract, amount Γ— 1_000_000)
   β”‚  2. PropertyToken.purchaseTokens(handle, handleProof, clearAmount)
   β”‚     └─ Nox.fromExternal(handle, handleProof) β†’ euint256 (encrypted)
   β–Ό
Arbitrum Sepolia β€” only encrypted handle on-chain

Nox Gateway

Only accepts requests from verified TEE enclaves β€” raw amounts cannot be injected by a malicious frontend.

fromExternal()

On-chain verification of the TDX attestation proof. Smart contract rejects any handle not signed by a real Intel TDX enclave.

toEuint256() NOT used

The bypass function is intentionally excluded β€” it would allow plaintext-to-encrypted conversion without TEE, defeating the privacy model.

Transaction Flows

Primary Market Buy/properties/[id]
1.POST /api/iexec-buy β†’ iExec TEE task submitted (taskid returned)
2.Frontend polls /api/iexec-poll every 5s until: { handle, handleProof }
3.USDT.approve(propertyContract, tokenAmount Γ— 1_000_000)
4.PropertyToken.purchaseTokens(handle, handleProof, clearAmount)
5.β†’ balance stored as euint256 via Nox.fromExternal()
Secondary Market β€” List/market
1.PropertyToken.grantOperator(secondaryMarket, expiry) // 7-day window recommended
2.SecondaryMarket.createListing(tokenContract, propertyId, tokenAmount, pricePerToken)
3.β†’ pricePerToken in USDT 6 decimals (e.g. $1.025 = 1_025_000)
4.β†’ returns listingId
Secondary Market β€” Buy/market
1.POST /api/iexec-buy β†’ TEE task for listing's tokenAmount
2.Frontend polls until: { handle, handleProof }
3.USDT.approve(secondaryMarket, listingTokenAmount Γ— pricePerToken)
4.SecondaryMarket.executeBuy(listingId, handle, handleProof)
5.β†’ confidentialTransferFrom (encrypted) via Nox.fromExternal()
Direct Transfer/dashboard β†’ Transfer tab
1.PropertyToken.grantOperator(recipientAddress, expiry)
2.β†’ expiry = block.timestamp + 7 days (recommended)
3.β†’ recipient can now call transferFrom on your behalf
Governance/dashboard β†’ Governance tab
1.ConfidentialGovernance.createProposal(propertyId, proposalType, description)
2.β†’ caller must be a verified PropertyToken holder
3.ConfidentialGovernance.castVote(proposalId, option)
4.β†’ option: 0 = For Β· 1 = Against Β· 2 = Abstain
5.β†’ 1 address = 1 vote (balance-blind)
6.ConfidentialGovernance.finalizeProposal(proposalId) // after deadline, any caller

Dashboard Guide

TabWhat you can do
PortfolioSee all your property token holdings per contract. Holdings are private on-chain β€” amounts shown from local state only.
TransferSend tokens to any wallet: call grantOperator(recipient, expiry) β†’ recipient can then pull your tokens via the SDK.
MarketCreate new secondary market listings (grantOperator + createListing) or cancel active listings you own.
GovernanceCreate proposals for properties you hold. Vote For / Against / Abstain. 1 address = 1 vote regardless of balance.
RewardsView pending rent distributions and past distribution history for your holdings.

Deploy Smart Contracts (Optional)

Only needed if deploying your own instance. Official contracts are already live on Arbitrum Sepolia.

# Compile all contracts
npx hardhat compile

# Deploy to Arbitrum Sepolia
npx hardhat run scripts/deploy.ts --network arbitrumSepolia

# Verify on Arbiscan
npx hardhat verify --network arbitrumSepolia <ADDRESS> [constructor args]

Deployment addresses are saved to deployments.json. All ABIs in artifacts/ and app/lib/contracts.ts.

Testnet Resources

Arbitrum Sepolia ETH (Gas)

  • 1. Get Sepolia ETH: cloud.google.com/application/web3/faucet
  • 2. Bridge to Arbitrum Sepolia: portal.arbitrum.io/bridge
  • 3. Select "Arbitrum Sepolia" as destination

Testnet RLC (iExec TEE tasks)

  • 1. Get testnet RLC: faucet.iex.ec (Bellecour network)
  • 2. 0.1 RLC consumed per TEE task (buy flow)
  • 3. Store in PRIVATE_KEY wallet (server-side signer)

USDT + CEST (App tokens)

  • 1. Connect wallet β†’ visit /faucet
  • 2. Click "Claim 1,000 USDT" β†’ confirm tx
  • 3. Click "Claim 2,400 CEST" β†’ confirm tx

iExec Explorer

  • iApp: explorer.iex.ec/bellecour/app/0xB11bC7…
  • Requester: explorer.iex.ec/bellecour/address/0x834De7…
  • 4/5 tasks COMPLETED on April 30, 2026