# Hologram — Full Documentation Corpus > Every documentation page for hologram.derod.org, inlined as Markdown for long-context LLM ingestion. Curated link list: https://hologram.derod.org/llms.txt. Each page is also available individually at https://hologram.derod.org/.md. --- --- title: "Full API Reference" description: "Complete reference of all 300+ Hologram API methods across 30 functional areas." --- # Full API Reference Complete reference of all Hologram API methods. These are Go methods exposed to the frontend via Wails bindings. All methods returning `map[string]interface{}` follow the standard [response format](#response-format). ## Browser Navigation ```go Navigate(scid string) map[string]interface{} GoBack() map[string]interface{} GoForward() map[string]interface{} Reload() map[string]interface{} FetchSCID(scid string) map[string]interface{} FetchByDURL(durl string) map[string]interface{} FetchTELAContent(scid string) map[string]interface{} ServeTELAContent(scid string) map[string]interface{} ``` ## Wallet Lifecycle ```go OpenWallet(filePath string, password string) map[string]interface{} CloseWallet() map[string]interface{} CreateWallet(filePath string, password string) map[string]interface{} RestoreWallet(filePath string, password string, seed string) map[string]interface{} SwitchWallet(filePath string, password string) map[string]interface{} IsWalletOpen() bool GetWalletStatus() map[string]interface{} GetCurrentWalletPath() map[string]interface{} SelectWalletFile() map[string]interface{} ``` ## Wallet Balance & Sync ```go GetBalance() map[string]interface{} GetBalanceAtHeight(address string, topoheight int64, scid string) map[string]interface{} GetAddress() map[string]interface{} SyncWallet() map[string]interface{} GetWalletSyncStatus() map[string]interface{} ``` ## Wallet Transfers ```go Transfer(destination string, amount uint64, paymentID string) map[string]interface{} TransferToken(scid string, destination string, amount uint64, password string, ringsize uint64) map[string]interface{} InternalWalletCall(method string, params string, password string) map[string]interface{} ``` ## Transaction History ```go GetTransactionHistory(limit int) map[string]interface{} GetTransactionBasic(txid string) map[string]interface{} GetPersonalTransfers(limit int) map[string]interface{} GetWalletMiningEarnings(limit int) map[string]interface{} GetMiningEarningsSummary() map[string]interface{} ``` ## Transaction Labels ```go SetTransactionLabel(txid string, label string) map[string]interface{} GetTransactionLabel(txid string) map[string]interface{} GetAllTransactionLabels() map[string]interface{} DeleteTransactionLabel(txid string) map[string]interface{} GenerateSemanticLabel(scid string, commitNum int) map[string]interface{} ``` ## Integrated Addresses ```go GetIntegratedAddress(destinationPort uint64, comment string, amount uint64) map[string]interface{} SplitIntegratedAddress(address string) map[string]interface{} CreatePaymentRequest(amount uint64, comment string) map[string]interface{} DecodeIntegratedAddress(addr string) map[string]interface{} ``` ## Token Portfolio ```go GetTokenPortfolio() map[string]interface{} GetTrackedTokens() map[string]interface{} AddTrackedToken(scid string, name string, symbol string) map[string]interface{} RemoveTrackedToken(scid string) map[string]interface{} ``` ## Address Book ```go GetAddressBook() map[string]interface{} AddContact(label string, address string, notes string) map[string]interface{} UpdateContact(id string, label string, address string, notes string) map[string]interface{} DeleteContact(id string) map[string]interface{} ``` ## Wallet Security ```go GetSeedPhrase(password string) map[string]interface{} GetWalletKeys(password string) map[string]interface{} ChangeWalletPassword(currentPassword string, newPassword string) map[string]interface{} SignMessage(message string) map[string]interface{} VerifySignature(signedData string) map[string]interface{} ``` ## Recent Wallets ```go GetRecentWalletsWithInfo() map[string]interface{} ListRecentWallets() map[string]interface{} RemoveRecentWallet(path string) map[string]interface{} ClearRecentWallets() map[string]interface{} ``` ## XSWD (dApp Integration) ```go // Client mode (connect to external wallet) ConnectXSWD() map[string]interface{} DisconnectXSWD() map[string]interface{} CallXSWD(methodJSON string) map[string]interface{} GetXSWDStatus() map[string]interface{} // Server mode (internal wallet serves dApps) ApproveWalletConnection() map[string]interface{} RespondToXSWDRequest(requestID string, approved bool, password string) map[string]interface{} RespondToXSWDRequestWithPermissions(requestID string, approved bool, password string, permissions string) map[string]interface{} GetActiveXSWDConnections() map[string]interface{} RevokeXSWDConnection(origin string) map[string]interface{} GetConnectionLog(limit int) map[string]interface{} ClearConnectionLog() map[string]interface{} ExecuteSCViaXSWD(scid string, function string, args string) map[string]interface{} // Events SubscribeToBlockEvents() map[string]interface{} SubscribeToWalletEvents() map[string]interface{} UnsubscribeFromEvents() map[string]interface{} ``` ## Connected Apps & Permissions ```go GetConnectedApps() map[string]interface{} GetActiveConnections() map[string]interface{} GetPermissionTypes() map[string]interface{} GrantAppPermission(origin string, permission string, alwaysAsk bool) map[string]interface{} RevokeAppPermissions(origin string) map[string]interface{} RevokeAppPermission(origin string, permission string) map[string]interface{} ``` ## Explorer - Blocks ```go GetBlock(height int64) map[string]interface{} GetBlockByHash(hash string) map[string]interface{} GetBlockExtended(heightOrHash string) map[string]interface{} GetRecentBlocks(count int) map[string]interface{} FormatBlockAge(timestampMs int64) map[string]interface{} DaemonGetBlockHeaderByHeight(height int64) map[string]interface{} ``` ## Explorer - Transactions ```go GetTransaction(txid string) map[string]interface{} GetTransactionExtended(txid string) map[string]interface{} GetTransactionWithRings(txid string) map[string]interface{} GetCoinbaseMiner(txid string) map[string]interface{} GetRingMembers(txid string) map[string]interface{} ``` ## Explorer - Mempool ```go GetMempoolTransactions() map[string]interface{} GetMempoolExtended(maxCount int) map[string]interface{} GetMempoolStats() map[string]interface{} DaemonGetTxPool() map[string]interface{} ``` ## Explorer - Network ```go GetBlockchainStats() map[string]interface{} GetNetworkInfo() map[string]interface{} GetNetworkStats() map[string]interface{} GetNetworkHealth() map[string]interface{} GetLiveStats() map[string]interface{} StartBlockMonitoring() map[string]interface{} StopBlockMonitoring() map[string]interface{} ``` ## Explorer - Smart Contracts ```go GetSCInfo(scid string) map[string]interface{} GetSCCode(scid string) map[string]interface{} GetSCVariables(scid string) map[string]interface{} GetSCInteractionHistory(scid string) map[string]interface{} DaemonGetSC(scid string) map[string]interface{} GetRandomSmartContracts(count int) map[string]interface{} GetAddressSCIDReferences(address string) map[string]interface{} SearchAddress(address string) map[string]interface{} ``` ## Smart Contract Interaction ```go ParseSCFunctions(scid string) map[string]interface{} InvokeSCFunction(paramsJSON string) map[string]interface{} InvokeSCFromExplorer(scid string, entrypoint string, args []map[string]interface{}, deposit uint64) map[string]interface{} InstallSmartContract(code string, anonymous bool) map[string]interface{} EstimateSCGas(scid string, entrypoint string, args []map[string]interface{}) map[string]interface{} GetGasEstimate(paramsJSON string) map[string]interface{} ``` ## Proof Validation ```go ValidatePayloadProofAmount(amount uint64) error ValidatePayloadProofAmountWithContext(amount uint64) map[string]interface{} DetectSuspiciousProofPatterns(amount uint64) []string ValidateProof(proofJSON string) map[string]interface{} ValidateProofFull(proofJSON string, address string) map[string]interface{} ValidateSenderProof(txid string, address string, amount uint64, message string, signature string) map[string]interface{} ``` ## Ratings System ```go RateTELAApp(scid string, rating int) map[string]interface{} RateTELA(scid string, rating uint64) map[string]interface{} LikeTELAApp(scid string) map[string]interface{} DislikeTELAApp(scid string) map[string]interface{} GetAppRating(scid string) map[string]interface{} GetRatingDetails(scid string) map[string]interface{} GetRatingsBreakdown(scid string) map[string]interface{} GetRatingResultForSCID(scid string) map[string]interface{} GetRatingCategories() map[string]interface{} ParseRatingForUI(ratingJSON string) map[string]interface{} BuildRating(category int, detail int) map[string]interface{} SubmitRatingWithPicker(scid string, category int, detail int) map[string]interface{} ``` ## NRS (Name Resolution) ```go ResolveDeroName(name string) map[string]interface{} GetNameForAddress(address string) map[string]interface{} GetNameSuggestions(prefix string) map[string]interface{} GetNRSCacheStats() map[string]interface{} GetAllCachedNames() map[string]interface{} ``` ## Search & Discovery ```go OmniSearch(query string) map[string]interface{} SearchApps(query string) map[string]interface{} SearchByKey(key string) map[string]interface{} SearchByValue(value string) map[string]interface{} SearchCodeLine(pattern string) map[string]interface{} SearchAddress(address string) map[string]interface{} FilterSearchResults(filterJSON string) map[string]interface{} AddSearchExclusion(filter string) map[string]interface{} RemoveSearchExclusion(filter string) map[string]interface{} GetSearchExclusions() map[string]interface{} ClearSearchExclusions() map[string]interface{} SetSearchMinLikes(percent int) map[string]interface{} ``` ## Gnomon Indexer ```go StartGnomon() map[string]interface{} StopGnomon() map[string]interface{} GetGnomonStatus() map[string]interface{} EnsureGnomonRunning() map[string]interface{} SetGnomonAutostart(enabled bool) map[string]interface{} GetGnomonAutostart() map[string]interface{} ResyncGnomon() map[string]interface{} ResyncGnomonFromHeight(height int64) map[string]interface{} CleanGnomonDB(confirm bool) map[string]interface{} GetDiscoveredApps() map[string]interface{} GetAppDetails(scid string) map[string]interface{} ``` ## Gnomon Tagging & Classification ```go GetAllTags() map[string]interface{} GetSCIDsByTag(tag string) map[string]interface{} GetTagStats() map[string]interface{} GetAllClasses() map[string]interface{} GetSCIDsByClass(class string) map[string]interface{} GetSCIDMetadata(scid string) map[string]interface{} GetTELAAppsWithTags() map[string]interface{} RebuildTagIndex() map[string]interface{} ``` ## Gnomon Historical Queries ```go GetSCChangeTimeline(scid string) map[string]interface{} GetSCStateAtHeight(scid string, height uint64) map[string]interface{} CompareSCStateAtHeights(scid string, from uint64, to uint64) map[string]interface{} GetSCStateHistory(scid string) map[string]interface{} ``` ## Gnomon WebSocket API ```go StartGnomonWSServer(address string) map[string]interface{} StopGnomonWSServer() map[string]interface{} GetGnomonWSStatus() map[string]interface{} ``` ## Time Travel & SC Watching ```go CaptureSCState(scid string) map[string]interface{} WatchSmartContract(scid string, name string) map[string]interface{} UnwatchSmartContract(scid string) map[string]interface{} GetWatchedSmartContracts() map[string]interface{} RefreshWatchedSCs() map[string]interface{} ``` ## Developer Support (EPOCH) ```go SetDevSupportEnabled(enabled bool) map[string]interface{} IsDevSupportEnabled() bool GetDevSupportStatus() map[string]interface{} GetDevSupportStats() map[string]interface{} SetEpochEnabled(enabled bool) map[string]interface{} IsEpochEnabled() bool IsEpochActive() bool GetEpochStats() map[string]interface{} SetEpochConfig(maxHashes int, maxThreads int) map[string]interface{} HandleEpochRequest(hashes int, appSCID string) map[string]interface{} InitializeEpoch() map[string]interface{} ShutdownEpoch() map[string]interface{} GetEpochAddressInfo() map[string]interface{} GetEpochSupportingApps() map[string]interface{} StartEpochAddressMonitor() map[string]interface{} CheckAppSupportsEpoch(scid string) map[string]interface{} ``` ## Offline Cache ```go PrefetchApp(scid string) map[string]interface{} GetCachedApps() map[string]interface{} IsAppCachedOffline(scid string) map[string]interface{} RemoveCachedApp(scid string) map[string]interface{} UpdateCachedApp(scid string) map[string]interface{} GetOfflineCacheStats() map[string]interface{} ClearOfflineCache() map[string]interface{} SetOfflineCacheEnabled(enabled bool) map[string]interface{} BatchPrefetchFavorites(favorites []map[string]interface{}, minRating int) map[string]interface{} CheckAppForUpdate(scid string) map[string]interface{} CheckAllForUpdates() map[string]interface{} DiffCachedVsOnChain(scid string) map[string]interface{} ``` ## Studio - Local Dev Server ```go StartLocalDevServer(directory string) map[string]interface{} StopLocalDevServer() map[string]interface{} GetLocalDevServerStatus() map[string]interface{} RefreshLocalDevServer() map[string]interface{} ``` ## Studio - Deployment ```go DeployTELABatch(configJSON string) map[string]interface{} ParseFolderForTELA(directory string) map[string]interface{} EstimateBatchGas(configJSON string) map[string]interface{} CheckBalanceForBatchDeployment(fileCount int, hasGzip bool, hasMods bool) map[string]interface{} DetectDocTypes(directory string) map[string]interface{} GetAvailableDOCTypes() map[string]interface{} ``` ## Studio - INDEX & DOC Management ```go GetINDEXInfo(scid string) map[string]interface{} InstallINDEX(configJSON string) map[string]interface{} UpdateINDEX(scid string, configJSON string) map[string]interface{} InstallDOC(configJSON string) map[string]interface{} PreviewDOC(configJSON string) map[string]interface{} ``` ## Studio - MODs ```go GetAllMODClasses() map[string]interface{} GetMODInfo(modTag string) map[string]interface{} GetMODsByClass(class string) map[string]interface{} GetMODsList() map[string]interface{} PrepareMODInstall(scid string, modTags string) map[string]interface{} ``` ## Studio - Version Control ```go GetCommitHistory(scid string) map[string]interface{} GetCommitHistoryWithLabels(scid string) map[string]interface{} GetCommitContent(scid string, commitNum int) map[string]interface{} DiffCommits(scid string, fromCommit int, toCommit int) map[string]interface{} DiffFiles(contentA string, contentB string) map[string]interface{} DiffSCIDs(scidA string, scidB string) map[string]interface{} CloneTELA(scid string, directory string) map[string]interface{} GetClonePath() map[string]interface{} ``` ## Studio - My Content ```go SearchMyContent() map[string]interface{} SearchMyINDEXes() map[string]interface{} SearchMyDOCs(docType string) map[string]interface{} ``` ## Studio - DocShards ```go ShardFile(filePath string, compress bool) map[string]interface{} ConstructFromShards(shardPath string) map[string]interface{} ``` ## Studio - Libraries ```go GetTELALibraries() map[string]interface{} ``` ## Simulator ```go StartSimulatorMode() map[string]interface{} StopSimulatorMode() map[string]interface{} GetSimulatorStatus() map[string]interface{} IsSimulatorReady() map[string]interface{} ResetSimulator() map[string]interface{} IsInSimulatorMode() bool GetSimulatorDeploymentInfo() map[string]interface{} GetSimulatorWalletStatus() map[string]interface{} GetSimulatorWalletInfo() map[string]interface{} IsSimulatorWalletRegistered() map[string]interface{} UseSimulatorWallet() map[string]interface{} DeployToSimulator(code string) map[string]interface{} PreviewTELAApp(appJSON string) map[string]interface{} QuickDeployFile(name string, content string, docType string) map[string]interface{} BatchDeployToSimulator(codesJSON string) map[string]interface{} EstimateSimulatorGas(docJSON string) map[string]interface{} ``` ## Simulator - Test Wallets ```go GetSimulatorTestWallets() map[string]interface{} GetSimulatorTestWallet(walletId int) map[string]interface{} SyncSimulatorTestWallets() map[string]interface{} OpenSimulatorTestWallet(walletId int) map[string]interface{} FundTestWallet(walletId int, amount uint64) map[string]interface{} RefreshTestWalletBalance(walletId int) map[string]interface{} ``` ## Node Management ```go StartNode(config map[string]interface{}) map[string]interface{} StartNodeWithNetwork(config map[string]interface{}, network string) map[string]interface{} StopNode() map[string]interface{} GetNodeStatus() map[string]interface{} GetNodeConfig() map[string]interface{} SetNodeConfig(configJSON string) map[string]interface{} GetNodeAdvancedConfig() map[string]interface{} SetNodeAdvancedConfig(fastSync bool, pruneHistory int, extraArgs string) map[string]interface{} SetNodePorts(rpcPort int, p2pPort int) map[string]interface{} GetNodeLogs(limit int) map[string]interface{} DetectRunningNode() map[string]interface{} DetectExistingBlockchain() map[string]interface{} CheckDerodStatus() map[string]interface{} TestAndConnectEndpoint(endpoint string) map[string]interface{} GetSyncProgress() map[string]interface{} EstimateSyncTime() map[string]interface{} ``` ## Network & Mode ```go SetNetworkMode(mode string) map[string]interface{} GetNetworkMode() map[string]interface{} GetAvailableNetworks() map[string]interface{} GetNetworkFilterStatus() map[string]interface{} ``` ## TELA Server Management ```go ListActiveServers() map[string]interface{} ShutdownServer(name string) map[string]interface{} ShutdownAllServers() map[string]interface{} ShutdownTELAServers() map[string]interface{} ShutdownLocalServers() map[string]interface{} ServeLocalDirectory(directory string) map[string]interface{} SetMaxServers(count int) map[string]interface{} SetServerPortStart(port int) map[string]interface{} GetServerPortRange() map[string]interface{} GetServerInfo(name string) map[string]interface{} ``` ## Content Filtering & Safe Browsing ```go GetContentFilterConfig() map[string]interface{} SetContentFilterConfig(enabled bool, minRating int, blockMalware bool, blockUnrated bool, requireEpoch bool, showWarnings bool, parentalLevel string, epochBonus int) map[string]interface{} GetContentFilterRules() map[string]interface{} GetContentFilterHistory(limit int) map[string]interface{} GetContentFilterStats() map[string]interface{} CheckAppFilter(scid string, name string, author string, category string, rating int, ratingCount int, supportsEpoch bool) map[string]interface{} ManuallyAllowApp(scid string) map[string]interface{} ManuallyBlockApp(scid string) map[string]interface{} ClearAppFilterOverride(scid string) map[string]interface{} IsRequestAllowed(url string) map[string]interface{} ``` ## Privacy Mode ```go AddAllowedHost(host string) map[string]interface{} RemoveAllowedHost(host string) map[string]interface{} GetCypherpunkMode() map[string]interface{} SetCypherpunkMode(enabled bool) map[string]interface{} RequestInterceptor(url string) map[string]interface{} ``` ## Settings ```go GetSetting(key string) map[string]interface{} GetAllSettings() map[string]interface{} SetSetting(settingsJSON string) map[string]interface{} GetHistory() map[string]interface{} ClearHistory() map[string]interface{} GetAppInfo() map[string]interface{} ``` ## Console ```go GetConsoleLogs() map[string]interface{} ClearConsoleLogs() map[string]interface{} ``` ## File Operations ```go SelectFile() map[string]interface{} SelectFiles() map[string]interface{} SelectFolder() map[string]interface{} ListDirectory(path string) map[string]interface{} GetFileInfo(path string) map[string]interface{} ScanFolder(path string) map[string]interface{} GetMetadataFiles(folderPath string) map[string]interface{} GenerateSubDirs(basePath string, name string) map[string]interface{} MoveFile(source string, destination string) map[string]interface{} RemoveFile(path string) map[string]interface{} SaveFileWithDialog(filename string, content string, title string, defaultDir string) map[string]interface{} SaveBinaryFileWithDialog(filename string, base64Data string, title string, defaultDir string) map[string]interface{} ``` ## Graviton Storage ```go SetVar(bucket string, key string, value string) map[string]interface{} DeleteVar(bucket string, key string) map[string]interface{} ``` ## Status Broadcast ```go StartStatusBroadcast() map[string]interface{} ``` ## Events Hologram emits these events to the frontend: | Event | Description | |-------|-------------| | `status:update` | 5-second status broadcast (node, wallet, gnomon) | | `localdev:reload` | File changed in local dev server | | `xswd:connection` | XSWD connection state changed | | `wallet:balance` | Wallet balance updated | | `wallet:daemon_connection_warning` | Wallet lost daemon connection | | `xswd:server_error` | XSWD server encountered an error | | `gnomon:progress` | Gnomon indexing progress | ## Response Format All API methods return a map with standard fields: ```go { "success": bool, // Operation succeeded "error": string, // Error message if success=false // Plus method-specific fields } ``` ## Unit Test Coverage | Test File | Coverage Area | |-----------|---------------| | `wallet_test.go` | Wallet operations | | `tela_service_test.go` | TELA content assembly | | `daemon_client_test.go` | RPC client | | `blockchain_test.go` | TELA assembly, gzip | | `xswd_permissions_test.go` | Permission types, persistence | | `search_service_test.go` | Search and filtering | | `gnomon_features_test.go` | Gnomon feature tests | | `cache_optimizer_test.go` | LRU cache, eviction | | `xswd_server_test.go` | JSON-RPC protocol | | `rating_system_test.go` | App rating system | | `gnomon_test.go` | Indexer operations | | `epoch_handler_test.go` | EPOCH requests, rate limiting | Run tests: ```bash cd /path/to/HOLOGRAM go test -v -count=1 # Run all tests go test -bench=. -benchmem # Run benchmarks ``` --- --- title: "TELA Browser" description: "Browse decentralized applications stored entirely on the DERO blockchain with Hologram's TELA Browser engine." --- # TELA Browser ![TELA Browser](/assets/browser.png) The TELA Browser enables accessing decentralized web applications stored entirely on the DERO blockchain. ## Core Concepts ### What is TELA? TELA is a protocol for storing and serving web content from the DERO blockchain. Key benefits: - **Immutable**: Content cannot be modified after deployment - **Censorship-Resistant**: No central server to take down - **Privacy-Preserving**: No tracking, no cookies (see [Security Features](/security.md)) - **Permanent**: Content exists as long as the blockchain exists > [!NOTE] > New to TELA development? Check out [Studio](/studio.md) for local development tools and [Simulator Mode](/simulator.md) for testing your apps. ### How It Works ```mermaid flowchart TD INDEX["INDEX Contract (SCID)"] --> DOC1["DOC1 HTML"] INDEX --> DOC2["DOC2 CSS"] INDEX --> DOC3["DOC3 JavaScript"] INDEX --> DOC4["DOC4 Assets"] DOC1 & DOC2 & DOC3 & DOC4 --> ASM["Content Assembler"] ASM --> BRIDGE["telaHost Bridge"] BRIDGE --> APP["Rendered Application"] ``` ## Address Bar Navigation The Browser address bar uses the same **OmniSearch** engine as the Explorer, with intelligent type detection and cross-tab routing. Browsable content (dURLs, SCIDs, names) loads directly in the Browser. Explorer-type queries (block heights, addresses, search prefixes) automatically switch to the Explorer tab. ```mermaid flowchart LR INPUT["User Input"] --> DETECT{Type Detection} DETECT -->|"64 hex chars"| SCID["Direct SCID Fetch"] DETECT -->|"dero://"| DURL["dURL Resolution via Gnomon"] DETECT -->|"text"| SEARCH["Name Search"] DETECT -->|"number"| EXPLORER["→ Explorer Tab"] DETECT -->|"dero1..."| EXPLORER DETECT -->|"key: value: code: class: tag:"| EXPLORER SCID --> RENDER["Render App"] DURL --> RENDER SEARCH --> RENDER EXPLORER --> RESULT["Explorer Search Results"] ``` {/* removed: name@txid "Versioned Fetch" render branch not in code as of 2026-06-12; address-bar navigate() only handles 64-hex SCID or dURL, and FetchSCID always fetches the latest version. Restore if built */} | Input Format | Example | Action | |--------------|---------|--------| | Raw SCID (64 hex) | `abc123...def456` | Fetch directly from blockchain | | dero:// URL | `dero://myapp` | Resolve via Gnomon, then fetch | | Name lookup | `myapp` | Search indexed apps | | Block height | `5000000` | Switch to Explorer | | Address | `dero1qy...` | Switch to Explorer | | Search prefix | `key:owner` | Switch to Explorer with results | > [!NOTE] > The address bar runs in compact mode — no search button or helper text. Just type and press Enter. A type badge appears as you type to show what OmniSearch detected (Block, SCID, dURL, etc.). {/* removed: "Versioned Navigation (scid@txid)" section not in code as of 2026-06-12 — the Browser address bar navigate() only resolves a 64-hex SCID or a dURL, and FetchSCID always serves the latest version (LatestInteractionHeight). The only scid@txid handling is in CloneTELA -> CloneAtCommit (download path), not browser render. Restore if address-bar versioned fetch is built. */} ## Browser Toolbar The browser toolbar includes: | Button | Function | |--------|----------| | **Back/Forward** | Navigate history | | **Reload** | Refresh current page | | **Home** | Return to Discover | | **Console** | Toggle developer console | | **Version History** | View commit history for current TELA app | > [!NOTE] > The Version History button opens the commit timeline for the currently loaded TELA app. See [Studio > Actions](/studio.md#actions-version-control) for full version control documentation. ## Supported Document Types - `TELA-HTML-1`: HTML documents - `TELA-CSS-1`: Stylesheets - `TELA-JS-1`: JavaScript files - `TELA-JSON-1`: JSON data - `TELA-STATIC`: Static files (SVG, images, etc.) - `*.tela.shards`: Shard index files - `*.tela.lib`: Library info views ### TELA-STATIC Support Hologram supports `TELA-STATIC` document type for embedding static files like SVG images and other binary assets. #### Automatic Inline Embedding When Hologram encounters a `TELA-STATIC` DOC: 1. **File content extracted** — Static file content is read from the DOC contract 2. **MIME type detection** — Automatically detects file type (SVG, PNG, JPEG, GIF, WebP, ICO) 3. **Data URI conversion** — Converts to data URI format for inline embedding 4. **HTML replacement** — Replaces `` references with inline data URIs #### Supported Static File Types | File Type | MIME Type | Encoding | |-----------|-----------|----------| | SVG | `image/svg+xml` | URL-encoded (direct) | | PNG | `image/png` | Base64 | | JPEG | `image/jpeg` | Base64 | | GIF | `image/gif` | Base64 | | WebP | `image/webp` | Base64 | | ICO | `image/x-icon` | Base64 | #### Example ```html Logo Logo ``` This ensures static assets are always available, even when the original source is inaccessible. ### TELA V2 Contract Keys Hologram supports both TELA V1 and V2 contract formats for maximum compatibility. #### Version Comparison | Version | Variable Keys | Description | |---------|---------------|-------------| | **V1 (Original)** | `nameHdr`, `descrHdr`, `iconHdr` | Original TELA format used by early deployments | | **V2 (Current)** | `var_header_name`, `var_header_description`, `var_header_icon` | Newer standardized format | #### Key Differences **V1 Format:** - Uses `nameHdr`, `descrHdr`, `iconHdr` for metadata - Original TELA specification - Still supported for backward compatibility **V2 Format:** - Uses `var_header_name`, `var_header_description`, `var_header_icon` - Standardized naming convention - **Mutable** — Can be updated after deployment (if INDEX is Ring 2) #### How Hologram Handles Both When fetching TELA content, Hologram automatically checks for both formats: 1. **First checks V2 keys** — Looks for `var_header_name`, `var_header_description`, `var_header_icon` 2. **Falls back to V1 keys** — If V2 not found, checks `nameHdr`, `descrHdr`, `iconHdr` 3. **No user action needed** — Hologram handles the format detection automatically #### For Developers - **New deployments**: Use V2 headers (`var_header_*`) for better compatibility - **Existing apps**: V1 headers still work perfectly - **Updates**: V2 headers can be updated if your INDEX is Ring 2 (updateable) > [!NOTE] > You don't need to know which version an app uses—Hologram automatically detects and handles both formats. For developers: use V2 headers if you want the ability to update metadata later! ## Features ### Automatic Gzip Decompression Files stored with `.gz` extension are automatically decompressed: ```go // Automatic gzip handling if strings.HasSuffix(fileName, ".gz") { decompressed, err := decompressGzip(fileContent) // fileName becomes "app.js" from "app.js.gz" } ``` ### External Reference Inlining External ` ``` ### Versioned Caching Content is cached with version tracking: - **Key**: SCID or dURL - **Version**: Latest interaction height from Gnomon - **Hash**: SHA256 of assembled content - **Auto-invalidation**: When version changes on-chain ```go // Cache lookup with version validation if html, ok := cache.GetHTMLIfVersion(scid, version); ok { return html // Cache hit } // Fetch from blockchain on cache miss ``` ### telaHost Bridge API Every TELA app automatically has access to the `telaHost` JavaScript API (similar to `window.ethereum` in Web3 browsers), enabling: - Blockchain queries - Wallet connection - Smart contract interaction - Transaction signing (with user approval) See [telaHost API Reference](/telahost-api.md) for full documentation, including [Smart Permission Detection](/telahost-api.md#smart-permission-detection). ## Full TELA dApp Compatibility Hologram provides full compatibility with complex TELA dApps, including those requiring CSP relaxation and direct WebSocket connections. This infrastructure enables dApps like `explorer.tela` to function fully within Hologram's secure sandboxed environment. Learn more about the security model in [Security Features](/security.md#reverse-proxy-system--csp-relaxation). ### Key Features | Feature | Description | |---------|-------------| | **Reverse Proxy System** | Strips `Content-Security-Policy` headers while maintaining security through iframe sandboxing and blockchain immutability. Provides XSWD bridge script and adds security headers. | | **XSWD WebSocket Bridge** | Intercepts `new WebSocket()` calls to the XSWD port (44326), creating a proxy that routes connections through `window.parent.postMessage()`. | | **Smart RPC Routing** | Automatically routes `DERO.*` methods to daemon when internal XSWD server is running, optimizing performance while maintaining backward compatibility. | | **WKWebView Compatibility** | Custom workarounds for WKWebView's strict property enforcement, ensuring compatibility with JavaScriptCore engine on macOS. | ### How the XSWD Bridge Works 1. **App calls `new WebSocket('ws://127.0.0.1:44326/xswd')`** 2. **Bridge script intercepts** — The bridge script catches WebSocket creation 3. **Creates proxy WebSocket** — Returns a fake WebSocket object to the app 4. **Routes via postMessage** — All messages go through `window.parent.postMessage()` 5. **Hologram handles routing** — Go backend processes XSWD requests 6. **Response returned** — Results sent back through the same postMessage channel This allows TELA apps to use standard XSWD WebSocket code while running in a sandboxed iframe. ### XSWD Method Compatibility Hologram supports all standard XSWD methods for full compatibility with existing TELA dApps: #### Supported Method Categories | Category | Methods | Status | |----------|---------|--------| | **DERO Daemon** | `DERO.GetInfo`, `DERO.GetBlock`, `DERO.GetTransaction`, etc. | ✅ Fully supported | | **Wallet** | `GetAddress`, `GetBalance`, `Transfer`, `scinvoke`, `GetTransfers`, `GetTransferbyTXID`, `MakeIntegratedAddress`, `SplitIntegratedAddress`, `QueryKey`, `SignData`, `CheckSignature`, `HasMethod`, `Unsubscribe`, `transfer_split` | ✅ Fully supported | | **Gnomon Indexer** | `Gnomon.GetAllSCIDVariableDetails`, `Gnomon.GetStatus`, etc. | ✅ Fully supported | | **EPOCH Mining** | `AttemptEPOCH`, `AttemptEPOCHWithAddr`, `GetMaxHashesEPOCH` | ✅ Fully supported | | **TELA Links** | `HandleTELALinks` | ✅ Fully supported | #### XSWD Parity Features Hologram's XSWD server has been specifically engineered to ensure 100% plug-and-play parity with Engram and the official DERO CLI: - **Case-Insensitivity**: Fully supports lowercase aliases (e.g., `getbalance`, `getaddress`, `transfer_split`) to match various dApp implementations. - **Advanced Transfer Parsing**: Full support for parsing `sc_dero_deposit`, `sc_token_deposit`, custom `fees`, and per-transfer `scid` (for token transfers) via XSWD. - **Smart Contract Deployment**: XSWD `sc` parameter forwarding is fully supported for deploying new contracts directly from dApps. #### Response Format Compatibility Hologram ensures compatibility with existing dApps by maintaining expected response formats: **Gnomon.GetAllSCIDVariableDetails** returns data in the format expected by apps like `feed.tela`: ```json { "success": true, "result": { "allVariables": [ {"Key": "eid_1", "Value": "..."}, {"Key": "eid_2", "Value": "..."} ] } } ``` **AttemptEPOCHWithAddr** is supported for developer hash donations. The method accepts an `address` parameter for directing mining rewards, though rewards currently go to the connected wallet. > [!NOTE] > For new dApp development, consider using the [telaHost API](/telahost-api.md) instead of raw XSWD for a cleaner, more maintainable codebase. ### Compatibility | dApp Type | Status | |-----------|--------| | telaHost API apps | Fully functional | | Direct XSWD WebSocket apps | Fully functional | | CSP-restricted apps | Fully functional | | Complex multi-file apps | Fully functional | ### Security Model CSP removal is mitigated by multiple defense layers: | Layer | Protection | |-------|------------| | **Blockchain immutability** | Content is cryptographically verified from on-chain data | | **Iframe sandboxing** | Restricted permissions prevent malicious actions | | **Controlled API access** | User approval required for wallet operations | | **Local execution** | Content runs locally, not from remote servers | | **Source verification** | All content fetched directly from blockchain | > [!NOTE] > This infrastructure benefits all TELA dApps, not just specific ones. It's part of Hologram's core browser rendering capabilities. ## Shard & Library Support ### Shard Index (`*.tela.shards`) For large applications split across multiple contracts: - Concatenates multiple DOC files into single HTML - Maintains proper ordering - Useful for apps exceeding single contract size limits ### Library View (`*.tela.lib`) For inspecting TELA content without execution: - Renders lightweight info table - Shows file names, types, and SCIDs - Metadata display only (no JavaScript execution) ## Browser Session Persistence Hologram preserves your browser state when navigating to other tabs (Wallet, Settings, etc.): - **Tabs persist** — All open tabs with their URLs and loading states - **Filters persist** — Category, tag, sort order, and rating filters - **Discover cache** — App list is cached to avoid reloading - **Address bar** — Current URL preserved This means you can check your wallet balance and return to Browser without losing your place or waiting for apps to reload. ## Discover Tab The Discover tab provides app discovery features: - **Browse All**: See all indexed TELA apps - **Search**: Full-text search by name and description - **Ratings**: Community-driven trust scores (0-99) - **EPOCH Filter**: Find apps that support developer mining ## Tag-Based App Discovery > [!NOTE] > **New in v6.3** - Filter apps by smart contract classification tags for faster discovery. Hologram's Gnomon indexer automatically classifies smart contracts into categories based on their code patterns. Use tag filters in the Browser to quickly find specific types of apps. ### Available Tags | Tag | Description | Matched Patterns | |-----|-------------|------------------| | `tela` | TELA applications | `docVersion`, `telaVersion` | | `g45` | G45 standard tokens/NFTs | `G45-NFT`, `G45-AT`, `G45-C`, `G45-FAT`, `G45-NAME`, `T345` | | `nfa` | Non-Fungible Assets | `ART-NFA-MS1` | | `epoch` | EPOCH-enabled apps | `EPOCH`, `epochEnabled`, `crowd_mining` | ### Tag Filter UI The Browser shows tag filter buttons when tags are available: ``` +----------------------------------------------------------+ | Filter by Tag: [All] [tela] [g45] [nfa] [epoch] | +----------------------------------------------------------+ | 72 apps found | +----------------------------------------------------------+ ``` ### Tag API ```go // Get all available tags GetAllTags() -> { success: bool, tags: []string, // ["tela", "g45", "nfa", "epoch"] } // Get SCIDs matching a tag GetSCIDsByTag(tag) -> { success: bool, tag: string, scids: []string, count: int, } // Get classification for specific SCID GetSCIDMetadata(scid) -> { success: bool, metadata: { scid: string, class: string, // "TELA-INDEX-1", "G45-NFT", etc. tags: []string, // ["tela", "all"] owner: string, deployHeight: int64, }, } // Get tag distribution statistics GetTagStats() -> { success: bool, stats: { tela: int, g45: int, nfa: int, epoch: int, total: int, }, } ``` ### Classification System Smart contracts are classified based on code analysis: | Class | Detection Method | |-------|------------------| | `TELA-INDEX-1` | Contains `DOC1`, `DOC2`, etc. variables | | `TELA-DOC-1` | Contains `docVersion` variable | | `G45-NFT` | Contains `G45-NFT` in code | | `G45-AT` | Contains `G45-AT` in code | | `ART-NFA-MS1` | Contains `ART-NFA-MS1` in code | ```go // Get SCIDs by class GetSCIDsByClass(class) -> { success: bool, class: string, scids: []string, count: int, } // Get all known classes GetAllClasses() -> { success: bool, classes: []string, } // Rebuild tag index from Gnomon data RebuildTagIndex() -> { success: bool, indexed: int, message: string, } ``` > [!NOTE] > Tags are automatically assigned during indexing. Use `RebuildTagIndex()` to re-classify all indexed contracts if needed. ## Offline Access Apps can be cached for offline access: ```go // Cache entire app for offline use PrefetchApp(scid) -> { app: CachedApp, message: "Cached for offline use" } // Check if cached IsAppCachedOffline(scid) -> bool ``` > [!NOTE] > Offline cache size is configurable (default 500MB). Oldest accessed apps are automatically evicted when space is needed. ### Sync Manager For power users, the **Sync Manager** (Settings → Sync Manager) enables: - **Batch Prefetch**: Clone all favorites with one click - **Rating Threshold**: Filter by minimum community rating - **Update Checking**: Compare cached vs on-chain versions - **Visual Diffing**: See exactly what changed before updating See [Offline-First Browsing](/offline-first.md) for complete documentation and [Privacy Mode](/security.md#privacy-mode) for network-level isolation. ## Content Filtering Hologram includes optional content filtering: | Setting | Description | Default | |---------|-------------|---------| | `min_rating` | Minimum app rating | 0 | | `block_malware` | Block dangerous apps | true | | `show_nsfw` | Show adult content | false | ## Navigation API For developers, the browser exposes these Go methods: ```go Navigate(scid string) map[string]interface{} GoBack() map[string]interface{} GoForward() map[string]interface{} Reload() map[string]interface{} FetchSCID(scid string) map[string]interface{} FetchByDURL(durl string) map[string]interface{} ``` --- --- title: "Sign In with DERO" description: "HOLOGRAM-exclusive: authenticate on any HTTPS website using your DERO wallet address — no extensions, no passwords, no seed phrases in the browser." --- # Sign In with DERO HOLOGRAM is the only DERO wallet that supports **wallet-based authentication on HTTPS websites**. Any website using the [DeroAuth](https://github.com/DHEBP/DeroAuth) SDK can let visitors sign in with their DERO wallet address — no browser extension, no seed phrase, no password. > [!NOTE] > **HOLOGRAM-exclusive feature.** This cannot be done with Engram, CyberDeck, or any other DERO wallet. HOLOGRAM is the only wallet that exposes the HTTP auth endpoints required for HTTPS-compatible sign-in. ## Why HOLOGRAM Only? Browsers enforce **mixed content restrictions**: an HTTPS page cannot open a `ws://` WebSocket connection to localhost. Every other DERO wallet communicates exclusively via the XSWD WebSocket protocol (`ws://127.0.0.1:44326/xswd`), which means they are unreachable from any production HTTPS website. HOLOGRAM solves this with a local **HTTP redirect endpoint** — the same pattern used by OAuth, Auth0, and SAML. No WebSocket required. | Wallet | Transport | Works on HTTPS? | |--------|-----------|-----------------| | **HOLOGRAM** | HTTP redirect (localhost) | **Yes** | | Engram | WebSocket only (`ws://`) | No — blocked by browser | | CyberDeck | WebSocket only (`ws://`) | No — blocked by browser | ## How It Works The flow follows the same OAuth-style redirect pattern used by "Sign in with Google/GitHub": ``` Website HOLOGRAM (localhost) ─────── ──────────────────── 1. User clicks "Sign In with DERO" 2. Browser redirects to ──────→ GET /auth?callback=...&nonce=...&domain=... 3. HOLOGRAM shows wallet approval modal 4. User clicks "Approve" 5. HOLOGRAM signs the challenge 6. Browser redirects back ←──── 302 → callback?signature=...&nonce=... 7. Server verifies signature 8. Session created — user is signed in ``` ### Step by Step 1. **Website redirects** — The site generates a nonce and redirects the browser to `http://127.0.0.1:44326/auth` with `callback`, `nonce`, and `domain` parameters. 2. **HOLOGRAM receives the request** — The local HTTP server serves a lightweight page that triggers the wallet approval flow. 3. **User approves** — HOLOGRAM's slide-in wallet modal shows the requesting domain and asks for approval. One click — no password entry, no seed phrase. 4. **HOLOGRAM signs** — Upon approval, HOLOGRAM constructs a [DeroAuth challenge message](/wallet.md#sign--verify-messages) containing the wallet address, domain, nonce, and timestamps, then signs it with the wallet's private key. 5. **Redirect back** — The browser redirects to the callback URL with the signature and nonce as query parameters. 6. **Server verifies** — The website's backend verifies the Schnorr signature against the DERO address. If valid, a session is created. ## What the User Sees 1. Click "Sign In with DERO" on any website 2. Browser briefly redirects to HOLOGRAM 3. HOLOGRAM's wallet modal slides in: *"deropay.com wants to verify your identity"* 4. Click **Approve** 5. Automatically redirected back to the website, now signed in The entire flow takes about 2–3 seconds. ## Security Properties | Property | Detail | |----------|--------| | **No secrets in the browser** | Private keys never leave HOLOGRAM. The website only receives a signature. | | **Replay protection** | The website supplies a nonce, which HOLOGRAM signs and returns unchanged. Single-use enforcement (storing and expiring the nonce) is the website backend's responsibility, per the DeroAuth SDK — HOLOGRAM does not store nonces. | | **Domain binding** | The challenge message includes the requesting domain — signatures cannot be reused across sites. | | **Time-bounded** | Challenge includes `Issued At` and `Expiration Time` timestamps. | | **No tracking** | No third-party services, no analytics, no cookies until the user explicitly signs in. | ## For Website Developers Integrate "Sign In with DERO" using the [DeroAuth SDK](https://github.com/DHEBP/DeroAuth): ```typescript const auth = new DeroAuthSigner({ hologramPort: 44326, }); // Redirects the browser to HOLOGRAM auth.signInViaRedirect(); ``` Server-side (Next.js example): ```typescript const { signinHandler, callbackHandler, sessionHandler, signoutHandler } = createDeroAuth({ secret: process.env.DERO_AUTH_SECRET }); ``` See the full [DeroAuth documentation](https://deropay.derod.org/dero-auth/overview) for setup instructions. ## For Other Wallet Developers The redirect auth protocol is **open and wallet-agnostic**. Any DERO wallet can support it by implementing two HTTP endpoints: ### `GET /auth` Accept query parameters: `callback` (URL), `nonce` (string), `domain` (string). Serve a page or UI that triggers user approval. ### `POST /auth/complete` Accept JSON body: `{ nonce, domain, uri }`. On user approval: 1. Construct the DeroAuth challenge message: ``` {domain} wants you to sign in with your DERO wallet: {address} Sign in to {domain} URI: {uri} Version: 1 Chain ID: dero-mainnet Nonce: {nonce} Issued At: {timestamp} Expiration Time: {timestamp} ``` 2. Sign the message with the wallet's private key. 3. Return `{ signature, address, nonce }` as JSON. The auth page then redirects the browser to `{callback}?signature={sig}&nonce={nonce}`. > [!NOTE] > If you're a wallet developer and want to add DeroAuth support, the protocol spec and reference implementation are available in the [HOLOGRAM source code](https://github.com/DHEBP/HOLOGRAM) (`xswd_server.go`). --- --- title: "Developer Support" description: "Support TELA app developers through the EPOCH passive hashing system - no ads, no data collection." --- # Developer Support ![Developer Support](/assets/support.png) Hologram includes the unique **EPOCH** developer support system, allowing you to support TELA app developers through minimal, passive CPU hashing—**without ads or data collection**. ## What is EPOCH? **E**vent-driven **P**ropagation of **O**pportunistic **C**rowd **H**ashing EPOCH enables dApps to request hash computations from users as a non-intrusive form of developer support—**without ads or data collection**. ### How It Works 1. You browse a TELA app that supports EPOCH (in the [TELA Browser](/browser.md)) 2. On user interactions (clicks, scrolls), the app may request hashes 3. Hologram computes a small number of hashes (imperceptible) 4. Valid hashes are submitted to the developer's address 5. You've supported the developer without seeing ads! 6. Rewards appear in the developer's [Wallet](/wallet.md#coinbase-transactions) as coinbase transactions > [!NOTE] > TELA developers: Test EPOCH in your apps using [Simulator Mode](/simulator.md) before deploying to mainnet. ### Key Characteristics | Aspect | Description | |--------|-------------| | **Purpose** | Developer support (rewards go to app developers) | | **Trigger** | User interaction events or passive background | | **Duration** | Millisecond bursts | | **Consent** | Opt-out (default ON) | | **CPU Impact** | Minimal (imperceptible) | | **Reward Recipient** | App developer's wallet | > [!NOTE] > By default, EPOCH hashing rewards go to the developer's address. However, some TELA apps now support **hash splitting**, allowing you to direct a portion of rewards to your own wallet while still supporting the developer. ## Configuration Access Developer Support settings in **Settings > Developer Support** (above About). ### Default Limits ```go const ( DEFAULT_EPOCH_MAX_HASHES = 100 // Per-request limit DEFAULT_EPOCH_MAX_THREADS = 2 // CPU threads RATE_LIMIT_WINDOW = 10s // Per-app rate limiting RATE_LIMIT_MAX_HASHES = 500 // Max per window ) ``` ### Controls | Function | Description | |----------|-------------| | `SetDevSupportEnabled(bool)` | Toggle developer support on/off | | `IsDevSupportEnabled()` | Check current setting | | `GetDevSupportStatus()` | Get unified status | | `GetDevSupportStats()` | Get contribution statistics | | `GetEpochStats()` | Session statistics | | `SetEpochConfig(maxHashes, maxThreads)` | Update limits | ## Fair Developer Support Address Switching When TELA dApps request developer support via `AttemptEPOCHWithAddr`, Hologram temporarily switches EPOCH rewards to the app developer's address, ensuring fair distribution of support. > [!NOTE] > **External XSWD Support:** The `AttemptEPOCHWithAddr` method is fully supported over the external XSWD WebSocket (port 44326), allowing external dApps to seamlessly request hash computations directed to their specific developer address, just like internal TELA apps. ### How It Works 1. **App requests support** — TELA app calls `AttemptEPOCHWithAddr` with developer address 2. **Hologram pauses background worker** — Stops passive hashing for Hologram's default address 3. **Switches to app address** — EPOCH connection switches to app developer's address 4. **Auto-switch back** — After 30 seconds of inactivity, switches back to Hologram's default address 5. **Background worker resumes** — Passive hashing continues for Hologram ### Sticky Timeout The address switching uses a **30-second sticky timeout**: - Each new request from the app resets the 30-second timer - As long as the app is actively requesting hashes, rewards go to the developer - After 30 seconds of no requests, automatically switches back to Hologram's default ### Address State API ```go // Get current EPOCH address info GetEpochAddressInfo() -> { current_address: "dero1qy...", // address currently receiving rewards default_address: "dero1qy...", // Hologram's default is_on_app_address: true, // true if on app developer's address last_app_request: "2026-01-03T12:00:00Z", seconds_until_switch: 12 // seconds before switching back to default } ``` ### Background Worker Behavior The background DevSupportWorker automatically pauses and resumes: - **Pauses** when switched to an app developer's address - **Resumes** when switched back to Hologram's default address - Ensures only one EPOCH connection is active at a time ### Example Flow ``` User browsing app.tela ↓ App calls AttemptEPOCHWithAddr(developerAddr) ↓ Hologram switches EPOCH to developerAddr ↓ Background worker pauses ↓ [User continues using app - requests keep coming] ↓ [30 seconds pass with no requests] ↓ Hologram switches back to default address ↓ Background worker resumes ↓ Default: Hologram gets support during idle time ``` > [!NOTE] > This system ensures fair distribution: app developers get support when users actively use their apps, while Hologram receives background support during idle periods. ## Passive Background Support The **DevSupportWorker** runs in the background when enabled, performing small hashing bursts during idle periods: - **Cycle Interval**: Every 5 seconds - **Hashes per Cycle**: 50 (configurable) - **Auto-Pause**: Pauses on battery, high CPU load, or no node connection - **Auto-Pause on Address Switch**: Pauses when EPOCH is switched to an app developer's address ### Pause Conditions The worker automatically pauses when: | Condition | Reason | |-----------|--------| | No node connection | Waiting for node connection | | On battery power | Preserving battery life | | High CPU load | System under heavy load | ## Statistics Tracking Developer Support tracks your contributions: ```go type DevSupportStats struct { TotalHashes uint64 // Lifetime hashes contributed TotalHashesStr string // "1.2M" formatted MiniBlocksFound int // Miniblocks found for developers UptimeSeconds int64 // Total active time SessionHashes uint64 // Current session hashes SessionMiniblocks int // Current session miniblocks SessionStart time.Time // When the current session started LastActive time.Time // Last time the worker did work TotalSessions int // Number of sessions IsRunning bool // Currently active IsPaused bool // Temporarily paused PauseReason string // Why paused } ``` ## DERO Miniblock System DERO uses a unique **miniblock system**: - 48-byte compact blocks - Multiple miners can contribute to single block - Rewards distributed proportionally - Lower barrier to earning (find miniblocks more often than full blocks) When Developer Support finds a miniblock, the reward goes to the TELA app developer whose app you're using. ## Rate Limiting Per-app rate limiting prevents abuse: ```go type rateLimitEntry struct { lastRequest time.Time hashCount uint64 window time.Duration } // Max 500 hashes per app per 10-second window ``` ## Privacy Considerations - **No tracking**: Your browsing activity is not logged - **No data collection**: Only hash computations, no personal data - **Opt-out available**: Disable anytime in Settings - **Transparent**: Stats show exactly what you've contributed ## FAQ ### Does this affect my computer's performance? No. EPOCH uses minimal CPU (2 threads max, millisecond bursts). Most users won't notice any impact. ### Do I earn anything from Developer Support? By default, rewards go to app developers. However, some TELA apps now support **hash splitting**, where you can configure a percentage of rewards to go to your own wallet. Check if the TELA app you're using supports this feature. ### Can I still mine DERO for myself? Yes! Use a dedicated mining tool: - [derohe-miner](https://github.com/deroproject/derohe) - Official DERO miner - Connect to your node's GetWork endpoint (default: `localhost:10100`) --- --- title: "Block Explorer" description: "Explore the DERO blockchain - blocks, transactions, smart contracts, and real-time analytics." --- # Block Explorer ![Block Explorer](/assets/explorer.png) Hologram includes a comprehensive blockchain explorer for viewing blocks, transactions, smart contracts, and network statistics. ## OmniSearch The Explorer landing page features **OmniSearch**, a universal search that intelligently detects and routes queries to the appropriate handler. ### Intelligent Hash Resolution When searching a 64-character hex string, OmniSearch automatically determines if it's a Smart Contract (SCID) or a standard Transaction (TXID). It does this by checking if the returned object contains actual smart contract `code`. If the code is empty, it intelligently falls back to displaying the standard transaction details, preventing misclassification. ### Non-Eager Autocomplete To provide a cleaner user experience, the OmniSearch input field features a non-eager autocomplete. While it focuses automatically on page load, the recent searches dropdown will only appear upon explicit user interaction (clicking the input), preventing the UI from feeling overly aggressive. ```mermaid flowchart LR INPUT["Search Input"] --> DETECT{Type Detection} DETECT -->|"64 hex"| HASH["Hash Lookup"] DETECT -->|"Number"| BLOCK["Block Height"] DETECT -->|"dero1..."| ADDR["Address Search"] DETECT -->|".tela"| DURL["dURL → Browser"] DETECT -->|"Text"| SEARCH["Full-Text Search"] DETECT -->|"key: value: code:"| PREFIX["Gnomon Query"] DETECT -->|"class: tag:"| CLASSIFY["Classification Query"] HASH --> SCID["Smart Contract"] HASH --> TX["Transaction"] BLOCK --> RESULT["Display Result"] ADDR --> RESULT SCID --> RESULT TX --> RESULT SEARCH --> RESULT PREFIX --> RESULT CLASSIFY --> RESULT DURL --> BROWSER["TELA Browser"] ``` ### Search Syntax | Input Format | Example | Action | |--------------|---------|--------| | **64-char hex** | `abc123...def456` | Detect as SCID or TX hash | | **Block height** | `5000000` | Load block at height | | **DERO address** | `dero1qy...` | Search address references | | **dURL** | `myapp.tela` | Navigate to Browser with app | | **Name** | `alice` | Resolve via NRS | | **Free text** | `voting app` | Search TELA apps by name/description | | **Prefix query** | `key:owner` | Advanced search (see below) | ### Advanced Search Prefixes Power users can use special prefixes for targeted searches. These query the Gnomon indexer directly. | Prefix | Example | Description | |--------|---------|-------------| | `key:` | `key:owner` | Search SC state variables by key name | | `value:` | `value:TELA` | Search SC state variables by stored value | | `code:` | `code:STORE` | Search SC source code for patterns | | `class:` | `class:TELA-INDEX-1` | List all SCIDs in a specific class | | `tag:` | `tag:g45` | List all SCIDs matching a tag | ``` // Examples key:owner → Find all SCs with an "owner" variable value:TELA-INDEX → Find all SCs storing "TELA-INDEX" in a value code:STORE("votes" → Find SCs with voting logic in their code class: → List all known SC classes (empty query) class:TELA-INDEX-1 → Find all TELA INDEX contracts tag:epoch → Find all EPOCH-enabled apps ``` > [!NOTE] > The `class:` prefix with no argument returns all known smart contract classes. The `tag:` prefix queries the tag classification system — see [TELA Browser > Tag-Based App Discovery](/browser.md#tag-based-app-discovery) for available tags. > [!NOTE] > Found a TELA app? Click the app icon to view it in the [TELA Browser](/browser.md), or use [Version History](#time-travel-state-viewer) to explore its deployment timeline. ### Search Exclusions Filter out unwanted results from your searches: 1. Go to **Settings > Gnomon** 2. Find **Search Exclusions** section 3. Add SCIDs or patterns to exclude ```go // API AddSearchExclusion(filter string) -> { success: true } RemoveSearchExclusion(filter string) -> { success: true } GetSearchExclusions() -> { filters: ["scid1...", "scid2..."] } ClearSearchExclusions() -> { success: true } ``` ### Min-Likes Filter Filter search results by minimum approval rating: 1. Go to **Settings > Gnomon** 2. Adjust the **Minimum Likes %** slider 3. Results below threshold are hidden ```go SetSearchMinLikes(percent int) -> { success: true } ``` ### Recent Searches The landing page displays your recent searches for quick access: - Click any recent search to re-run it - Searches are stored locally - Clear history from the search bar ## Block Exploration ### View Blocks | Function | Description | |----------|-------------| | `GetBlock(height)` | Basic block data by height | | `GetBlockByHash(hash)` | Block data by hash | | `GetBlockExtended(heightOrHash)` | **Full block metadata** (tips, nonce, size, fees, miner, status) | | `GetRecentBlocks(count)` | Last N blocks | | `FormatBlockAge(timestamp)` | "5m 23s ago" format | ### GetBlockExtended Response Returns comprehensive block data matching official DERO explorer: ```go { // Core identifiers height, topoheight, hash, // Block metadata depth, difficulty, nonce, major_version, minor_version, // Status flags orphan_status, sync_block, side_block, // DAG structure tips: []string, // Parent block hashes // Mining info miners: []string, miner_address: string, // Extracted from coinbase TX reward: uint64, // Timing timestamp, age, block_time, // Transactions tx_count, tx_hashes: []string, txs: []TxSummary, // Type, fee per TX total_fees: uint64, // Size size_bytes, size_kb, // Raw data blob: string, } ``` ### Block Data Each block includes: - Block header (hash, height, timestamp, difficulty) - TopoHeight (position in DAG) - Tips (parent blocks in DAG structure) - Depth (confirmations) - Status flags (orphan, sync, side block) - Miner address (extracted from coinbase TX) - Miner transaction (coinbase) - Transaction list with types and fees - Total fees and block size ## Transaction Exploration ### View Transactions | Function | Description | |----------|-------------| | `GetTransaction(txid)` | Basic transaction details | | `GetTransactionWithRings(txid)` | TX + ring members | | `GetTransactionExtended(txid)` | **Full TX data** (rings per payload, assets, valid/invalid blocks, hex) | | `GetCoinbaseMiner(txid)` | Extract miner from coinbase TX | | `GetRingMembers(txid)` | Ring signature members | ### GetTransactionExtended Response Returns comprehensive transaction data matching official DERO explorer: ```go { txid, tx_type, // Status in_pool, ignored, is_coinbase, // Block info block_height, valid_block, invalid_blocks: []string, // Timing age, block_time, // Build info height_built, blid, root_hash, // Addresses miner_address, signer, // Economics fee, reward, burn_value, balance, // Ring members PER PAYLOAD (critical for privacy) rings: []PayloadRing{ index: int, members: []string, // Full addresses count: int, }, ring_count, max_ring_size, // Assets breakdown PER PAYLOAD assets: []Asset{ index: int, scid: string, fees: uint64, burn: uint64, ring_size: int, ring: []string, }, // Smart Contract data sc_args, sc_code, sc_balance, sc_balance_now, sc_code_now, // Size size_bytes, size_kb, // Raw data hex: string, output_indices, } ``` > [!NOTE] > **Ring members per payload** is critical for understanding DERO's privacy model. Each payload (asset transfer) has its own ring of decoy addresses, providing plausible deniability. ### Transaction Types ```go const ( PREMINE // Genesis allocation REGISTRATION // Address registration COINBASE // Mining reward NORMAL // Standard transfer BURN_TX // Token burn SC_TX // Smart contract interaction ) ``` ## Proof Validation Hologram validates payload proofs before display to prevent fake/fabricated proofs with impossible amounts. This feature is critical for merchants and service providers who need cryptographic proof of payment. See the dedicated [Proof Validation](/proof-validation.md) page for detailed documentation. ### What This Blocks | Attack Type | Result | |-------------|--------| | 184 trillion DERO proofs | **REJECTED** | | Any amount > 22M DERO | **REJECTED** | | int64 wraparound attacks | **REJECTED** | | Amounts > current supply (~16.5M) | WARNING | | Large amounts (> 1M DERO) | INFO | ### Validation Functions ```go // Block proofs with impossible amounts ValidatePayloadProofAmount(amount uint64) error // Get detailed validation with warnings ValidatePayloadProofAmountWithContext(amount uint64) -> { valid: bool, error: string, warnings: []string, supplyContext: string // "12.5% of current DERO supply" } // Flag suspicious but valid amounts DetectSuspiciousProofPatterns(amount uint64) -> []string ``` ### Constants ```go const ( MAX_INT64_SAFE = 9223372036854775807 // 2^63 - 1 MAX_REASONABLE_AMOUNT_ATOMIC = 2_200_000_000_000 // 22M DERO (22_000_000 * 100_000) DERO_HARD_CAP_ATOMIC = 2_100_000_000_000 // 21M DERO (21_000_000 * 100_000) ) ``` > [!NOTE] > DERO has a permanent hard cap of 21 million (like Bitcoin). Any proof claiming more than 21M DERO is mathematically impossible, not just suspicious. ### UI Features - Supply context display: "12.5% of current DERO supply" - Warning panel for suspicious patterns (AlertTriangle icon) - "Proof Rejected" with security note for fabricated proofs (Shield icon) See [Proof Validation Security](/proof-validation.md) for detailed documentation. ## Smart Contract Interaction ### View Smart Contracts ```go GetSCInfo(scid) -> { code: string, // DVM bytecode balance: uint64, // SC balance variables: map, // All stored variables } DaemonGetSC(scid) // Direct daemon call ``` ### TELA INDEX Detection When viewing a smart contract, Hologram automatically detects if it's a TELA INDEX (by checking for `DOC1` or `dURL` variables). When detected, a **VERSION CONTROL** panel appears with: - **TELA INDEX** badge - **View Version History** button - Opens commit timeline modal - **Open in Studio** button - Jump to Studio Actions page > [!NOTE] > TELA INDEXes have Git-like version control. Each update creates a commit; **View Version History** opens the commit timeline so you can compare versions, and **Open in Studio** jumps to the Studio Actions page. See [Studio > Actions](/studio.md#actions-version-control) for full documentation. > {/* removed: scid@txid retrieval not wired in Explorer as of 2026-06-12 (Studio Clone only); restore if built */} ### Invoke Smart Contracts ```go // Invoke SC function (requires wallet approval) InvokeSCFromExplorer(scid, entrypoint, args, deposit) -> txid // Specific actions RateTELAApp(scid, rating) // 0-99 rating LikeTELAApp(scid) DislikeTELAApp(scid) ``` ### Gas Estimation ```go EstimateSCGas(scid, entrypoint, args) -> { gascompute: uint64, gasstorage: uint64, total: uint64, cost_dero: string, } ``` ## Smart Contract Function Interactor > [!NOTE] > Dynamically discover and call smart contract functions without writing code. The interactor parses DVM bytecode to auto-generate input forms. When viewing any smart contract in Explorer, a **Call Smart Contract Function** panel appears below the SC Variable Editor. This feature: 1. **Parses DVM code** to discover all exported functions (uppercase first letter) 2. **Auto-generates input fields** based on parameter types (String or Uint64) 3. **Detects special requirements**: - `DEROVALUE()` - Shows DERO amount input - `ASSETVALUE()` - Shows token SCID and amount inputs - `SIGNER()` - Disables anonymous mode (ringsize 16) 4. **Works with local wallet or XSWD** - No wallet? Connect via XSWD ``` +----------------------------------------------------------+ | [Zap] Call Smart Contract Function | +----------------------------------------------------------+ | Function: [Deposit(amount: Uint64) v] | +----------------------------------------------------------+ | PARAMETERS | | +------------------------------------------------------+ | | | amount [Uint64] | | | | [_________________________] (number input) | | | +------------------------------------------------------+ | +----------------------------------------------------------+ | [DEROVALUE] DERO Amount to Send | | [_____________] DERO | +----------------------------------------------------------+ | [ ] Anonymous transaction (ringsize 16) | | ! SIGNER() detected - anonymous mode disabled | +----------------------------------------------------------+ | [ Call Deposit ] | +----------------------------------------------------------+ ``` ### Parse Functions ```go ParseSCFunctions(scid) -> { success: bool, functions: []SCFunction{ name: string, // "Deposit" params: []SCParam{ name: string, // "amount" type: string, // "Uint64" or "String" dataType: string, // "U" or "S" for XSWD }, returnType: string, // "Uint64" usesDero: bool, // DEROVALUE() detected usesAsset: bool, // ASSETVALUE() detected usesSigner: bool, // SIGNER() detected }, count: int, } ``` ### Invoke Functions ```go InvokeSCFunction(paramsJSON) -> { success: bool, txid: string, function: string, message: string, } // paramsJSON structure: { scid: "abc123...", function: "Deposit", params: { "amount": 1000 }, deroAmount: 100000, // Atomic units (0.001 DERO) assetScid: "", // Token SCID if sending asset assetAmount: 0, anonymous: false, // Use ringsize 16 } ``` ### Install Smart Contracts Deploy new smart contracts directly from Hologram: ```go InstallSmartContract(code, anonymous) -> { success: bool, txid: string, message: string, } ``` > [!WARNING] > Smart contract deployment requires a local wallet (not XSWD). The SCID will be available once the transaction is confirmed. ## Time-Travel Explorer View smart contract state at any point in history using Graviton's versioning. > [!NOTE] > **Time-Travel** lets you see exactly what a smart contract looked like at any block height—compare changes, track variable evolution, and audit contract history. ```mermaid flowchart LR H1["Height 1000 Deploy"] --> H2["Height 2500 Update"] H2 --> H3["Height 4000 Update"] H3 --> NOW["Current State"] H2 --> DIFF["State Diff"] H3 --> DIFF ``` ### State Capture ```go // Capture current state CaptureSCState(scid) -> SCStateSnapshot // Retrieve historical state GetSCStateAtHeight(scid, height) -> SCStateSnapshot ``` ### State Comparison ```go // Compare two heights CompareSCStateAtHeights(scid, from, to) -> SCStateDiff // Get change timeline GetSCChangeTimeline(scid) -> []SCStateDiff ``` ### SC Watching Watch smart contracts to automatically capture state snapshots when changes occur. #### Watch Button (Header) When viewing any smart contract in Explorer, a **Watch** button appears directly in the SC header alongside the balance: ``` ┌──────────────────────────────────────────────────────────────┐ │ ◎ SMART CONTRACT │ │ 0.00500 DERO │ View as TX │ Watch │ └──────────────────────────────────────────────────────────────┘ ``` - **Watch** (Eye icon) — Adds the SC to your watch list and captures the current state - **Watching** (EyeOff icon, cyan) — Indicates SC is being watched; click to unwatch This provides one-click access to the Time Machine watch feature without needing to expand the Time Machine panel. #### Watch/Unwatch in Time Machine Panel The **Time Machine** panel (further down the SC view) also includes Watch/Unwatch controls: - **Watch** — Adds the SC to your watch list and captures the current state - **Unwatch** — Removes the SC from your watch list #### Automatic Snapshot Capture When a watched SC changes: 1. **State change detected** — Hologram monitors watched SCs for variable changes 2. **Snapshot captured** — Current state is automatically saved 3. **Timeline updated** — New snapshot appears in the change timeline 4. **Notification** — You can see which SCs have changed in Settings > Gnomon #### Watched SCs Management Manage your watch list in **Settings > Gnomon > Time Machine Watch List**: - View all watched SCs with their names and change counts - See when each SC was last checked - Unwatch SCs you no longer want to monitor - Refresh all watched SCs to check for changes ```go // Watch SC for changes WatchSmartContract(scid, name) -> { success: true, message: "Now watching abc123..." } // Unwatch SC UnwatchSmartContract(scid) -> { success: true } // Get all watched SCs GetWatchedSmartContracts() -> { success: true, watched: [ { scid: "abc123...", name: "My App", watched_since: "2026-01-03T10:00:00Z", last_checked: "2026-01-03T12:00:00Z", last_change: "2026-01-03T11:30:00Z", change_count: 3 }, ... ], count: 2 } // Manually refresh all watched SCs RefreshWatchedSCs() -> { success: true, changes_detected: 1 // Number of SCs that changed } ``` ### State Diff Structure ```go type SCStateDiff struct { SCID string FromHeight uint64 ToHeight uint64 BalanceDiff int64 Changes []SCStateChange TotalAdded int TotalModified int TotalRemoved int CodeChanged bool } ``` ## Historical Variable Timeline > [!NOTE] > View smart contract variable snapshots at any point in history using an interactive timeline slider. When viewing a smart contract in Explorer, a **Historical Timeline** panel shows all recorded state changes. Use the slider to travel back in time and see exactly what variables looked like at each snapshot. ### Change Timeline The timeline displays a chronological list of all state changes: - **Block height ranges** — Shows when changes occurred - **Change counts** — Number of variables added, modified, or removed - **Code change indicators** — Visual markers when contract code changed - **Visual timeline** — Interactive display of change history Each timeline entry shows: - Height range (from → to) - Timestamp of the change - Number of variables added/modified/removed - Balance changes (if any) ``` +----------------------------------------------------------+ | [History] HISTORICAL TIMELINE | +----------------------------------------------------------+ | [o--------o--------o--------o--------o] Height Slider | | 1000 2500 4000 5500 Current | +----------------------------------------------------------+ | Viewing state at height: 4000 | | +------------------------------------------------------+ | | | owner | dero1qy...abc | | | | balance | 50000 | | | | status | "active" | | | +------------------------------------------------------+ | +----------------------------------------------------------+ ``` ### Timeline API ```go // Get the change timeline for an SC GetSCChangeTimeline(scid) -> { success: bool, timeline: []SCStateDiff, count: int, } // Get SC state at a specific height GetSCStateAtHeight(scid, height) -> { success: bool, height: int64, variables: { stringkeys: map[string]string, uint64keys: map[string]uint64, }, } // Compare state between two heights CompareSCStateAtHeights(scid, from, to) -> { success: bool, from: uint64, to: uint64, added: []SCStateChange, modified: []SCStateChange, removed: []SCStateChange, codeChanged: bool, } ``` > [!NOTE] > Historical snapshots are stored locally and persist across sessions. Use the Watch feature to automatically capture snapshots when changes occur. ## Network Statistics ```go GetMempoolTransactions() // Basic pending transaction list GetMempoolExtended(max) // Detailed mempool with full TX info GetNetworkInfo() // Chain height, difficulty, peers GetBlockchainStats() // Comprehensive stats ``` ### GetMempoolExtended Response Returns detailed mempool data for the Mempool Browser: ```go { txs: []MempoolTx{ hash, type, fee, fee_dero, size_bytes, size_kb, ring_size, ring_count, signer, in_pool, }, count: int, // Returned count total_count: int, // Actual mempool size truncated: bool, // If > maxCount // Aggregate stats total_fees, total_fees_dero, total_size_bytes, total_size_kb, // Type breakdown type_stats: { NORMAL: int, SC: int, BURN: int, OTHER: int, }, } ``` > [!NOTE] > The Mempool Browser in Explorer shows all pending transactions with their type, fee, size, and ring size. Click any TX to view full details. ## Address Search Due to DERO's privacy features, full TX history requires wallet access: ```go SearchAddress(address) -> { ownedSCIDs: [] // SCIDs where address is owner } GetAddressSCIDReferences(address) // SCIDs where address appears ``` ## Name Resolution ### NRS Cache Bidirectional name-to-address caching: ```go // Forward lookup (name -> address) ResolveDeroName(name) -> address // Reverse lookup (address -> name) GetNameForAddress(address) -> name // Cache management GetNRSCacheStats() GetAllCachedNames() ``` ### Lookup Flow ```mermaid flowchart TD INPUT["User enters 'alice'"] --> CACHE{NRS Cache Check} CACHE -->|"Hit"| RETURN["Return Address (instant)"] CACHE -->|"Miss"| RPC["Query DERO.NameToAddress RPC"] RPC --> STORE["Cache Result (bidirectional)"] STORE --> RETURN ``` --- --- title: "Installation" description: "Download and install Hologram on macOS, Linux, or Windows." --- # Installation Hologram is available for macOS, Linux, and Windows. ## System Requirements - **OS**: macOS 10.15+, Windows 10+, or Linux (glibc 2.17+) - **RAM**: 4GB minimum, 8GB recommended - **Storage**: 500MB for application, additional space for blockchain data - **Network**: Internet connection for blockchain sync ## Download Download the latest release from the [GitHub Releases](https://github.com/DHEBP/HOLOGRAM/releases) page. | Platform | Architecture | File | |----------|--------------|------| | macOS | Universal (Intel + Apple Silicon) | `Hologram-v*-macos-universal.zip` | | Linux | x64 | `Hologram-v*-linux-amd64.tar.gz` | | Windows | x64 | `Hologram-v*-windows-amd64.zip` | Each archive ships with a matching `.sha256` checksum file if you'd like to verify the download. ## Installation Steps ### macOS ### Download the archive Download `Hologram-v*-macos-universal.zip` from the Releases page. The universal binary runs natively on both Intel and Apple Silicon. ### Unzip Double-click the downloaded `.zip` to extract `Hologram.app`. ### Move to Applications Drag `Hologram.app` to your `/Applications` folder. ### First Launch Right-click `Hologram.app` and select **Open** for the first launch (required for unsigned apps). > [!WARNING] > On macOS, you may need to allow the app in **System Settings > Privacy & Security** if you see a security warning on first launch. ### Linux ### Download the archive Download `Hologram-v*-linux-amd64.tar.gz` from the Releases page. ### Extract ```bash tar -xzf Hologram-v*-linux-amd64.tar.gz ``` ### Run ```bash ./Hologram ``` > [!NOTE] > Linux builds currently target `glibc 2.35+` (Ubuntu 22.04 build host). If your distribution ships an older glibc, use [Build from Source](#building-from-source) below. ### Windows ### Download the archive Download `Hologram-v*-windows-amd64.zip` from the Releases page. ### Extract Right-click the `.zip` and choose **Extract All…**, or use your preferred archive tool. ### Run Double-click `Hologram.exe` to launch. > [!WARNING] > Windows SmartScreen may show an "unrecognized app" warning on first launch. Click **More info → Run anyway** — the release is unsigned for v1.0.x. ## First Run Wizard On first launch, Hologram runs a **First Run Wizard** that auto-detects your environment before presenting options. ### Automatic Detection The wizard automatically checks for: 1. **Running nodes** — Scans for an existing `derod` process on default ports 2. **Installed daemon** — Checks if `derod` binary is already on your system 3. **Blockchain data** — Looks for existing blockchain databases at known locations If a running node is found, the wizard offers to connect to it immediately. ### Setup Options After detection, you're presented with the appropriate choices: | Option | When Shown | What It Does | |--------|-----------|--------------| | **Start Embedded Node** | `derod` found on system | Launches your local daemon with optional blockchain location selection | | **Connect to External Node** | Always | Enter a remote node address (e.g., `http://192.168.1.1:10102`) and test the connection | | **Skip to Simulator** | Always | Starts a local simulator environment for development — no real DERO needed | ### External Node Connection When connecting to a LAN or remote node: 1. Enter the node endpoint (e.g., `http://192.168.1.1:10102`) 2. Click **Test & Connect** — Hologram verifies the node is reachable and returns chain info 3. On success, the endpoint is saved and Hologram connects automatically on future launches ### Developer Support (EPOCH) After node setup, the wizard shows a brief introduction to [Developer Support (EPOCH)](/developer-support.md): - Explains how passive hashing supports TELA app developers - Option to **enable** or **skip** Developer Support - Can be changed later in Settings > Developer Support ### After Setup Once the wizard completes, Hologram saves your preferences and proceeds to the main application. You can then: - [Create or import a wallet](/wallet.md) - [Browse TELA apps](/browser.md) (read-only, no wallet needed) - [Start developing](/studio.md) with the local dev server > [!NOTE] > The wizard only runs once. To reconfigure your node connection later, go to **Settings > Node**. ## Building from Source For developers who want to build from source: ```bash # Clone the repository git clone https://github.com/DHEBP/HOLOGRAM.git cd HOLOGRAM # Install frontend dependencies cd frontend && npm install && cd .. # Download Go dependencies go mod download # Build for development wails dev # Build for production wails build ``` ### Build All (Including Dependencies) To build Hologram along with derod and simulator binaries from DERO source: ```bash # Build everything from source make all ``` This builds: - **Hologram** - The main application - **derod** - DERO daemon (from derohe source) - **simulator** - DERO simulator (from derohe source) All binaries are placed in `build/bin/` alongside the Hologram executable. > [!NOTE] > Building from source eliminates the need to download pre-built binaries and ensures you have matching versions of all components. ### Build Requirements - Go 1.24.0+ - Node.js 18+ - Wails CLI v2 (`go install github.com/wailsapp/wails/v2/cmd/wails@latest`) - Platform-specific requirements (see Wails documentation) ### Linux Dependencies On Linux, you need GTK and WebKit development libraries: ```bash # Ubuntu/Debian sudo apt install libgtk-3-dev libglib2.0-dev libwebkit2gtk-4.0-dev # Arch Linux sudo pacman -S gtk3 glib2 webkit2gtk ``` ## Next Steps - [Quick Start](/quick-start.md) - Configure Hologram and browse your first dApp - [Wallet Setup](/wallet.md) - Create or import a DERO wallet - [Developer Support](/developer-support.md) - Support TELA developers through EPOCH --- --- title: "Local Dev Server" description: "Hot-reload development of TELA applications directly within Hologram." --- # Local Dev Server The **Local Dev Server** enables hot-reload development of TELA applications directly within Hologram—before deploying to the blockchain. > [!NOTE] > Combine [Simulator Mode](/simulator.md) with Studio's Local Dev Server for the ultimate development workflow: hot-reload your app locally, then deploy to Simulator for blockchain testing. ## Features - **HTTP File Server**: Serves local directory on `127.0.0.1`, first free port in the `50080-51000` range - **Hot Reload**: Automatic browser refresh on file changes - **File Watcher**: Uses `fsnotify` to detect changes - **CORS Support**: Proper headers for local development - **MIME Types**: Correct content types for web files - **telaHost Bridge**: Full native API available during development ## Quick Start 1. Navigate to **Studio** tab 2. Click **Start Local Dev Server** 3. Select your project directory 4. Start developing with instant reload! ## Local Dev Server API | Function | Description | |----------|-------------| | `StartLocalDevServer(directory)` | Start serving a local directory | | `StopLocalDevServer()` | Stop the dev server | | `GetLocalDevServerStatus()` | Running state, URL, port, directory | | `RefreshLocalDevServer()` | Manual refresh trigger | ## Start Server Response ```go StartLocalDevServer("/path/to/tela-app") -> { success: true, url: "http://127.0.0.1:50080", port: 50080, directory: "/path/to/tela-app", message: "Local dev server started" } ``` ## Status Response ```go GetLocalDevServerStatus() -> { running: true, url: "http://127.0.0.1:50080", port: 50080, directory: "/path/to/tela-app", watcherActive: true } ``` ## File Watcher Details ### Watched Extensions - `.html`, `.htm`, `.css`, `.js`, `.mjs`, `.json` - `.svg`, `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.ico` - `.woff`, `.woff2`, `.ttf` ### Ignored Directories - `node_modules`, `vendor`, `__pycache__` - Hidden directories (starting with `.`) ### Debounce 300ms delay to prevent rapid-fire reloads during save operations. ## Event Emission On file change, emits `localdev:reload` event to frontend: ```javascript // Frontend listens for reload events runtime.EventsOn("localdev:reload", (data) => { console.log(`File changed: ${data.file}`); // Refresh iframe content }); ``` ## Development Workflow ### Basic HTML/CSS/JS Development 1. Create your project structure: ``` my-tela-app/ |-- index.html |-- styles.css +-- app.js ``` 2. Start the local dev server pointing to this directory 3. Edit files—changes appear instantly 4. When ready, use Studio to deploy to simulator or mainnet ### Using telaHost During Development Even in local dev mode, `telaHost` is available: ```javascript // Check connection if (typeof telaHost !== 'undefined') { // Works in local dev mode too! const info = await telaHost.getNetworkInfo(); console.log('Height:', info.topoheight); } ``` > [!NOTE] > For wallet operations during development, start Simulator Mode alongside the Local Dev Server. ### Combined with Simulator Mode For full development experience: 1. **Start Simulator Mode** (Settings > Developer) 2. **Start Local Dev Server** (Studio tab) 3. Develop with: - Instant file reload - Working `telaHost` API - Test DERO for transactions - Smart contract deployment ## Project Structure Recommendations ### Minimal TELA App ``` my-app/ |-- index.html # Entry point |-- style.css # Styles +-- app.js # Logic ``` ### Larger Application ``` my-app/ |-- index.html |-- css/ | |-- main.css | +-- components.css |-- js/ | |-- app.js | |-- telahost-utils.js | +-- components/ +-- assets/ |-- logo.svg +-- images/ ``` ## Tips for TELA Development ### 1. Use Relative Paths ```html ``` ### 2. Handle telaHost Gracefully ```javascript // Wrapper for telaHost availability const deroApi = { async getInfo() { if (typeof telaHost === 'undefined') { console.warn('Not in Hologram, using mock data'); return { topoheight: 0, testnet: true }; } return await telaHost.getNetworkInfo(); } }; ``` ### 3. Size Optimization TELA has size limits. During development: - Watch your file sizes - Compress images (use SVG where possible) - Minify before deployment - Consider gzip compression ### 4. Test Offline Behavior Since TELA apps can be cached offline: - Test with daemon disconnected - Handle failed API calls gracefully - Cache important data locally ## Troubleshooting ### Server Won't Start - Check that ports in the `50080-51000` range are available - Try a different directory - Restart Hologram ### Changes Not Reflecting - Check file extension is in watched list - Manually trigger refresh - Check file is saved ### telaHost Not Available - Ensure you're viewing through Hologram (not external browser) - Check browser console for errors - Verify daemon connection --- --- title: "Offline-First Browsing" description: "Clone, cache, and diff TELA apps locally for instant access without network dependency." --- # Offline-First Browsing ![Offline-First Browsing](/assets/offline.png) Hologram enables true offline-first TELA browsing. Clone your favorite dApps locally, cache them in Graviton storage, and access them instantly—no network, no Gnomon, no waiting. > [!NOTE] > **Your data, your machine, your rules**. Once synced, TELA apps load from local storage with zero network latency. Combine with [Privacy Mode](/security.md#privacy-mode) for complete network isolation. ## Why Offline-First? | Traditional Web | Hologram Offline-First | |-----------------|------------------------| | Fetch from server every time | Cached locally in Graviton | | Requires network connection | Works completely offline | | Depends on external services | Self-sovereign operation | | Servers can go down | Content lives on your machine | | CDNs track your requests | Zero network fingerprinting | ## How It Works 1. **Favorite apps** in the Browser's app discovery 2. **Sync Manager** fetches and caches them locally (filtered by rating) 3. **Graviton storage** holds the cached content 4. **TELA Browser** loads instantly from local cache ## Getting Started ### Favorite Your Apps Browse TELA apps in the [TELA Browser](/browser.md) and click the heart icon to add them to your favorites. Favorites are stored locally and persist across sessions. ### Open Sync Manager Navigate to **Settings → Sync Manager** to access batch sync controls. ### Configure Rating Threshold Use the slider to set a minimum rating (0-99). Apps rated below this threshold will be skipped during sync—useful for filtering out low-quality or potentially malicious content. ### Sync Favorites Click **"Sync Favorites"** to batch-prefetch all favorited apps that meet your rating threshold. For each favorite app: 1. Resolve dURL to SCID 2. Check rating against threshold 3. If passes: fetch from blockchain → store in cache 4. If fails: skip ## Sync Manager Features ### Batch Prefetch Prefetch all favorites in one operation: ```go BatchPrefetchFavorites(favorites, minRating) → { success: true, total: 9, prefetched: 5, already_cached: 3, skipped: 1, // Below rating threshold failed: 0, duration_ms: 2340, results: [ { scid: "abc...", status: "prefetched", name: "...", version: 3 } ] } ``` ### Update Checking Compare all cached apps against their current on-chain versions: ```go CheckAllForUpdates() → { success: true, total_checked: 8, updates_found: 2, failed_checks: 0, duration_ms: 1820, apps: [ { scid: "abc...", cached_version: 3, onchain_version: 5, has_update: true }, { scid: "def...", cached_version: 7, onchain_version: 7, has_update: false } ] } ``` > [!WARNING] > Update checking requires a connection to a DERO daemon to fetch current SC state. Once you've reviewed and accepted updates, you're back to fully offline operation. ### Visual Diffing Before updating, view exactly what changed: ```go DiffCachedVsOnChain(scid) → { success: true, has_changes: true, lines_added: 42, lines_removed: 12, lines_modified: 8, cached_size: 8192, onchain_size: 9540, diff: [ { type: "added", line: 15, content: "const newFeature = true;" }, { type: "removed", line: 22, content: "// old comment" } ] } ``` The diff viewer shows: - **Green (+)**: New lines added - **Red (-)**: Lines removed - **Yellow (~)**: Lines modified ### Selective Updates You're always in control: - Review diffs before updating - Update individual apps (not all-or-nothing) - Keep your preferred version indefinitely - Roll back by re-cloning at specific commit ## Offline Cache Management ### Settings → Offline Cache The Offline Cache Manager shows: | Stat | Description | |------|-------------| | **Cached Apps** | Number of apps stored locally | | **Files** | Total file count across all apps | | **Used** | Current cache size | | **Max Size** | Configurable limit (default 500MB) | ### Cache Behavior - **LRU Eviction**: Oldest-accessed apps are removed when space is needed - **Complete vs Partial**: Full app caches include all assets - **Version Tracking**: Each cached app tracks its blockchain version - **Content Hashing**: SHA256 verification ensures integrity ### API Reference #### Prefetch ```go // Cache a single app PrefetchApp(scid string) → { success: true, app: CachedApp, message: "Cached AppName for offline use" } // Batch cache favorites BatchPrefetchFavorites(favorites []map, minRating int) → BatchSyncResult ``` #### Query ```go // Check if app is cached IsAppCachedOffline(scid string) → { cached: bool, app: CachedApp } // Get all cached apps GetCachedApps() → { apps: []CachedApp, count: int } // Get cache statistics GetOfflineCacheStats() → { stats: CacheStats, max_size: 524288000, usage_percent: 42.5 } ``` #### Manage ```go // Remove specific app RemoveCachedApp(scid string) → { success: true } // Clear entire cache ClearOfflineCache() → { success: true, message: "Cache cleared" } // Update cached app to latest UpdateCachedApp(scid string) → { success: true, updated: true } ``` ## Version Control Integration TELA's built-in commit system enables powerful version control: ### Cached Version Tracking Each cached app stores: ```go type CachedApp struct { SCID string // App identifier Version int // Cached commit number OnChainVersion int // Latest blockchain version HasUpdate bool // True if update available LastSyncCheck time.Time // When we last checked ContentHash string // SHA256 for verification } ``` ### Clone at Commit For filesystem access (vs Graviton cache), use Clone with version pinning: ``` scid@txid → Clone at specific commit ``` This downloads the exact version specified, regardless of current on-chain state. ## Security Considerations ### Rating Threshold The minimum rating filter provides a first-line defense: | Rating | Typical Meaning | |--------|-----------------| | 0-9 | Flagged as malicious | | 10-49 | Unverified/new apps | | 50-79 | Community-vetted | | 80-99 | Highly trusted | > [!WARNING] > Ratings are community-driven and not a guarantee of safety. Always review diffs before updating and be cautious with apps from unknown developers. ### Content Verification - All cached content is fetched from immutable blockchain storage - Content hashes can verify integrity - Diffing shows exact changes before updating - You control when (and if) to update ## Performance | Operation | Typical Time | |-----------|--------------| | Load cached app | < 50ms | | Check single app for updates | ~200ms | | Batch check 10 apps | ~1.5s | | Prefetch single app | 1-3s | | Batch prefetch 10 apps | 10-30s | > [!NOTE] > After initial sync, apps load from local Graviton storage in under 50ms—faster than any CDN. ## Use Cases ### Daily Driver Setup 1. Favorite your essential dApps 2. Sync with rating threshold 50+ 3. Check for updates weekly 4. Review diffs before updating ### Air-Gapped Operation 1. Sync favorites on connected machine 2. Transfer Graviton cache to air-gapped system 3. Run Hologram completely offline 4. Periodically connect to sync updates ### Version Pinning 1. Find stable version of critical app 2. Clone at that commit (`scid@txid`) 3. Never auto-update 4. Manually review all updates before applying ## Benefits Offline-first browsing provides: - **Self-sovereignty**: Your apps, your machine, your rules - **Privacy**: No network requests after sync - **Resilience**: Works when network is down - **Verification**: See exactly what changed before updating - **Control**: You decide when to update (or not) --- --- title: "Overview" description: "Understanding Hologram's architecture, components, and core capabilities." --- # Overview ![Hologram Overview](/assets/overview.png) Hologram is a comprehensive desktop application that provides complete access to the DERO blockchain ecosystem. ## Architecture ``` ┌───────────────────────────────────────────────────────────┐ │ Frontend (Svelte) │ │ Explorer | Browser | Wallet | Studio | Settings │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Backend (Go / Wails) │ │ │ │ Daemon Client | Gnomon | Wallet Manager | XSWD │ │ │ │ ┌───────────────────────────────────────────────┐ │ │ │ │ │ Storage (Graviton) │ │ │ │ │ │ TELA Cache | NRS Cache | Offline | Prefs │ │ │ │ │ └───────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ └───────────────────────────────────────────────────────────┘ ``` ## Connection Modes | Mode | Description | Use Case | |------|-------------|----------| | **Direct Daemon** | Connect to local/remote derod | Full node access | | **Embedded Node** | Run derod inside Hologram | Self-sovereign operation | | **External Wallet** | Connect to Engram via XSWD | Extended wallet features | | **Integrated Wallet** | Built-in [DERO wallet](/wallet.md) | Complete independence | ## Network Support - **Mainnet**: Full production network - **[Simulator](/simulator.md)**: Local development environment with instant blocks ## Key Components ### TELA Browser Engine The [TELA Browser](/browser.md) enables accessing decentralized web applications stored entirely on the DERO blockchain. Features include: - Address bar navigation (SCID, dero:// URLs, name lookup) - Automatic content assembly from INDEX contracts - Gzip decompression for compressed content - Versioned caching with auto-invalidation ([Offline-First](/offline-first.md)) - External reference inlining - Shard and library support - Full [security features](/security.md) including iframe sandboxing and CSP management ### Gnomon Indexer Gnomon is a decentralized blockchain indexer that: - Discovers and catalogs TELA applications - Tracks smart contract state at any height - Provides full-text search capabilities - Manages ratings and name resolution ### telaHost Bridge The [telaHost API](/telahost-api.md) is a native JavaScript API available to all TELA apps (like `window.ethereum` for Web3): - Clean async interface to blockchain - Wallet operations with approval modals - No XSWD WebSocket complexity - Zero configuration required ### Sign In with DERO (HOLOGRAM-Exclusive) [HTTPS-compatible wallet authentication](/dero-auth.md) using an OAuth-style redirect flow. Websites can let visitors sign in with their DERO address — HOLOGRAM is the only wallet that supports this because it exposes local HTTP auth endpoints that bypass browser mixed content restrictions. Other wallets rely on WebSocket-only (`ws://`) which browsers block on HTTPS pages. ### Version Control System Git-like version control for TELA applications: - View commit history for any INDEX - Compare versions side-by-side - Clone content at specific commits using `scid@txid` - Accessible from Studio, Explorer, and Browser ### Villager Avatar System Visual identity integration for connected wallets: - Address-derived unique identicon frames - Custom avatar pixel overlay support - Displayed in sidebar wallet indicator - Cached locally for performance ### Sync Manager (Offline-First) Batch sync and version control for cached TELA apps: - Clone all favorites with rating threshold filter - Check cached apps for on-chain updates - Visual diffing before updating local copies - True offline operation after initial sync ### Developer Support (EPOCH) Passive hashing system to support TELA app developers: - EPOCH handler processes hash requests from dApps - DevSupportWorker runs passive background hashing - Rewards go to app developers (not users) - Configurable in Settings > Developer Support --- --- title: "Proof Validation" description: "Security enhancement for validating payload proofs and blocking fake/fabricated proofs with impossible amounts." --- # Proof Validation Hologram includes a security enhancement that validates payload proofs before display, preventing fake/fabricated proofs with impossible amounts from being shown to users. ## The Problem DERO's payload proof system allows users to prove they sent a specific amount to a specific address. However, these proofs can be fabricated with impossible amounts—like 184 trillion DERO—because the proof verification only checks cryptographic validity, not economic sanity. **Without validation:** - An attacker could create a fake proof claiming to have sent millions of DERO - The Explorer would display this as "Proof Valid" - Users could be deceived about transaction amounts - False accusations could be made based on fabricated proofs ## The Solution Hologram validates proof amounts before display using mathematical constraints: 1. **DERO Hard Cap Check**: DERO has a permanent hard cap of 21 million (like Bitcoin). Any proof claiming more than 21M DERO is mathematically impossible. 2. **Integer Overflow Protection**: Amounts near 2^63 can cause integer wraparound bugs. These are blocked. 3. **Suspicious Pattern Detection**: Large amounts or suspiciously round numbers trigger warnings. ## Validation Constants ```go const ( // Maximum safe value for int64 conversion (2^63 - 1) // Prevents uint64→int64 wraparound attacks MAX_INT64_SAFE = 9223372036854775807 // For display and calculations: 1 DERO = 100,000 atomic units ATOMIC_UNITS_PER_DERO = 100_000 // Maximum reasonable transfer amount in atomic units // DERO hard cap: 21M DERO (will never increase) // Setting max at 22M DERO = ~5% above hard cap for buffer // while blocking impossible amounts MAX_REASONABLE_AMOUNT_ATOMIC = 22_000_000 * ATOMIC_UNITS_PER_DERO // 2_200_000_000_000 // Hard cap reference DERO_HARD_CAP_ATOMIC = 21_000_000 * ATOMIC_UNITS_PER_DERO // 2_100_000_000_000 // Current approximate circulating supply (for context display) CURRENT_SUPPLY_APPROX_ATOMIC = 16_500_000 * ATOMIC_UNITS_PER_DERO // 1_650_000_000_000 ) ``` ## Validation Functions ### ValidatePayloadProofAmount Performs security checks on payload proof amounts: ```go func ValidatePayloadProofAmount(amount uint64) error { // Check 1: Prevent int64 wraparound if amount > MAX_INT64_SAFE { return fmt.Errorf("amount exceeds maximum safe integer - possible wraparound attack") } // Check 2: Sanity check against DERO hard cap if amount > MAX_REASONABLE_AMOUNT_ATOMIC { amountInDero := amount / ATOMIC_UNITS_PER_DERO return fmt.Errorf("amount %d DERO exceeds DERO hard cap (21M) - proof is fabricated", amountInDero) } return nil } ``` ### DetectSuspiciousProofPatterns Flags potentially fake or suspicious proofs: ```go func DetectSuspiciousProofPatterns(amount uint64) []string { var warnings []string // Warning 1: Near int64 boundary (possible wraparound attempt) boundaryThreshold := uint64(MAX_INT64_SAFE * 9 / 10) if amount > boundaryThreshold { warnings = append(warnings, "Amount near int64 maximum - possible wraparound attempt") } // Warning 2: Exceeds current circulating supply (~16.5M) if amount > CURRENT_SUPPLY_APPROX_ATOMIC { amountDero := amount / ATOMIC_UNITS_PER_DERO warnings = append(warnings, fmt.Sprintf("Amount (%d DERO) exceeds current circulating supply - verify carefully", amountDero)) } // Warning 3: Very large amount (> 1M DERO) - not fake, just notable largeThreshold := uint64(1_000_000 * ATOMIC_UNITS_PER_DERO) // 1M DERO if amount > largeThreshold && amount <= CURRENT_SUPPLY_APPROX_ATOMIC { amountDero := amount / ATOMIC_UNITS_PER_DERO warnings = append(warnings, fmt.Sprintf("Large transfer amount: %d DERO", amountDero)) } // Warning 4: Suspiciously round number (exact multiple of 1M DERO) - often fabricated roundThreshold := uint64(1_000_000 * ATOMIC_UNITS_PER_DERO) // 1M DERO if amount >= roundThreshold && amount%roundThreshold == 0 { amountDero := amount / ATOMIC_UNITS_PER_DERO warnings = append(warnings, fmt.Sprintf("Suspiciously round number (%d DERO exactly)", amountDero)) } return warnings } ``` ## What Gets Blocked | Attack Type | Result | |-------------|--------| | 184 trillion DERO proofs | **REJECTED** | | Any amount > 22M DERO | **REJECTED** | | int64 wraparound attacks (>= 2^63) | **REJECTED** | | Amounts > current supply (~16.5M) | WARNING | | Large amounts (> 1M DERO) | INFO | | Suspiciously round numbers | WARNING | ## UI Features ### Rejected Proofs When a proof is rejected, the UI displays: - "Proof Rejected" header with Shield icon - Error message explaining the rejection - Security note: "This proof claims an amount that exceeds the DERO hard cap (21M) and is therefore fabricated." ### Suspicious Proofs When a proof passes but has warnings, the UI displays: - "Proof Accepted" with verification details - Warning panel with AlertTriangle icon - Each warning listed with context ### Supply Context For valid proofs, the UI can display: - "12.5% of current DERO supply" - Helps users understand the magnitude ## Why 22M, Not 21M? The threshold is set slightly above the hard cap (22M vs 21M) for several reasons: 1. **Buffer for edge cases**: Rounding errors or minor timing issues 2. **Future-proof**: If supply approaches 21M, legitimate proofs still work 3. **Clear rejection**: Anything above 22M is obviously fabricated > [!NOTE] > The DERO hard cap of 21 million is defined in the protocol emission schedule. The remaining supply will be mined over many years through block rewards. ## Key Insight This validation enforces **mathematical reality**, not arbitrary limits: - DERO has a permanent, immutable hard cap of 21 million - Any proof claiming more than this is provably fabricated - This isn't a "best guess" - it's cryptographic certainty - The fix blocks ~95% of egregious fake proofs ## Limitations > [!WARNING] > This validation is a **sanity check**, not cryptographic verification of the proof itself. - Cannot verify proof without sender's private keys - Cannot detect subtle fakes (e.g., claiming 100 DERO when you sent 10) - Only blocks proofs with impossible amounts - Not a replacement for protocol-level proof verification ## Integration The validation is integrated into Hologram's Explorer at the proof display point: ```go // In ValidateProofFull() for i, amt := range amounts { // Validate each amount (blocks impossible amounts, collects warnings + context) validationResult := ValidatePayloadProofAmountWithContext(amt) if !validationResult.Valid { return map[string]interface{}{ "success": true, "valid": false, "error": fmt.Sprintf("Proof rejected: %s", validationResult.Error), "securityNote": "This proof claims an amount that exceeds the DERO hard cap (21M) and is therefore fabricated.", } } // Collect warnings and supply context for suspicious but valid amounts allWarnings = append(allWarnings, validationResult.Warnings...) } ``` ## Related Documentation - [Block Explorer](/explorer.md) - Full explorer features - [Security Features](/security.md) - Hologram's security model ### Protocol-Level Documentation For deeper understanding of the cryptographic foundations: - [Payload vs Transaction Proofs](https://derod.org/integrity/payload-vs-transaction-proofs) - Understanding the distinction between proof types at the protocol level - [Balance Mechanics](https://derod.org/integrity/balance-mechanics) - How DERO's homomorphic balance system works --- --- title: "Quick Start" description: "Get started with Hologram in minutes - connect to the network, create a wallet, and browse your first dApp." --- # Quick Start Get Hologram running and browse your first decentralized application in under 5 minutes. ## Prerequisites - Hologram installed ([Installation Guide](/installation.md)) - Internet connection ## First Run Wizard On your first launch, Hologram displays a **First Run Wizard** to help you get started quickly. ### Wizard Steps 1. **Welcome Screen**: Introduction to Hologram with version info 2. **Network Selection**: Choose your connection mode 3. **Node Setup**: Configure daemon connection or use embedded node 4. **Wallet Setup**: Create, restore, or open a wallet 5. **Ready**: Start browsing the decentralized web ### Network Options | Option | Description | Best For | |--------|-------------|----------| | **Download Node** | Auto-download and run derod | Maximum sovereignty | | **LAN / External** | Connect to node on your network | Power users with existing nodes | | **Simulator** | Local development mode | Developers | > [!NOTE] > You can skip the wizard and configure everything later from Settings. ### Simulator Quick Start For developers, the wizard offers a **"Use Simulator Instead"** button that: 1. Skips network configuration 2. Starts the integrated [Simulator](/simulator.md) 3. Opens a pre-funded test wallet 4. Gets you developing immediately with [Studio](/studio.md) tools ## Getting Started ### Launch Hologram Open Hologram from your applications. Complete the First Run Wizard or skip to configure manually. ### Connect to the Network Go to **Settings > Node** and configure your daemon connection: - **Quick Start**: Use a public remote node - **Self-Sovereign**: Run the embedded node (recommended) - **Custom**: Connect to your own derod instance > [!NOTE] > For the best experience, run the embedded node. Hologram can download and manage derod automatically from Settings > Node. ### Create or Import Wallet Navigate to **[Wallet](/wallet.md)** and either: - **Create New Wallet**: Generate a new wallet with a secure password - **Import Wallet**: Restore from 25-word seed phrase - **Open Existing**: Open an existing wallet file > [!WARNING] > Write down your 25-word seed phrase and store it securely. This is the ONLY way to recover your wallet. For added security, enable [Privacy Mode](/security.md#privacy-mode). ### Browse a dApp Go to **Browser** and try navigating to a TELA application: - Enter a SCID in the address bar - Use `dero://appname` format for named apps - Or explore the **Discover** tab to find apps ### (Optional) Enable Developer Support Go to **Settings > Developer Support** to optionally support TELA app developers through EPOCH passive hashing. This is a lightweight way to contribute to the ecosystem without traditional mining. ## Understanding the Interface ### Navigation | Tab | Purpose | |-----|---------| | **Explorer** | Landing page with OmniSearch, blockchain data | | **Browser** | Navigate and view TELA dApps, Discover apps | | **Wallet** | Balance, transactions, token portfolio | | **Studio** | DOC/INDEX deployment, version control, local development | | **Settings** | Configuration, node management, preferences | {/* removed: "Developer Support" is not a top-level navigation tab as of 2026-06-12; it lives at Settings > Developer Support. Restore the row if it is promoted to a tab. */} ### Sidebar Status Indicators The sidebar shows real-time status: - **Node**: Connection state (click to go to Settings > Node) - **XSWD**: External wallet connection status - **Gnomon**: Indexer sync status (click to go to Settings > Gnomon) - **EPOCH**: Developer support activity - **Network**: Current network (Mainnet/Simulator - click to switch) - **Block Height**: Current blockchain height ## Your First Transaction ### Ensure Wallet is Open Your wallet must be open and synced. ### Get Some DERO - Receive from another wallet - Use [Simulator Mode](/simulator.md) for development (provides pre-funded test wallets) ### Send DERO 1. Go to **Wallet** 2. Click "Send" 3. Enter recipient address and amount 4. Enter wallet password 5. Confirm transaction ## Simulator Mode (For Developers) To test without real DERO: ### Enable Simulator Click the network indicator in the sidebar (shows "Mainnet") and select "Simulator", or go to **Settings > Simulator**. ### Get Test DERO The simulator auto-mines blocks and provides test coins. ### Deploy and Test Use the Studio tab to develop and deploy TELA apps instantly. ## Next Steps - [TELA Browser](/browser.md) - Deep dive into decentralized browsing - [Studio](/studio.md) - Deploy and manage TELA content with version control - [Wallet Management](/wallet.md) - Full wallet features - [telaHost API](/telahost-api.md) - Build dApps with the JavaScript bridge - [Developer Support (EPOCH)](/developer-support.md) - Passively support TELA developers --- --- title: "Security Features" description: "Understanding Hologram's security model, sandboxing, and privacy protections." --- # Security Features Hologram implements multiple layers of security to protect users while enabling powerful dApp functionality. This page explains the security model and how each layer works. ## Defense Layers Hologram protects users through four concentric security layers: ``` ┌───────────────────────────────────────────────────────┐ │ Layer 1: Blockchain Immutability │ │ ┌─────────────────────────────────────────────────┐ │ │ │ Layer 2: Iframe Sandboxing │ │ │ │ ┌───────────────────────────────────────────┐ │ │ │ │ │ Layer 3: Permission System │ │ │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ │ │ │ │ Layer 4: Local Execution │ │ │ │ │ │ │ │ ┌───────────────────────────────┐ │ │ │ │ │ │ │ │ │ Protected User │ │ │ │ │ │ │ │ │ └───────────────────────────────┘ │ │ │ │ │ │ │ └─────────────────────────────────────┘ │ │ │ │ │ └───────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────┘ │ └───────────────────────────────────────────────────────┘ ``` ### Layer 1: Blockchain Immutability TELA content is stored on the DERO blockchain and served through the [TELA Browser](/browser.md), providing: | Property | Benefit | |----------|---------| | **Cryptographic verification** | Content hash verifiable against blockchain | | **Immutable DOCs** | Individual files cannot be modified | | **Transparent history** | All changes recorded on-chain | | **No server trust** | Content comes from decentralized network | ### Layer 2: Iframe Sandboxing All TELA content runs in a sandboxed iframe: ```html