{"id":666579,"date":"2025-04-16T07:41:31","date_gmt":"2025-04-16T07:41:31","guid":{"rendered":"https:\/\/gridnet.org\/wpp\/?p=666579"},"modified":"2026-03-07T16:18:15","modified_gmt":"2026-03-07T16:18:15","slug":"blockchain-explorer-api-documentation","status":"publish","type":"post","link":"https:\/\/gridnet.org\/wpp\/index.php\/2025\/04\/16\/blockchain-explorer-api-documentation\/","title":{"rendered":"Blockchain Explorer API Documentation"},"content":{"rendered":"<p>&nbsp;<\/p>\n<h2>1. Introduction<\/h2>\n<p>Welcome to the GRIDNET OS Blockchain Explorer API documentation. This API provides UI dApps running within the GRIDNET OS web-browser subsystem the ability to query and interact with the underlying decentralized blockchain state machine. It allows developers to build applications that can visualize, search, and analyze blockchain data, including blocks, transactions, domain information (accounts), and various network statistics.<\/p>\n<p>This document is intended for developers building UI dApps for GRIDNET OS who need to access blockchain information. It covers the API&#8217;s architecture, core concepts, method reference, data object descriptions, and event handling mechanisms.<\/p>\n<h3>Resources:<\/h3>\n<ul>\n<li>For a technical overview of an UI dApp already using this API see <a href=\"https:\/\/talk.gridnet.org\/t\/experimental-blockchain-explorer-ui-dapp\/1041\">here<\/a><\/li>\n<li>For GRIDNE OS UI dApp best design practices see <a href=\"https:\/\/talk.gridnet.org\/t\/gridnet-os-ui-dapp-design-guidelines\/1055\">here<br \/>\n<\/a><\/li>\n<li>For a Tutorial including sample deployment described see <a href=\"https:\/\/gridnet.org\/wpp\/index.php\/2022\/07\/12\/create-ui-dapps-right-now-developer-guide\/\">here<\/a><\/li>\n<li>Want to see how it works? Just launch the Blockchain Explorer UI dApp <a href=\"https:\/\/ui.gridnet.org\">here<\/a> (available from GRIDNET OS&#8217; Start Menu).<\/li>\n<\/ul>\n<h2 id=\"2-architecture-overview\">2. Architecture Overview<\/h2>\n<p>The Blockchain Explorer API is primarily exposed through the <code>CVMContext<\/code> singleton object, which acts as the central bridge between the in-browser UI dApp environment and the remote GRIDNET Core nodes forming the decentralized network.<br \/>\n<a href=\"https:\/\/gridnet.org\/wpp\/wp-content\/uploads\/2025\/04\/blockchain-architecture-diagram.svg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-666633\" src=\"https:\/\/gridnet.org\/wpp\/wp-content\/uploads\/2025\/04\/blockchain-architecture-diagram.svg\" alt=\"\" width=\"1\" height=\"1\" \/><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-666636 aligncenter\" src=\"https:\/\/gridnet.org\/wpp\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-16-at-09.23.15.png\" alt=\"\" width=\"817\" height=\"670\" \/><\/a><\/p>\n<p><strong>Key Architectural Points:<\/strong><\/p>\n<ol>\n<li><strong>Decentralized Nature:<\/strong> Unlike traditional client-server models, requests are processed by the distributed network of GRIDNET Core nodes. <code>CVMContext<\/code> handles selecting appropriate nodes (based on proximity or randomness) and managing the connection (typically WebSocket).<\/li>\n<li><strong>CVMContext:<\/strong> This singleton JavaScript object is the main entry point for all interactions with the GRIDNET OS backend, including the Blockchain Explorer API.<\/li>\n<li><strong>GridScript:<\/strong> Under the hood, most Blockchain Explorer API calls are translated into specific <code>#GridScript<\/code> commands (e.g., <code>context -c getBlockDetails ...<\/code>). These commands are sent to a Core node for execution within a secure, sandboxed environment.<\/li>\n<li><strong>Decentralized Processing Threads:<\/strong> GRIDNET OS utilizes the concept of decentralized threads. API calls can optionally target specific threads (<code>threadID<\/code>). If not specified, they often default to system-managed threads (like the main data thread).<\/li>\n<li><strong>Asynchronous Communication:<\/strong> Communication between the UI dApp and Core nodes is inherently asynchronous. The API provides both non-async (returning a Request ID immediately) and async (<code>A<\/code> suffix, returning a Promise) methods.<\/li>\n<li><strong>Event-Driven Responses:<\/strong> Results from API calls are typically delivered back to the UI dApp via events. The dApp registers specific listeners (e.g., <code>addNewBlockDetailsListener<\/code>) with <code>CVMContext<\/code> to receive and process these responses.<\/li>\n<li><strong>BER Encoding &amp; Meta Data Protocol:<\/strong> Data exchanged between the browser and Core nodes (especially complex data like block or transaction details) uses the GRIDNET Meta Data Protocol, which is BER (Basic Encoding Rules) encoded for efficient and standardized data representation. <code>CVMContext<\/code> handles the encoding\/decoding internally.<\/li>\n<li><strong>Security:<\/strong> Communication can be secured using end-to-end encryption and authentication mechanisms managed by <code>CVMContext<\/code> based on session state and configuration.<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-666638 aligncenter\" src=\"https:\/\/gridnet.org\/wpp\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-16-at-09.24.23.png\" alt=\"\" width=\"875\" height=\"670\" \/><\/p>\n<p><strong>Simplified Flow:<\/strong><\/p>\n<pre>[<span class=\"hljs-name\">UI<\/span> dApp] --(<span class=\"hljs-name\">JS<\/span> API Call)--&gt; [<span class=\"hljs-name\">CVMContext<\/span>] --(<span class=\"hljs-name\">GridScript\/BER<\/span>)--&gt; [<span class=\"hljs-name\">WebSocket<\/span>] --&gt; [<span class=\"hljs-name\">GRIDNET<\/span> Core Node(<span class=\"hljs-name\">s<\/span>)]\r\n^                                                                                    |\r\n|                               (<span class=\"hljs-name\">BER\/Event<\/span>)                                          |\r\n+------------------------------------------------------------------------------------+\r\n<\/pre>\n<h2 class=\"ng-star-inserted\"><strong class=\"ng-star-inserted\"><span class=\"ng-star-inserted\">Under the Hood: GridScript Execution and the Decentralized Paradigm<\/span><\/strong><\/h2>\n<p class=\"ng-star-inserted\"><span class=\"ng-star-inserted\">Beneath the familiar JavaScript interface of the Blockchain Explorer API lies a fundamentally decentralized execution model powered by\u00a0<\/span><strong class=\"ng-star-inserted\"><span class=\"ng-star-inserted\">#GridScript<\/span><\/strong><span class=\"ng-star-inserted\">. When a UI dApp calls an API method like\u00a0<\/span><span class=\"inline-code ng-star-inserted\">CVMContext.getBlockDetailsA()<\/span><span class=\"ng-star-inserted\">,\u00a0<\/span><span class=\"inline-code ng-star-inserted\">CVMContext<\/span><span class=\"ng-star-inserted\">\u00a0doesn&#8217;t query a local database or send a request to a traditional centralized backend. Instead, it\u00a0<\/span><strong class=\"ng-star-inserted\"><span class=\"ng-star-inserted\">seamlessly translates<\/span><\/strong><span class=\"ng-star-inserted\">\u00a0the JavaScript call and its parameters into a specific\u00a0<\/span><span class=\"inline-code ng-star-inserted\">#GridScript<\/span><span class=\"ng-star-inserted\">\u00a0command string (e.g.,\u00a0<\/span><span class=\"inline-code ng-star-inserted\">context -c getBlockDetails -search &#8220;&lt;blockID&gt;&#8221; -tx<\/span><span class=\"ng-star-inserted\">). This GridScript command, representing the data request, is then packaged using the GRIDNET OS&#8217;s BER-encoded\u00a0<\/span><strong class=\"ng-star-inserted\"><span class=\"ng-star-inserted\">VM Meta Data exchange protocol<\/span><\/strong><span class=\"ng-star-inserted\">\u00a0and dispatched via WebSocket to a connected GRIDNET Core node. The Core node routes this command to an appropriate\u00a0<\/span><strong class=\"ng-star-inserted\"><span class=\"ng-star-inserted\">Decentralized Processing Thread (DPT)<\/span><\/strong><span class=\"ng-star-inserted\">, which hosts its own sandboxed GridScript virtual machine instance. This VM executes the received command, interacting directly with the node&#8217;s local view of the decentralized blockchain state machine to retrieve the requested block details.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-666652\" src=\"https:\/\/gridnet.org\/wpp\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-16-at-09.32.03.png\" alt=\"\" width=\"907\" height=\"693\" \/><\/span><\/p>\n<p>The results are then packaged back into a BER-encoded VM Meta Data response, sent back through the network to the originating\u00a0<span class=\"inline-code ng-star-inserted\">CVMContext<\/span><span class=\"ng-star-inserted\">, which decodes it and delivers the structured data (like a\u00a0<\/span><span class=\"inline-code ng-star-inserted\">CBlockDesc<\/span><span class=\"ng-star-inserted\">\u00a0object) back to the UI dApp, either by resolving the corresponding Promise or triggering a registered event listener. This entire process represents a\u00a0<\/span><strong class=\"ng-star-inserted\"><span class=\"ng-star-inserted\">paradigm shift from traditional Service-Oriented Architectures (SOA)<\/span><\/strong><span class=\"ng-star-inserted\">; requests are not handled by a centralized server running PHP or .NET against a central database, but are executed decentrally across the network by capable Core nodes running GridScript. This architecture inherently supports a future where such computational or data retrieval tasks performed by nodes could be incentivized, potentially through mechanisms like off-chain cryptocurrency micropayments, truly decentralizing not just data storage but also application logic execution.<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-666656\" src=\"https:\/\/gridnet.org\/wpp\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-16-at-09.37.33.png\" alt=\"\" width=\"907\" height=\"693\" \/><\/span><\/p>\n<p>Let&#8217;s take a look at how the execution environment is structured:<\/p>\n<p class=\"ng-star-inserted\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-666657\" src=\"https:\/\/gridnet.org\/wpp\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-16-at-09.38.15.png\" alt=\"\" width=\"907\" height=\"693\" \/><\/p>\n<p>Now let&#8217;s better understand involvement of BER encoding as it&#8217;s involved:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-666660\" src=\"https:\/\/gridnet.org\/wpp\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-16-at-09.38.38.png\" alt=\"\" width=\"907\" height=\"693\" \/><\/p>\n<p>Now, let&#8217;s go with a complete Blockchain Explorer API execution Cycle:<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-666661\" src=\"https:\/\/gridnet.org\/wpp\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-16-at-09.39.05.png\" alt=\"\" width=\"907\" height=\"761\" \/><br \/>\n3. Core Concepts<\/p>\n<h3 id=\"3-1-synchronous-vs-asynchronous-api-methods\">3.1 Synchronous vs. Asynchronous API Methods<\/h3>\n<p>The API offers two styles for many methods:<\/p>\n<ul>\n<li><strong>Non-Async (Synchronous-like Invocation):<\/strong> Methods like <code>getBlockDetails(...)<\/code> execute the request immediately and return a unique <code>request identifier<\/code> (a number &gt; 0) if the request was successfully <em>sent<\/em>. The actual result arrives later via an event. The UI dApp needs to register a corresponding listener (e.g., <code>addNewBlockDetailsListener<\/code>) to handle the response, matching it using the <code>reqID<\/code> field in the event argument.<\/li>\n<li><strong>Async (Promise-based):<\/strong> Methods ending with <code>A<\/code> (e.g., <code>getBlockDetailsA(...)<\/code>) return a JavaScript <code>Promise<\/code>. This Promise resolves with the result data when the response is received from the network or rejects if an error or timeout occurs. This simplifies handling asynchronous operations compared to managing request IDs and listeners manually.<\/li>\n<\/ul>\n<p><strong>Recommendation:<\/strong> Use the asynchronous (<code>A<\/code> suffix) methods whenever possible for cleaner code structure using <code>async\/await<\/code> or <code>.then()\/.catch()<\/code>.<\/p>\n<h3 id=\"3-2-event-driven-architecture\">3.2 Event-Driven Architecture<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-666644 aligncenter\" src=\"https:\/\/gridnet.org\/wpp\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-16-at-09.25.56.png\" alt=\"\" width=\"907\" height=\"693\" \/><\/p>\n<p>Responses to API calls and real-time blockchain updates are delivered through events. UI dApps must register listener functions with <code>CVMContext<\/code> using specific <code>add...Listener<\/code> methods.<\/p>\n<ul>\n<li><strong>Listeners:<\/strong> Functions provided by the UI dApp to handle specific types of data (e.g., block details, search results).<\/li>\n<li><strong>Notifiers:<\/strong> Internal <code>CVMContext<\/code> methods (<code>notify...<\/code>) that trigger the registered listeners when relevant data arrives.<\/li>\n<li><strong>Event Arguments:<\/strong> Listener functions receive an argument object, typically containing:\n<ul>\n<li><code>reqID<\/code>: The original request identifier (if applicable).<\/li>\n<li><code>data<\/code> or specific properties: The payload, often an instance of a data object class (e.g., <code>CBlockDesc<\/code>).<\/li>\n<li>Other contextual information (e.g., <code>processID<\/code>, <code>source<\/code>).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3 id=\"3-3-request-response-flow-ids\">3.3 Request\/Response Flow &amp; IDs<\/h3>\n<ol>\n<li><strong>API Call:<\/strong> The UI dApp calls an API method (e.g., <code>CVMContext.getTransactionDetails(...)<\/code>).<\/li>\n<li><strong>Request ID Generation:<\/strong> <code>CVMContext<\/code> generates a unique <code>request identifier<\/code> (<code>reqID<\/code>).<\/li>\n<li><strong>GridScript Formulation:<\/strong> The API method formats the corresponding <code>#GridScript<\/code> command.<\/li>\n<li><strong>Dispatch:<\/strong> <code>CVMContext<\/code> (via <code>processGridScriptKM<\/code>) sends the command (encapsulated in Meta Data) over the network. The non-async method returns the <code>reqID<\/code> immediately. The async method registers the Promise internally using this <code>reqID<\/code>.<\/li>\n<li><strong>Network Processing:<\/strong> GRIDNET Core nodes process the request.<\/li>\n<li><strong>Response Delivery:<\/strong> The result is sent back via WebSocket, BER-encoded within the Meta Data protocol.<\/li>\n<li><strong>Response Processing:<\/strong> <code>CVMContext<\/code> receives the message, decrypts\/authenticates if necessary, parses the Meta Data, and identifies the relevant data and original <code>reqID<\/code>.<\/li>\n<li><strong>Notification\/Resolution:<\/strong>\n<ul>\n<li><code>CVMContext<\/code> triggers the appropriate notifier function (e.g., <code>notifyNewTransactionDetails<\/code>).<\/li>\n<li>The notifier function iterates through registered listeners, calling their callback functions with the response data and <code>reqID<\/code>.<\/li>\n<li>If the request was made using an async (<code>A<\/code>) method, <code>CVMContext<\/code> finds the corresponding pending Promise using the <code>reqID<\/code> and resolves it with the data (via <code>resolvePendingRequest<\/code>).<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-666641\" src=\"https:\/\/gridnet.org\/wpp\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-16-at-09.25.09.png\" alt=\"\" width=\"907\" height=\"693\" \/><\/p>\n<h3 id=\"3-4-decentralized-processing-threads-threadid-\">3.4 Decentralized Processing Threads (<code>threadID<\/code>)<\/h3>\n<p>GRIDNET OS allows operations to be executed within specific decentralized processing threads. Most Blockchain Explorer API methods accept an optional <code>threadID<\/code> (as an <code>ArrayBuffer<\/code>).<\/p>\n<ul>\n<li>If provided, the operation targets that specific thread.<\/li>\n<li>If omitted or an empty <code>ArrayBuffer<\/code> is provided, it usually defaults to a system-managed thread (often the main <em>Data Thread<\/em>, accessible via <code>CVMContext.getDataThreadID<\/code>).<\/li>\n<li>The main <em>System Thread<\/em> (<code>CVMContext.getSystemThreadID<\/code>) handles core system operations.<\/li>\n<\/ul>\n<h3 id=\"3-5-process-handles-processhandle-\">3.5 Process Handles (<code>processHandle<\/code>)<\/h3>\n<p>Many API methods require a <code>processHandle<\/code>. This is typically the instance of the UI dApp&#8217;s main class (which usually extends <code>CWindow<\/code>). It&#8217;s used for:<\/p>\n<ul>\n<li><strong>Authorization:<\/strong> Ensuring that API calls originate from a registered, valid UI dApp process. Anonymous calls are often disallowed.<\/li>\n<li><strong>Context:<\/strong> Linking the API request to the specific application making the call.<\/li>\n<li><strong>Resource Management:<\/strong> Potentially used by the system to manage resources associated with the dApp&#8217;s requests.<\/li>\n<\/ul>\n<h3 id=\"3-6-execution-modes-mode-\">3.6 Execution Modes (<code>mode<\/code>)<\/h3>\n<p>The <code>mode<\/code> parameter (using the <code>eVMMetaCodeExecutionMode<\/code> enum) specifies how the underlying GridScript command should be executed and how results should be returned. For the Blockchain Explorer API:<\/p>\n<ul>\n<li><code>eVMMetaCodeExecutionMode.RAW<\/code>: Typically used. Returns raw, structured data objects (like <code>CBlockDesc<\/code>) suitable for programmatic use.<\/li>\n<li><code>eVMMetaCodeExecutionMode.GUI<\/code>: Might return data formatted for direct display in a terminal-like UI (less common for this API).<\/li>\n<\/ul>\n<h3 id=\"3-7-data-objects\">3.7 Data Objects<\/h3>\n<p>The API uses specific classes to represent blockchain entities:<\/p>\n<ul>\n<li><code>CBlockDesc<\/code>: Block details.<\/li>\n<li><code>CTransactionDesc<\/code>: Transaction details.<\/li>\n<li><code>CDomainDesc<\/code>: Domain\/account details.<\/li>\n<li><code>CSearchResults<\/code>: Container for search results, holding multiple items of the above types.<\/li>\n<li><code>CSearchFilter<\/code>: Used to define complex search criteria.<\/li>\n<\/ul>\n<p>These objects provide methods for accessing properties and often include serialization (<code>getPackedData<\/code>) and deserialization (<code>instantiate<\/code>) methods for BER encoding.<\/p>\n<hr \/>\n<h2 id=\"4-api-reference\">4. API Reference<\/h2>\n<p>This section details the public methods provided by <code>CVMContext<\/code> for the Blockchain Explorer API.<\/p>\n<h3 id=\"4-1-data-retrieval-methods\">4.1 Data Retrieval Methods<\/h3>\n<h4 id=\"-getrecenttransactions-size-page-includemem-threadid-processhandle-mode-reqid-\"><code>getRecentTransactions(size, page, includeMem, threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves a list of recent transactions from the blockchain.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>size<\/code> {<code>number<\/code>} [Optional, Default: 10] &#8211; Number of transactions per page.<\/li>\n<li><code>page<\/code> {<code>number<\/code>} [Optional, Default: 1] &#8211; Page number to retrieve (1-based).<\/li>\n<li><code>includeMem<\/code> {<code>boolean<\/code>} [Optional, Default: false] &#8211; If true, includes transactions from the memory pool (unconfirmed).<\/li>\n<li><code>threadID<\/code> {<code>ArrayBuffer<\/code>} [Optional, Default: Data Thread] &#8211; The target decentralized thread ID.<\/li>\n<li><code>processHandle<\/code> {<code>Object<\/code>} [Optional, Default: null] &#8211; Handle of the calling UI dApp process (required for user-mode calls).<\/li>\n<li><code>mode<\/code> {<code>eVMMetaCodeExecutionMode<\/code>} [Optional, Default: <code>RAW<\/code>] &#8211; Execution mode.<\/li>\n<li><code>reqID<\/code> {<code>number<\/code>} [Optional, Default: 0] &#8211; Specific request ID to use (0 generates a new one).<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; A request identifier (<code>reqID &gt; 0<\/code>) if the request was sent successfully, otherwise 0.<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getRecentTransactions -size &lt;size&gt; -page &lt;page&gt; [-mem]<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addNewSearchResultsListener<\/code> (Results delivered within a <code>CSearchResults<\/code> object containing <code>CTransactionDesc<\/code> instances).<\/li>\n<li><strong>Async Version:<\/strong> <code>getRecentTransactionsA(...)<\/code> -&gt; <code>Promise&lt;CSearchResults&gt;<\/code><\/li>\n<li><strong>Example (Non-Async):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>; <span class=\"hljs-comment\">\/\/ Assuming 'this' is the UI dApp instance<\/span><br \/>\n<span class=\"hljs-keyword\">const<\/span> listenerId = vmContext.addNewSearchResultsListener(<span class=\"hljs-function\">(<span class=\"hljs-params\">event<\/span>) =&gt;<\/span> {<br \/>\n<span class=\"hljs-keyword\">if<\/span> (event.reqID === myReqId &amp;&amp; event.results <span class=\"hljs-keyword\">instanceof<\/span> CSearchResults) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Received <span class=\"hljs-subst\">${event.results.getResultCount()}<\/span> recent transactions.`<\/span>);<br \/>\n<span class=\"hljs-comment\">\/\/ Process event.results containing CTransactionDesc objects<\/span><br \/>\nvmContext.unregisterEventListenerByID(listenerId); <span class=\"hljs-comment\">\/\/ Clean up listener<\/span><br \/>\n}<br \/>\n});<br \/>\n<span class=\"hljs-keyword\">const<\/span> myReqId = vmContext.getRecentTransactions(<span class=\"hljs-number\">20<\/span>, <span class=\"hljs-number\">1<\/span>, <span class=\"hljs-literal\">false<\/span>, <span class=\"hljs-literal\">undefined<\/span>, processHandle);<br \/>\n<span class=\"hljs-keyword\">if<\/span> (!myReqId) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Failed to send request for recent transactions.\"<\/span>);<br \/>\nvmContext.unregisterEventListenerByID(listenerId);<br \/>\n} <span class=\"hljs-keyword\">else<\/span> {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"Request sent with ID:\"<\/span>, myReqId);<br \/>\n}<br \/>\n<\/code><\/li>\n<li><strong>Example (Async):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">fetchRecentTxs<\/span>() <\/span>{<br \/>\n<span class=\"hljs-keyword\">try<\/span> {<br \/>\n<span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>;<br \/>\n<span class=\"hljs-keyword\">const<\/span> searchResults = <span class=\"hljs-keyword\">await<\/span> vmContext.getRecentTransactionsA(<span class=\"hljs-number\">20<\/span>, <span class=\"hljs-number\">1<\/span>, <span class=\"hljs-literal\">false<\/span>, <span class=\"hljs-literal\">undefined<\/span>, processHandle);<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Received <span class=\"hljs-subst\">${searchResults.getResultCount()}<\/span> recent transactions.`<\/span>);<br \/>\nsearchResults.getAllResults().forEach(<span class=\"hljs-function\"><span class=\"hljs-params\">resultData<\/span> =&gt;<\/span> {<br \/>\n<span class=\"hljs-keyword\">if<\/span> (resultData.getValue() <span class=\"hljs-keyword\">instanceof<\/span> CTransactionDesc) {<br \/>\n<span class=\"hljs-keyword\">const<\/span> tx = resultData.getValue();<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`TX ID: <span class=\"hljs-subst\">${tx.verifiableID}<\/span>, Value: <span class=\"hljs-subst\">${tx.value}<\/span>`<\/span>);<br \/>\n}<br \/>\n});<br \/>\n} <span class=\"hljs-keyword\">catch<\/span> (error) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Error fetching recent transactions:\"<\/span>, error);<br \/>\n}<br \/>\n}<br \/>\nfetchRecentTxs();<br \/>\n<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-getrecentblocks-size-page-sortblocksbyenumval-threadid-processhandle-mode-reqid-\"><code>getRecentBlocks(size, page, sortBlocksByEnumVal, threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves a list of recent blocks from the blockchain.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>size<\/code> {<code>number<\/code>} [Optional, Default: 10] &#8211; Number of blocks per page.<\/li>\n<li><code>page<\/code> {<code>number<\/code>} [Optional, Default: 1] &#8211; Page number to retrieve (1-based).<\/li>\n<li><code>sortBlocksByEnumVal<\/code> {<code>eSortBlocksBy<\/code>} [Optional, Default: <code>timestampDesc<\/code>] &#8211; The sorting criteria (use values from <code>eSortBlocksBy<\/code> enum).<\/li>\n<li><code>threadID<\/code> {<code>ArrayBuffer<\/code>} [Optional, Default: Data Thread] &#8211; The target decentralized thread ID.<\/li>\n<li><code>processHandle<\/code> {<code>Object<\/code>} [Optional, Default: null] &#8211; Handle of the calling UI dApp process.<\/li>\n<li><code>mode<\/code> {<code>eVMMetaCodeExecutionMode<\/code>} [Optional, Default: <code>RAW<\/code>] &#8211; Execution mode.<\/li>\n<li><code>reqID<\/code> {<code>number<\/code>} [Optional, Default: 0] &#8211; Specific request ID to use.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; A request identifier (<code>reqID &gt; 0<\/code>) if sent successfully, otherwise 0.<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getRecentBlocks -size &lt;size&gt; -page &lt;page&gt; -sort &lt;sortBlocksByEnumVal&gt;<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addNewSearchResultsListener<\/code> (Results delivered within a <code>CSearchResults<\/code> object containing <code>CBlockDesc<\/code> instances).<\/li>\n<li><strong>Async Version:<\/strong> <code>getRecentBlocksA(...)<\/code> -&gt; <code>Promise&lt;CSearchResults&gt;<\/code><\/li>\n<li><strong>Example (Async):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">fetchRecentBlocks<\/span>() <\/span>{<br \/>\n<span class=\"hljs-keyword\">try<\/span> {<br \/>\n<span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>;<br \/>\n<span class=\"hljs-keyword\">const<\/span> searchResults = <span class=\"hljs-keyword\">await<\/span> vmContext.getRecentBlocksA(<span class=\"hljs-number\">15<\/span>, <span class=\"hljs-number\">1<\/span>, eSortBlocksBy.heightDesc, <span class=\"hljs-literal\">undefined<\/span>, processHandle);<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Received <span class=\"hljs-subst\">${searchResults.getResultCount()}<\/span> recent blocks.`<\/span>);<br \/>\nsearchResults.getAllResults().forEach(<span class=\"hljs-function\"><span class=\"hljs-params\">resultData<\/span> =&gt;<\/span> {<br \/>\n<span class=\"hljs-keyword\">if<\/span> (resultData.getValue() <span class=\"hljs-keyword\">instanceof<\/span> CBlockDesc) {<br \/>\n<span class=\"hljs-keyword\">const<\/span> block = resultData.getValue();<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Block Height: <span class=\"hljs-subst\">${block.height}<\/span>, ID: <span class=\"hljs-subst\">${block.blockID}<\/span>`<\/span>);<br \/>\n}<br \/>\n});<br \/>\n} <span class=\"hljs-keyword\">catch<\/span> (error) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Error fetching recent blocks:\"<\/span>, error);<br \/>\n}<br \/>\n}<br \/>\nfetchRecentBlocks();<br \/>\n<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-gettransactiondailystats-days-includemem-threadid-processhandle-mode-reqid-\"><code>getTransactionDailyStats(days, includeMem, threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves daily statistics about transaction activity over a specified number of days.<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>days<\/code> {<code>number<\/code>} [Optional, Default: 14] &#8211; The number of past days to retrieve statistics for.<\/li>\n<li><code>includeMem<\/code> {<code>boolean<\/code>} [Optional, Default: false] &#8211; If true, includes unconfirmed transactions in the statistics.<\/li>\n<li><code>threadID<\/code> {<code>ArrayBuffer<\/code>} [Optional, Default: Data Thread] &#8211; The target decentralized thread ID.<\/li>\n<li><code>processHandle<\/code> {<code>Object<\/code>} [Optional, Default: null] &#8211; Handle of the calling UI dApp process.<\/li>\n<li><code>mode<\/code> {<code>eVMMetaCodeExecutionMode<\/code>} [Optional, Default: <code>RAW<\/code>] &#8211; Execution mode.<\/li>\n<li><code>reqID<\/code> {<code>number<\/code>} [Optional, Default: 0] &#8211; Specific request ID to use.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; A request identifier (<code>reqID &gt; 0<\/code>) if sent successfully, otherwise 0.<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getTransactionDailyStats -days &lt;days&gt; [-mem]<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addBlockchainStatsListener<\/code> (Event argument <code>arg.data<\/code> contains the statistics, usually an array or object with date\/count\/volume pairs).<\/li>\n<li><strong>Async Version:<\/strong> <code>getTransactionDailyStatsA(...)<\/code> -&gt; <code>Promise&lt;Object|Array&gt;<\/code><\/li>\n<li><strong>Example (Async):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">fetchTxStats<\/span>() <\/span>{<br \/>\n<span class=\"hljs-keyword\">try<\/span> {<br \/>\n<span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>;<br \/>\n<span class=\"hljs-keyword\">const<\/span> stats = <span class=\"hljs-keyword\">await<\/span> vmContext.getTransactionDailyStatsA(<span class=\"hljs-number\">30<\/span>, <span class=\"hljs-literal\">false<\/span>, <span class=\"hljs-literal\">undefined<\/span>, processHandle);<br \/>\n<span class=\"hljs-comment\">\/\/ Assuming stats is { dates: [...], counts: [...], volumes: [...] }<\/span><br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Received stats for <span class=\"hljs-subst\">${stats.dates.length}<\/span> days.`<\/span>);<br \/>\n<span class=\"hljs-comment\">\/\/ Process stats for charting or display<\/span><br \/>\n} <span class=\"hljs-keyword\">catch<\/span> (error) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Error fetching transaction stats:\"<\/span>, error);<br \/>\n}<br \/>\n}<br \/>\nfetchTxStats();<br \/>\n<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&lt;code<\/p>\n<hr \/>\n<h4 id=\"-getblockchainstatus-threadid-processhandle-mode-reqid-\"><code>getBlockchainStatus(threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves the overall status of the blockchain, potentially including total supply, current heights, and network status.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>threadID<\/code> {<code>ArrayBuffer<\/code>} [Optional, Default: Data Thread] &#8211; The target decentralized thread ID.<\/li>\n<li><code>processHandle<\/code> {<code>Object<\/code>} [Optional, Default: null] &#8211; Handle of the calling UI dApp process.<\/li>\n<li><code>mode<\/code> {<code>eVMMetaCodeExecutionMode<\/code>} [Optional, Default: <code>RAW<\/code>] &#8211; Execution mode.<\/li>\n<li><code>reqID<\/code> {<code>number<\/code>} [Optional, Default: 0] &#8211; Specific request ID to use.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; A request identifier (<code>reqID &gt; 0<\/code>) if sent successfully, otherwise 0.<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getBlockchainStatus<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addBlockchainStatsListener<\/code> (Event argument <code>arg.data<\/code> contains status information like <code>totalSupply<\/code>, <code>height<\/code>, <code>keyHeight<\/code>).<\/li>\n<li><strong>Async Version:<\/strong> <code>getBlockchainStatusA(...)<\/code> -&gt; <code>Promise&lt;Object&gt;<\/code><\/li>\n<li><strong>Example (Async):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">fetchStatus<\/span>() <\/span>{<br \/>\n<span class=\"hljs-keyword\">try<\/span> {<br \/>\n<span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>;<br \/>\n<span class=\"hljs-keyword\">const<\/span> status = <span class=\"hljs-keyword\">await<\/span> vmContext.getBlockchainStatusA(<span class=\"hljs-literal\">undefined<\/span>, processHandle);<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Blockchain Status: Height=<span class=\"hljs-subst\">${status.height}<\/span>, KeyHeight=<span class=\"hljs-subst\">${status.keyHeight}<\/span>, Supply=<span class=\"hljs-subst\">${status.totalSupply}<\/span>`<\/span>);<br \/>\n} <span class=\"hljs-keyword\">catch<\/span> (error) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Error fetching blockchain status:\"<\/span>, error);<br \/>\n}<br \/>\n}<br \/>\nfetchStatus();<br \/>\n<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-getmarketdata-getmarketcap-getbalances-page-pagesize-sorttype-sortorder-threadid-processhandle-mode-reqid-\"><code>getMarketData(getMarketCap, getBalances, page, pageSize, sortType, sortOrder, threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves market data, including total market capitalization and\/or domain balances, with sorting and pagination.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>getMarketCap<\/code> {<code>boolean<\/code>} [Optional, Default: false] &#8211; If true, retrieve total market cap (<code>-d<\/code> flag).<\/li>\n<li><code>getBalances<\/code> {<code>boolean<\/code>} [Optional, Default: true] &#8211; If true, retrieve domain balances (<code>-b<\/code> flag).<\/li>\n<li><code>page<\/code> {<code>number<\/code>} [Optional, Default: 1] &#8211; Page number for balance results.<\/li>\n<li><code>pageSize<\/code> {<code>number<\/code>} [Optional, Default: 50] &#8211; Number of domain balances per page.<\/li>\n<li><code>sortType<\/code> {<code>eMarketSortType<\/code>} [Optional, Default: null] &#8211; Criteria for sorting domain balances (e.g., <code>eMarketSortType.balance<\/code>).<\/li>\n<li><code>sortOrder<\/code> {<code>eSortOrder<\/code>} [Optional, Default: <code>ascending<\/code>] &#8211; Sort order (<code>ascending<\/code> or <code>descending<\/code>).<\/li>\n<li><code>threadID<\/code> {<code>ArrayBuffer<\/code>} [Optional, Default: Data Thread] &#8211; The target decentralized thread ID.<\/li>\n<li><code>processHandle<\/code> {<code>Object<\/code>} [Optional, Default: null] &#8211; Handle of the calling UI dApp process (required).<\/li>\n<li><code>mode<\/code> {<code>eVMMetaCodeExecutionMode<\/code>} [Optional, Default: <code>RAW<\/code>] &#8211; Execution mode.<\/li>\n<li><code>reqID<\/code> {<code>number<\/code>} [Optional, Default: 0] &#8211; Specific request ID to use.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; A request identifier (<code>reqID &gt; 0<\/code>) if sent successfully, otherwise 0.<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>market [-d] [-b] -page &lt;page&gt; -size &lt;pageSize&gt; [-sort &lt;sortTypeStr&gt;] [-asc | -desc]<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addBlockchainStatsListener<\/code> (for market cap) and\/or <code>addNewSearchResultsListener<\/code> (for domain balances, delivered in <code>CSearchResults<\/code> containing <code>CDomainDesc<\/code>).<\/li>\n<li><strong>Async Version:<\/strong> <code>getMarketDataA(...)<\/code> -&gt; <code>Promise&lt;Object&gt;<\/code> (The resolved object structure depends on <code>getMarketCap<\/code> and <code>getBalances<\/code> flags).<\/li>\n<li><strong>Example (Async &#8211; Get Top 10 Richest Domains):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">fetchTopDomains<\/span>() <\/span>{<br \/>\n<span class=\"hljs-keyword\">try<\/span> {<br \/>\n<span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>;<br \/>\n<span class=\"hljs-comment\">\/\/ Request balances, sort by balance descending, page 1, size 10<\/span><br \/>\n<span class=\"hljs-keyword\">const<\/span> marketResults = <span class=\"hljs-keyword\">await<\/span> vmContext.getMarketDataA(<br \/>\n<span class=\"hljs-literal\">false<\/span>, <span class=\"hljs-comment\">\/\/ Don't need total market cap<\/span><br \/>\n<span class=\"hljs-literal\">true<\/span>,  <span class=\"hljs-comment\">\/\/ Need domain balances<\/span><br \/>\n<span class=\"hljs-number\">1<\/span>,<br \/>\n<span class=\"hljs-number\">10<\/span>,<br \/>\neMarketSortType.balance,<br \/>\neSortOrder.descending,<br \/>\n<span class=\"hljs-literal\">undefined<\/span>,<br \/>\nprocessHandle<br \/>\n);<br \/>\n<span class=\"hljs-comment\">\/\/ marketResults likely contains the data within a CSearchResults structure<\/span><br \/>\n<span class=\"hljs-comment\">\/\/ accessible through the listener or directly if the promise resolves with it.<\/span><br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Received <span class=\"hljs-subst\">${marketResults.getResultCount()}<\/span> top domains.`<\/span>);<br \/>\nmarketResults.getAllResults().forEach(<span class=\"hljs-function\"><span class=\"hljs-params\">resultData<\/span> =&gt;<\/span> {<br \/>\n<span class=\"hljs-keyword\">if<\/span> (resultData.getValue() <span class=\"hljs-keyword\">instanceof<\/span> CDomainDesc) {<br \/>\n<span class=\"hljs-keyword\">const<\/span> domain = resultData.getValue();<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Domain: <span class=\"hljs-subst\">${domain.domain}<\/span>, Balance: <span class=\"hljs-subst\">${domain.balanceTxt}<\/span>`<\/span>);<br \/>\n}<br \/>\n});} <span class=\"hljs-keyword\">catch<\/span> (error) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Error fetching market data:\"<\/span>, error);<br \/>\n}<br \/>\n}<br \/>\nfetchTopDomains();<br \/>\n<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-searchblockchain-query-size-page-flags-threadid-processhandle-mode-reqid-\"><code>searchBlockchain(query, size, page, flags, threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Performs a general search across the blockchain for blocks, transactions, or domains matching the query.<\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>query<\/code> {<code>string<\/code>} &#8211; The search term (e.g., block ID, transaction ID, domain name).<\/li>\n<li><code>size<\/code> {<code>number<\/code>} [Optional, Default: 10] &#8211; Maximum number of results per page.<\/li>\n<li><code>page<\/code> {<code>number<\/code>} [Optional, Default: 1] &#8211; Page number for results.<\/li>\n<li><code>flags<\/code> {<code>CSearchFilter<\/code> | <code>number<\/code> | <code>string<\/code> | <code>Array&lt;string&gt;<\/code>} [Optional, Default: null] &#8211; Search filter. Can be:\n<ul>\n<li>A <code>CSearchFilter<\/code> instance for complex filtering.<\/li>\n<li>A number representing a bitmask of standard flags (<code>TRANSACTIONS<\/code>, <code>DOMAINS<\/code>, <code>BLOCKS<\/code>).<\/li>\n<li>A Base58Check encoded string representing the filter.<\/li>\n<li>An array of standard flag names (e.g., <code>['TRANSACTIONS', 'BLOCKS']<\/code>).<\/li>\n<li>If <code>null<\/code>, defaults may apply on the Core node.<\/li>\n<\/ul>\n<\/li>\n<li><code>threadID<\/code> {<code>ArrayBuffer<\/code>} [Optional, Default: Data Thread] &#8211; The target decentralized thread ID.<\/li>\n<li><code>processHandle<\/code> {<code>Object<\/code>} [Optional, Default: null] &#8211; Handle of the calling UI dApp process.<\/li>\n<li><code>mode<\/code> {<code>eVMMetaCodeExecutionMode<\/code>} [Optional, Default: <code>RAW<\/code>] &#8211; Execution mode.<\/li>\n<li><code>reqID<\/code> {<code>number<\/code>} [Optional, Default: 0] &#8211; Specific request ID to use.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; A request identifier (<code>reqID &gt; 0<\/code>) if sent successfully, otherwise 0.<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c searchBlockchain -search \"&lt;query&gt;\" -size &lt;size&gt; -page &lt;page&gt; [-flags &lt;flags&gt;]<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addNewSearchResultsListener<\/code> (Results delivered within a <code>CSearchResults<\/code> object, potentially containing mixed types).<\/li>\n<li><strong>Async Version:<\/strong> <code>searchBlockchainA(...)<\/code> -&gt; <code>Promise&lt;CSearchResults&gt;<\/code><\/li>\n<li><strong>Example (Async &#8211; Search for a specific ID):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">search<\/span>(<span class=\"hljs-params\">queryTerm<\/span>) <\/span>{<br \/>\n<span class=\"hljs-keyword\">try<\/span> {<br \/>\n<span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>;<br \/>\n<span class=\"hljs-comment\">\/\/ Search only for blocks and transactions<\/span><br \/>\n<span class=\"hljs-keyword\">const<\/span> filter = <span class=\"hljs-keyword\">new<\/span> CSearchFilter(CSearchFilter.NO_STANDARD); <span class=\"hljs-comment\">\/\/ Start with no standard flags<\/span><br \/>\nfilter.setStandardFlags(CSearchFilter.StandardFlags.BLOCKS);<br \/>\nfilter.setStandardFlags(CSearchFilter.StandardFlags.TRANSACTIONS);<span class=\"hljs-keyword\">const<\/span> searchResults = <span class=\"hljs-keyword\">await<\/span> vmContext.searchBlockchainA(queryTerm, <span class=\"hljs-number\">10<\/span>, <span class=\"hljs-number\">1<\/span>, filter, <span class=\"hljs-literal\">undefined<\/span>, processHandle);<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Found <span class=\"hljs-subst\">${searchResults.getTotalResultCount()}<\/span> results.`<\/span>);<br \/>\n<span class=\"hljs-comment\">\/\/ Process results (could be CBlockDesc or CTransactionDesc)<\/span><br \/>\n} <span class=\"hljs-keyword\">catch<\/span> (error) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">`Error searching for \"<span class=\"hljs-subst\">${queryTerm}<\/span>\":`<\/span>, error);<br \/>\n}<br \/>\n}<br \/>\nsearch(<span class=\"hljs-string\">\"some_block_or_tx_id\"<\/span>);<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<hr \/>\n<h4 id=\"-getnetworkutilization24h-threadid-processhandle-mode-reqid-\"><code>getNetworkUtilization24h(threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves the average network utilization percentage over the last 24 hours.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong> See <code>getBlockchainStatus<\/code>.<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; Request ID (<code>reqID &gt; 0<\/code>).<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getNetworkUtilization24h<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addBlockchainStatsListener<\/code> (Event <code>arg.data<\/code> contains the utilization percentage).<\/li>\n<li><strong>Async Version:<\/strong> <code>getNetworkUtilization24hA(...)<\/code> -&gt; <code>Promise&lt;number&gt;<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-getblocksize24h-threadid-processhandle-mode-reqid-\"><code>getBlockSize24h(threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves the average block size in bytes over the last 24 hours.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong> See <code>getBlockchainStatus<\/code>.<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; Request ID (<code>reqID &gt; 0<\/code>).<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getBlockSize24h<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addBlockchainStatsListener<\/code> (Event <code>arg.data<\/code> contains the average size in bytes).<\/li>\n<li><strong>Async Version:<\/strong> <code>getBlockSize24hA(...)<\/code> -&gt; <code>Promise&lt;number&gt;<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-getblockrewards24h-threadid-processhandle-mode-reqid-\"><code>getBlockRewards24h(threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves the average block rewards (in attoGNC) over the last 24 hours.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong> See <code>getBlockchainStatus<\/code>.<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; Request ID (<code>reqID &gt; 0<\/code>).<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getBlockRewards24h<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addBlockchainStatsListener<\/code> (Event <code>arg.data<\/code> contains the average reward as BigInt).<\/li>\n<li><strong>Async Version:<\/strong> <code>getBlockRewards24hA(...)<\/code> -&gt; <code>Promise&lt;BigInt&gt;<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-getaveragekeyblocktime24h-threadid-processhandle-mode-reqid-\"><code>getAverageKeyBlockTime24h(threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves the average time between key blocks in seconds over the last 24 hours.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong> See <code>getBlockchainStatus<\/code>.<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; Request ID (<code>reqID &gt; 0<\/code>).<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getAverageKeyBlockTime24h<\/code> (Note: CVMContext code currently uses <code>getAverageBlockTime24h<\/code> GridScript, might be an inconsistency).<\/li>\n<li><strong>Response Event:<\/strong> <code>addBlockchainStatsListener<\/code> (Event <code>arg.data<\/code> contains the average time in seconds).<\/li>\n<li><strong>Async Version:<\/strong> <code>getAverageKeyBlockTime24hA(...)<\/code> -&gt; <code>Promise&lt;number&gt;<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-getaverageblocktime24h-threadid-processhandle-mode-reqid-\"><code>getAverageBlockTime24h(threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves the average time between all blocks (data and key) in seconds over the last 24 hours.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong> See <code>getBlockchainStatus<\/code>.<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; Request ID (<code>reqID &gt; 0<\/code>).<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getAverageBlockTime24h<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addBlockchainStatsListener<\/code> (Event <code>arg.data<\/code> contains the average time in seconds).<\/li>\n<li><strong>Async Version:<\/strong> <code>getAverageBlockTime24hA(...)<\/code> -&gt; <code>Promise&lt;number&gt;<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-getblockdetails-blockid-includetx-includemem-includesec-threadid-processhandle-mode-reqid-\"><code>getBlockDetails(blockID, includeTX, includeMem, includeSec, threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves detailed information for a specific block.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>blockID<\/code> {<code>string<\/code>} &#8211; The ID of the block to retrieve.<\/li>\n<li><code>includeTX<\/code> {<code>boolean<\/code>} [Optional, Default: true] &#8211; If true, include the list of transactions within the block (<code>-tx<\/code> flag).<\/li>\n<li><code>includeMem<\/code> {<code>boolean<\/code>} [Optional, Default: false] &#8211; (Likely unused for block details, but present in signature) Include mempool data (<code>-mem<\/code> flag).<\/li>\n<li><code>includeSec<\/code> {<code>boolean<\/code>} [Optional, Default: false] &#8211; If true, include a security report related to the block\/miner (<code>-sec<\/code> flag).<\/li>\n<li><code>threadID<\/code> {<code>ArrayBuffer<\/code>} [Optional, Default: Data Thread] &#8211; The target decentralized thread ID.<\/li>\n<li><code>processHandle<\/code> {<code>Object<\/code>} [Optional, Default: null] &#8211; Handle of the calling UI dApp process.<\/li>\n<li><code>mode<\/code> {<code>eVMMetaCodeExecutionMode<\/code>} [Optional, Default: <code>RAW<\/code>] &#8211; Execution mode.<\/li>\n<li><code>reqID<\/code> {<code>number<\/code>} [Optional, Default: 0] &#8211; Specific request ID to use.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; A request identifier (<code>reqID &gt; 0<\/code>) if sent successfully, otherwise 0.<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getBlockDetails -search \"&lt;blockID&gt;\" [-tx] [-mem] [-sec]<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addNewBlockDetailsListener<\/code> (Event <code>arg.data<\/code> contains a <code>CBlockDesc<\/code> instance).<\/li>\n<li><strong>Async Version:<\/strong> <code>getBlockDetailsA(...)<\/code> -&gt; <code>Promise&lt;CBlockDesc&gt;<\/code><\/li>\n<li><strong>Example (Async):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">fetchBlock<\/span>(<span class=\"hljs-params\">id<\/span>) <\/span>{<br \/>\n<span class=\"hljs-keyword\">try<\/span> {<br \/>\n<span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>;<br \/>\n<span class=\"hljs-keyword\">const<\/span> blockDetails = <span class=\"hljs-keyword\">await<\/span> vmContext.getBlockDetailsA(id, <span class=\"hljs-literal\">true<\/span>, <span class=\"hljs-literal\">false<\/span>, <span class=\"hljs-literal\">false<\/span>, <span class=\"hljs-literal\">undefined<\/span>, processHandle);<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Block Height: <span class=\"hljs-subst\">${blockDetails.height}<\/span>`<\/span>);<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Number of Transactions: <span class=\"hljs-subst\">${blockDetails.transactionsCount}<\/span>`<\/span>);<br \/>\n<span class=\"hljs-comment\">\/\/ Access other blockDetails properties (CBlockDesc instance)<\/span><br \/>\n} <span class=\"hljs-keyword\">catch<\/span> (error) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">`Error fetching block <span class=\"hljs-subst\">${id}<\/span>:`<\/span>, error);<br \/>\n}<br \/>\n}<br \/>\nfetchBlock(<span class=\"hljs-string\">\"some_block_id\"<\/span>);<br \/>\n<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-getdomainhistory-address-size-page-esorttransactionsbyval-stateid-threadid-processhandle-mode-reqid-\"><code>getDomainHistory(address, size, page, eSortTransactionsByVal, stateID, threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves the transaction history for a specific domain address.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>address<\/code> {<code>string<\/code>} &#8211; The domain address to query.<\/li>\n<li><code>size<\/code> {<code>number<\/code>} [Optional, Default: 10] &#8211; Number of transactions per page.<\/li>\n<li><code>page<\/code> {<code>number<\/code>} [Optional, Default: 1] &#8211; Page number to retrieve.<\/li>\n<li><code>eSortTransactionsByVal<\/code> {<code>eSortTransactionsBy<\/code>} [Optional, Default: <code>timestampDesc<\/code>] &#8211; Sorting criteria for transactions.<\/li>\n<li><code>stateID<\/code> {<code>string<\/code>} [Optional, Default: &#8220;&#8221;] &#8211; State ID for restoring iterators (used for deep pagination, currently experimental).<\/li>\n<li><code>threadID<\/code> {<code>ArrayBuffer<\/code>} [Optional, Default: Data Thread] &#8211; The target decentralized thread ID.<\/li>\n<li><code>processHandle<\/code> {<code>Object<\/code>} [Optional, Default: null] &#8211; Handle of the calling UI dApp process.<\/li>\n<li><code>mode<\/code> {<code>eVMMetaCodeExecutionMode<\/code>} [Optional, Default: <code>RAW<\/code>] &#8211; Execution mode.<\/li>\n<li><code>reqID<\/code> {<code>number<\/code>} [Optional, Default: 0] &#8211; Specific request ID to use.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; A request identifier (<code>reqID &gt; 0<\/code>) if sent successfully, otherwise 0.<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getDomainHistory -search \"&lt;address&gt;\" -size &lt;size&gt; -page &lt;page&gt; -sort &lt;eSortTransactionsByVal&gt; [-state \"&lt;stateID&gt;\"]<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addNewSearchResultsListener<\/code> (Results delivered within a <code>CSearchResults<\/code> object containing <code>CTransactionDesc<\/code> instances relevant to the domain).<\/li>\n<li><strong>Async Version:<\/strong> <code>getDomainHistoryA(...)<\/code> -&gt; <code>Promise&lt;CSearchResults&gt;<\/code><\/li>\n<li><strong>Example (Async):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">fetchDomainHistory<\/span>(<span class=\"hljs-params\">domainAddr<\/span>) <\/span>{<br \/>\n<span class=\"hljs-keyword\">try<\/span> {<br \/>\n<span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>;<br \/>\n<span class=\"hljs-keyword\">const<\/span> historyResults = <span class=\"hljs-keyword\">await<\/span> vmContext.getDomainHistoryA(domainAddr, <span class=\"hljs-number\">25<\/span>, <span class=\"hljs-number\">1<\/span>, eSortTransactionsBy.timestampDesc, <span class=\"hljs-string\">\"\"<\/span>, <span class=\"hljs-literal\">undefined<\/span>, processHandle);<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Found <span class=\"hljs-subst\">${historyResults.getTotalResultCount()}<\/span> transactions for domain <span class=\"hljs-subst\">${domainAddr}<\/span>.`<\/span>);<br \/>\n<span class=\"hljs-comment\">\/\/ Process historyResults containing CTransactionDesc objects<\/span><br \/>\n} <span class=\"hljs-keyword\">catch<\/span> (error) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">`Error fetching history for domain <span class=\"hljs-subst\">${domainAddr}<\/span>:`<\/span>, error);<br \/>\n}<br \/>\n}<br \/>\nfetchDomainHistory(<span class=\"hljs-string\">\"some_domain_address\"<\/span>);<br \/>\n<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-getdomaindetails-address-perspective-includesec-threadid-processhandle-mode-reqid-\"><code>getDomainDetails(address, perspective, includeSec, threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves detailed information about a specific domain address.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>address<\/code> {<code>string<\/code>} &#8211; The domain address to query.<\/li>\n<li><code>perspective<\/code> {<code>string<\/code>} [Optional, Default: &#8220;&#8221;] &#8211; Specifies a perspective for viewing domain state (advanced feature).<\/li>\n<li><code>includeSec<\/code> {<code>boolean<\/code>} [Optional, Default: false] &#8211; If true, includes the operator security report (<code>-sec<\/code> flag).<\/li>\n<li><code>threadID<\/code> {<code>ArrayBuffer<\/code>} [Optional, Default: Data Thread] &#8211; The target decentralized thread ID.<\/li>\n<li><code>processHandle<\/code> {<code>Object<\/code>} [Optional, Default: null] &#8211; Handle of the calling UI dApp process.<\/li>\n<li><code>mode<\/code> {<code>eVMMetaCodeExecutionMode<\/code>} [Optional, Default: <code>RAW<\/code>] &#8211; Execution mode.<\/li>\n<li><code>reqID<\/code> {<code>number<\/code>} [Optional, Default: 0] &#8211; Specific request ID to use.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; A request identifier (<code>reqID &gt; 0<\/code>) if sent successfully, otherwise 0.<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getDomainDetails -search \"&lt;address&gt;\" [-perspective \"&lt;perspective&gt;\"] [-sec]<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addNewDomainDetailsListener<\/code> (Event <code>arg.data<\/code> contains a <code>CDomainDesc<\/code> instance).<\/li>\n<li><strong>Async Version:<\/strong> <code>getDomainDetailsA(...)<\/code> -&gt; <code>Promise&lt;CDomainDesc&gt;<\/code><\/li>\n<li><strong>Example (Async):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">fetchDomain<\/span>(<span class=\"hljs-params\">domainAddr<\/span>) <\/span>{<br \/>\n<span class=\"hljs-keyword\">try<\/span> {<br \/>\n<span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>;<br \/>\n<span class=\"hljs-keyword\">const<\/span> domainDetails = <span class=\"hljs-keyword\">await<\/span> vmContext.getDomainDetailsA(domainAddr, <span class=\"hljs-string\">\"\"<\/span>, <span class=\"hljs-literal\">false<\/span>, <span class=\"hljs-literal\">undefined<\/span>, processHandle);<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Domain: <span class=\"hljs-subst\">${domainDetails.domain}<\/span>`<\/span>);<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Balance: <span class=\"hljs-subst\">${domainDetails.balanceTxt}<\/span>`<\/span>);<br \/>\n<span class=\"hljs-comment\">\/\/ Access other domainDetails properties (CDomainDesc instance)<\/span><br \/>\n} <span class=\"hljs-keyword\">catch<\/span> (error) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">`Error fetching details for domain <span class=\"hljs-subst\">${domainAddr}<\/span>:`<\/span>, error);<br \/>\n}<br \/>\n}<br \/>\nfetchDomain(<span class=\"hljs-string\">\"some_domain_address\"<\/span>);<br \/>\n<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-gettransactiondetails-transactionid-threadid-processhandle-mode-reqid-\"><code>getTransactionDetails(transactionID, threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves detailed information about a specific transaction.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>transactionID<\/code> {<code>string<\/code>} &#8211; The verifiable ID of the transaction.<\/li>\n<li><code>threadID<\/code> {<code>ArrayBuffer<\/code>} [Optional, Default: Data Thread] &#8211; The target decentralized thread ID.<\/li>\n<li><code>processHandle<\/code> {<code>Object<\/code>} [Optional, Default: null] &#8211; Handle of the calling UI dApp process.<\/li>\n<li><code>mode<\/code> {<code>eVMMetaCodeExecutionMode<\/code>} [Optional, Default: <code>RAW<\/code>] &#8211; Execution mode.<\/li>\n<li><code>reqID<\/code> {<code>number<\/code>} [Optional, Default: 0] &#8211; Specific request ID to use.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; A request identifier (<code>reqID &gt; 0<\/code>) if sent successfully, otherwise 0 or false if <code>transactionID<\/code> is invalid.<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getTransactionDetails -search \"&lt;transactionID&gt;\"<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addNewTransactionDetailsListener<\/code> (Event <code>arg.data<\/code> contains a <code>CTransactionDesc<\/code> instance).<\/li>\n<li><strong>Async Version:<\/strong> <code>getTransactionDetailsA(...)<\/code> -&gt; <code>Promise&lt;CTransactionDesc&gt;<\/code><\/li>\n<li><strong>Example (Async):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">fetchTxDetails<\/span>(<span class=\"hljs-params\">txId<\/span>) <\/span>{<br \/>\n<span class=\"hljs-keyword\">try<\/span> {<br \/>\n<span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>;<br \/>\n<span class=\"hljs-keyword\">const<\/span> txDetails = <span class=\"hljs-keyword\">await<\/span> vmContext.getTransactionDetailsA(txId, <span class=\"hljs-literal\">undefined<\/span>, processHandle);<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Transaction Sender: <span class=\"hljs-subst\">${txDetails.sender}<\/span>`<\/span>);<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Transaction Value: <span class=\"hljs-subst\">${txDetails.valueTxt}<\/span>`<\/span>);<br \/>\n<span class=\"hljs-comment\">\/\/ Access other txDetails properties (CTransactionDesc instance)<\/span><br \/>\n} <span class=\"hljs-keyword\">catch<\/span> (error) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">`Error fetching details for TX <span class=\"hljs-subst\">${txId}<\/span>:`<\/span>, error);<br \/>\n}<br \/>\n}<br \/>\nfetchTxDetails(<span class=\"hljs-string\">\"some_transaction_id\"<\/span>);<br \/>\n<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-getliveness-threadid-processhandle-mode-reqid-\"><code>getLiveness(threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves the current network liveness state.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong> See <code>getBlockchainStatus<\/code>.<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; Request ID (<code>reqID &gt; 0<\/code>).<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getLiveness<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addBlockchainStatsListener<\/code> (Event <code>arg.data<\/code> contains the liveness state, typically a value from <code>eLivenessState<\/code> enum).<\/li>\n<li><strong>Async Version:<\/strong> <code>getLivenessA(...)<\/code> -&gt; <code>Promise&lt;number&gt;<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-getusdtprice-threadid-processhandle-mode-reqid-\"><code>getUSDTPrice(threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves the current approximate price of GNC in USDT (fetched from oracle sources by Core nodes).<\/p>\n<ul>\n<li><strong>Parameters:<\/strong> See <code>getBlockchainStatus<\/code>.<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; Request ID (<code>reqID &gt; 0<\/code>).<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getUSDTPrice<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addBlockchainStatsListener<\/code> (Event <code>arg.data<\/code> contains the price, likely as a BigInt representing atto-USDT per GNC or similar fixed-point representation).<\/li>\n<li><strong>Async Version:<\/strong> <code>getUSDTPriceA(...)<\/code> -&gt; <code>Promise&lt;BigInt&gt;<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-getheight-iskeyheight-threadid-processhandle-mode-reqid-\"><code>getHeight(isKeyHeight, threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Retrieves the current height of the blockchain (either regular block height or key block height). Includes internal caching for efficiency.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>isKeyHeight<\/code> {<code>boolean<\/code>} &#8211; If true, retrieves the latest key block height; otherwise, retrieves the latest regular block height.<\/li>\n<li><code>threadID<\/code> {<code>ArrayBuffer<\/code>} [Optional, Default: Data Thread] &#8211; The target decentralized thread ID.<\/li>\n<li><code>processHandle<\/code> {<code>Object<\/code>} [Optional, Default: null] &#8211; Handle of the calling UI dApp process.<\/li>\n<li><code>mode<\/code> {<code>eVMMetaCodeExecutionMode<\/code>} [Optional, Default: <code>RAW<\/code>] &#8211; Execution mode.<\/li>\n<li><code>reqID<\/code> {<code>number<\/code>} [Optional, Default: 0] &#8211; Specific request ID to use.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; Request ID (<code>reqID &gt; 0<\/code>) if a network request is sent, or the same <code>reqID<\/code> (potentially generated) if returning a cached value via a scheduled event.<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c getHeight [-key]<\/code><\/li>\n<li><strong>Response Event:<\/strong> <code>addNewGridScriptResultListener<\/code> (Event <code>arg.data<\/code> contains the height number). The method internally uses caching (<code>mCachedHeight<\/code>, <code>mCachedKeyHeight<\/code>) and may return a cached value via a <code>setTimeout<\/code> event if <code>allowCache<\/code> is true (in async version) and the cache is fresh.<\/li>\n<li><strong>Async Version:<\/strong> <code>getHeightA(isKeyHeight, ..., allowCache)<\/code> -&gt; <code>Promise&lt;number&gt;<\/code> (The <code>allowCache<\/code> parameter controls cache usage).<\/li>\n<li><strong>Example (Async &#8211; Get Key Height):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">fetchKeyHeight<\/span>() <\/span>{<br \/>\n<span class=\"hljs-keyword\">try<\/span> {<br \/>\n<span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>;<br \/>\n<span class=\"hljs-keyword\">const<\/span> keyHeight = <span class=\"hljs-keyword\">await<\/span> vmContext.getHeightA(<span class=\"hljs-literal\">true<\/span>, <span class=\"hljs-literal\">undefined<\/span>, processHandle, <span class=\"hljs-literal\">undefined<\/span>, <span class=\"hljs-number\">0<\/span>, <span class=\"hljs-number\">5000<\/span>, <span class=\"hljs-literal\">true<\/span>); <span class=\"hljs-comment\">\/\/ Allow cache<\/span><br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">`Current Key Block Height: <span class=\"hljs-subst\">${keyHeight}<\/span>`<\/span>);<br \/>\n} <span class=\"hljs-keyword\">catch<\/span> (error) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Error fetching key height:\"<\/span>, error);<br \/>\n}<br \/>\n}<br \/>\nfetchKeyHeight();<br \/>\n<\/code><\/li>\n<\/ul>\n<hr \/>\n<h3 id=\"4-2-subscription-methods\">4.2 Subscription Methods<\/h3>\n<h4 id=\"-subscribetoblockchainupdates-threadid-processhandle-mode-reqid-\"><code>subscribeToBlockchainUpdates(threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Subscribes the current <code>CVMContext<\/code> instance to receive real-time updates about new blocks and potentially other blockchain events from the connected Core node. Registered listeners (e.g., <code>addNewBlockDetailsListener<\/code>, <code>addNewTransactionDetailsListener<\/code>) will be triggered as new data arrives.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong> See <code>getBlockchainStatus<\/code>.<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code> | <code>boolean<\/code>} &#8211; A request identifier (<code>reqID &gt; 0<\/code>) or <code>true<\/code> if already subscribed. Returns <code>false<\/code> on failure to send the request.<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c startBlockchainUpdates<\/code><\/li>\n<li><strong>Response Event:<\/strong> No direct response event. Success enables receiving blockchain update notifications via standard listeners.<\/li>\n<li><strong>Async Version:<\/strong> <code>subscribeToBlockchainUpdatesA(...)<\/code> -&gt; <code>Promise&lt;boolean&gt;<\/code><\/li>\n<li><strong>Example (Non-Async):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>;<br \/>\n<span class=\"hljs-keyword\">if<\/span> (vmContext.subscribeToBlockchainUpdates(<span class=\"hljs-literal\">undefined<\/span>, processHandle)) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"Subscription request sent successfully.\"<\/span>);<br \/>\n<span class=\"hljs-comment\">\/\/ Register listeners like addNewBlockDetailsListener here<\/span><br \/>\n} <span class=\"hljs-keyword\">else<\/span> {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Failed to send subscription request.\"<\/span>);<br \/>\n}<br \/>\n<\/code><\/li>\n<\/ul>\n<hr \/>\n<h4 id=\"-unsubscribefromblockchainupdates-threadid-processhandle-mode-reqid-\"><code>unsubscribeFromBlockchainUpdates(threadID, processHandle, mode, reqID)<\/code><\/h4>\n<p>Stops receiving real-time blockchain updates for this <code>CVMContext<\/code> instance.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong> See <code>getBlockchainStatus<\/code>.<\/li>\n<li><strong>Returns:<\/strong> {<code>number<\/code> | <code>boolean<\/code>} &#8211; A request identifier (<code>reqID &gt; 0<\/code>) or <code>true<\/code> if already unsubscribed. Returns <code>false<\/code> on failure to send the request.<\/li>\n<li><strong>Underlying GridScript:<\/strong> <code>context -c stopBlockchainUpdates<\/code><\/li>\n<li><strong>Response Event:<\/strong> No direct response event. Success stops the flow of update notifications.<\/li>\n<li><strong>Async Version:<\/strong> <code>unsubscribeFromBlockchainUpdatesA(...)<\/code> -&gt; <code>Promise&lt;boolean&gt;<\/code><\/li>\n<li><strong>Example (Non-Async):<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">const<\/span> vmContext = CVMContext.getInstance();<br \/>\n<span class=\"hljs-keyword\">const<\/span> processHandle = <span class=\"hljs-keyword\">this<\/span>;<br \/>\n<span class=\"hljs-keyword\">if<\/span> (vmContext.unsubscribeFromBlockchainUpdates(<span class=\"hljs-literal\">undefined<\/span>, processHandle)) {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">\"Unsubscription request sent successfully.\"<\/span>);<br \/>\n} <span class=\"hljs-keyword\">else<\/span> {<br \/>\n<span class=\"hljs-built_in\">console<\/span>.error(<span class=\"hljs-string\">\"Failed to send unsubscription request.\"<\/span>);<br \/>\n}<br \/>\n<\/code><\/li>\n<\/ul>\n<hr \/>\n<h3 id=\"4-3-bridge-api-methods\">4.3 Bridge API Methods<\/h3>\n<p>The Bridge API methods connect the GRIDNET OS wallet and explorer directly to the GRIDNET Bridge coordinator \u2014 the service that routes GNC value across chains (GRIDNET OS \u2194 Arbitrum \u2194 HyperEVM). All bridge methods are asynchronous (the <code>A<\/code> suffix denotes a Promise-returning async variant). Each resolves with an <code>ArrayBuffer[]<\/code> whose first element contains the coordinator&#8217;s raw JSON response body; decode it with <code>new TextDecoder().decode(result[0])<\/code>.<\/p>\n<p>The bridge coordinator is queried over HTTP. By default all bridge methods target <code>http:\/\/localhost:3000<\/code> (local coordinator). Pass a custom <code>bridgeUrl<\/code> to target a remote coordinator.<\/p>\n<h4 id=\"getbridgestatusa-threadid-processhandle-mode-reqid-bridgeurl-timeoutms\">getBridgeStatusA(threadID, processHandle, mode, reqID, bridgeUrl, timeoutMS)<\/h4>\n<p>Fetches the bridge coordinator&#8217;s health and configuration. Returns supported routes, deployed contract addresses, and overall coordinator health derived from the invariant checker&#8217;s last snapshot.<\/p>\n<ul>\n<li><strong>threadID<\/strong> <code>ArrayBuffer<\/code> \u2014 Decentralized thread ID (default: system thread)<\/li>\n<li><strong>processHandle<\/strong> <code>Object|null<\/code> \u2014 Calling process handle (default: <code>null<\/code>)<\/li>\n<li><strong>mode<\/strong> <code>eVMMetaCodeExecutionMode<\/code> \u2014 Execution mode (default: <code>RAW<\/code>)<\/li>\n<li><strong>reqID<\/strong> <code>number<\/code> \u2014 Request ID, 0 = auto-generate (default: <code>0<\/code>)<\/li>\n<li><strong>bridgeUrl<\/strong> <code>string|null<\/code> \u2014 Coordinator base URL (default: <code>null<\/code> \u2192 <code>http:\/\/localhost:3000<\/code>)<\/li>\n<li><strong>timeoutMS<\/strong> <code>number<\/code> \u2014 Timeout in milliseconds (default: <code>10000<\/code>)<\/li>\n<\/ul>\n<p><strong>Returns:<\/strong> <code>Promise&lt;ArrayBuffer[]&gt;<\/code> \u2014 Resolves with <code>[responseBuffer]<\/code>. Decode to get: <code>{ status: \"ok\", supportedRoutes: [...], coordinatorHealthy: bool }<\/code><\/p>\n<pre><code>const r = await gVMContext.getBridgeStatusA();\r\nconst status = JSON.parse(new TextDecoder().decode(r[0]));\r\nconsole.log(status.status);          \/\/ \"ok\"\r\nconsole.log(status.supportedRoutes); \/\/ [{id:\"arbitrum\",...}, {id:\"hyperEVM\",...}, ...]\r\n<\/code><\/pre>\n<h4 id=\"getbridgetransferstatusa-txhash-threadid-processhandle-mode-reqid-bridgeurl-timeoutms\">getBridgeTransferStatusA(txHash, threadID, processHandle, mode, reqID, bridgeUrl, timeoutMS)<\/h4>\n<p>Looks up a specific bridge transfer by its GRIDNET source transaction hash. Returns the transfer&#8217;s current routing status, direction, destination chain, amount, and on-chain hashes.<\/p>\n<ul>\n<li><strong>txHash<\/strong> <code>string<\/code> \u2014 GRIDNET source transaction hash (base58Check receipt ID)<\/li>\n<li><strong>threadID<\/strong> <code>ArrayBuffer<\/code> \u2014 Decentralized thread ID (default: system thread)<\/li>\n<li><strong>processHandle<\/strong> <code>Object|null<\/code> \u2014 Calling process handle (default: <code>null<\/code>)<\/li>\n<li><strong>mode<\/strong> <code>eVMMetaCodeExecutionMode<\/code> \u2014 Execution mode (default: <code>RAW<\/code>)<\/li>\n<li><strong>reqID<\/strong> <code>number<\/code> \u2014 Request ID (default: <code>0<\/code>)<\/li>\n<li><strong>bridgeUrl<\/strong> <code>string|null<\/code> \u2014 Coordinator base URL (default: <code>null<\/code>)<\/li>\n<li><strong>timeoutMS<\/strong> <code>number<\/code> \u2014 Timeout in milliseconds (default: <code>10000<\/code>)<\/li>\n<\/ul>\n<p><strong>Returns:<\/strong> <code>Promise&lt;ArrayBuffer[]&gt;<\/code> \u2014 Resolves with <code>[responseBuffer]<\/code>. Decode to get: <code>{ found: bool, transfer: { status, direction, destChain, amount, destTxHash, ... } }<\/code><\/p>\n<pre><code>const txHash = '4HZn63tSv9wKx9ErtnCksPe1sHAj7vXdqaajXH2Zhmy7oBCgqE';\r\nconst r = await gVMContext.getBridgeTransferStatusA(txHash);\r\nconst data = JSON.parse(new TextDecoder().decode(r[0]));\r\nif (data.found) {\r\n  console.log(data.transfer.status);    \/\/ \"COMPLETED\"\r\n  console.log(data.transfer.destChain); \/\/ \"arbitrum\"\r\n}\r\n<\/code><\/pre>\n<h4 id=\"getbridgecustodya-threadid-processhandle-mode-reqid-bridgeurl-timeoutms\">getBridgeCustodyA(threadID, processHandle, mode, reqID, bridgeUrl, timeoutMS)<\/h4>\n<p>Returns the bridge&#8217;s current cross-chain supply distribution: wGNC on Arbitrum, GNC OFT on HyperEVM, HyperCore balance, GRIDNET OS circulating supply, and solvency status. Used to render the Explorer Bridge tab custody chart.<\/p>\n<ul>\n<li><strong>threadID \/ processHandle \/ mode \/ reqID \/ bridgeUrl \/ timeoutMS<\/strong> \u2014 Same as <code>getBridgeStatusA<\/code><\/li>\n<\/ul>\n<p><strong>Returns:<\/strong> <code>Promise&lt;ArrayBuffer[]&gt;<\/code> \u2014 Decodes to: <code>{ success: true, data: { arb: {...}, hyperEVM: {...}, hyperCore: {...}, totals: {...} } }<\/code><\/p>\n<pre><code>const r = await gVMContext.getBridgeCustodyA();\r\nconst { data } = JSON.parse(new TextDecoder().decode(r[0]));\r\nconsole.log(data.arb.wgncBalance);    \/\/ wGNC held on Arbitrum\r\nconsole.log(data.hyperEVM.oftBalance); \/\/ GNC OFT held on HyperEVM\r\n<\/code><\/pre>\n<h4 id=\"getarbgncbalancea-address-threadid-processhandle-mode-reqid-timeoutms\">getArbGNCBalanceA(address, threadID, processHandle, mode, reqID, timeoutMS)<\/h4>\n<p>Queries the wGNC (Wrapped GNC) ERC-20 balance for a given Ethereum address on Arbitrum. Makes a direct <code>eth_call<\/code> to the wGNC contract using the configured Arbitrum RPC endpoint.<\/p>\n<ul>\n<li><strong>address<\/strong> <code>string<\/code> \u2014 Ethereum address (<code>0x...<\/code>) to query<\/li>\n<li><strong>threadID<\/strong> <code>ArrayBuffer<\/code> \u2014 (default: system thread)<\/li>\n<li><strong>processHandle<\/strong> <code>Object|null<\/code> \u2014 (default: <code>null<\/code>)<\/li>\n<li><strong>mode<\/strong> <code>eVMMetaCodeExecutionMode<\/code> \u2014 (default: <code>RAW<\/code>)<\/li>\n<li><strong>reqID<\/strong> <code>number<\/code> \u2014 (default: <code>0<\/code>)<\/li>\n<li><strong>timeoutMS<\/strong> <code>number<\/code> \u2014 (default: <code>15000<\/code>)<\/li>\n<\/ul>\n<p><strong>Returns:<\/strong> <code>Promise&lt;ArrayBuffer[]&gt;<\/code> \u2014 Decodes to: <code>{ balance: \"1234567890000000\", balanceFormatted: \"0.001234\", symbol: \"wGNC\" }<\/code><\/p>\n<pre><code>const r = await gVMContext.getArbGNCBalanceA('0x1b224a88d0895Dae32d76f028Bc4959bc5218cE4');\r\nconst bal = JSON.parse(new TextDecoder().decode(r[0]));\r\nconsole.log(bal.balanceFormatted); \/\/ e.g. \"0.00100\"\r\n<\/code><\/pre>\n<h4 id=\"gethyperevmgncbalancea-address-threadid-processhandle-mode-reqid-timeoutms\">getHyperEVMGNCBalanceA(address, threadID, processHandle, mode, reqID, timeoutMS)<\/h4>\n<p>Queries the GNC OFT (Omnichain Fungible Token) balance for a given address on HyperEVM (Hyperliquid&#8217;s EVM layer). Makes a direct <code>eth_call<\/code> to the GNC OFT contract via the HyperEVM RPC endpoint.<\/p>\n<ul>\n<li><strong>address<\/strong> <code>string<\/code> \u2014 Ethereum address to query<\/li>\n<li><strong>threadID \/ processHandle \/ mode \/ reqID \/ timeoutMS<\/strong> \u2014 Same as <code>getArbGNCBalanceA<\/code><\/li>\n<\/ul>\n<p><strong>Returns:<\/strong> <code>Promise&lt;ArrayBuffer[]&gt;<\/code> \u2014 Decodes to: <code>{ balance: \"...\", balanceFormatted: \"...\", symbol: \"GNC\" }<\/code><\/p>\n<pre><code>const r = await gVMContext.getHyperEVMGNCBalanceA('0x1b224a88d0895Dae32d76f028Bc4959bc5218cE4');\r\nconst bal = JSON.parse(new TextDecoder().decode(r[0]));\r\nconsole.log(bal.balanceFormatted);\r\n<\/code><\/pre>\n<h4 id=\"gethypercoregncbalancea-address-threadid-processhandle-mode-reqid-timeoutms\">getHyperCoreGNCBalanceA(address, threadID, processHandle, mode, reqID, timeoutMS)<\/h4>\n<p>Queries the GNC spot balance on HyperCore (Hyperliquid&#8217;s native L1 order book layer) for a given Ethereum address. Queries the HyperCore REST API for the account&#8217;s spot holdings.<\/p>\n<ul>\n<li><strong>address<\/strong> <code>string<\/code> \u2014 Ethereum address (HyperCore uses Ethereum-format addresses)<\/li>\n<li><strong>threadID \/ processHandle \/ mode \/ reqID \/ timeoutMS<\/strong> \u2014 Same as <code>getArbGNCBalanceA<\/code><\/li>\n<\/ul>\n<p><strong>Returns:<\/strong> <code>Promise&lt;ArrayBuffer[]&gt;<\/code> \u2014 Decodes to: <code>{ balance: \"...\", balanceFormatted: \"...\", symbol: \"GNC\", tokenId: number }<\/code><\/p>\n<pre><code>const r = await gVMContext.getHyperCoreGNCBalanceA('0x1b224a88d0895Dae32d76f028Bc4959bc5218cE4');\r\nconst bal = JSON.parse(new TextDecoder().decode(r[0]));\r\nconsole.log(bal.balance); \/\/ Raw balance in smallest units\r\n<\/code><\/pre>\n<h4 id=\"postbridgerequest-txref-destchain-destaddress-sourceaddress-amount-threadid-processhandle-mode-reqid-bridgeurl-timeoutms\">postBridgeRequestA(txRef, destChain, destAddress, sourceAddress, amount, threadID, processHandle, mode, reqID, bridgeUrl, timeoutMS)<\/h4>\n<p>Registers a bridge intent with the coordinator immediately after the user submits their on-chain GRIDNET OS bridge transaction. This pre-registers the destination address and chain so the coordinator can route funds correctly when it detects the confirmed on-chain transaction. The GRIDNET on-chain transaction remains the source of truth \u2014 this call only adds routing metadata.<\/p>\n<ul>\n<li><strong>txRef<\/strong> <code>string<\/code> \u2014 GRIDNET receipt ID (base58Check) of the on-chain bridge transaction<\/li>\n<li><strong>destChain<\/strong> <code>string<\/code> \u2014 Destination chain: <code>\"arbitrum\"<\/code>, <code>\"hyperEVM\"<\/code>, or <code>\"hyperCore\"<\/code><\/li>\n<li><strong>destAddress<\/strong> <code>string<\/code> \u2014 Destination address on the target chain (EVM <code>0x...<\/code> format)<\/li>\n<li><strong>sourceAddress<\/strong> <code>string<\/code> \u2014 Source GRIDNET OS address (base58Check), used for verification (default: <code>\"\"<\/code>)<\/li>\n<li><strong>amount<\/strong> <code>number<\/code> \u2014 Amount in smallest GNC units (default: <code>0<\/code>)<\/li>\n<li><strong>threadID<\/strong> <code>ArrayBuffer<\/code> \u2014 (default: system thread)<\/li>\n<li><strong>processHandle<\/strong> <code>Object|null<\/code> \u2014 (default: <code>null<\/code>)<\/li>\n<li><strong>mode<\/strong> <code>eVMMetaCodeExecutionMode<\/code> \u2014 (default: <code>RAW<\/code>)<\/li>\n<li><strong>reqID<\/strong> <code>number<\/code> \u2014 (default: <code>0<\/code>)<\/li>\n<li><strong>bridgeUrl<\/strong> <code>string|null<\/code> \u2014 Coordinator base URL (default: <code>null<\/code> \u2192 <code>http:\/\/localhost:3000<\/code>)<\/li>\n<li><strong>timeoutMS<\/strong> <code>number<\/code> \u2014 Timeout in milliseconds (default: <code>10000<\/code>)<\/li>\n<\/ul>\n<p><strong>Returns:<\/strong> <code>Promise&lt;ArrayBuffer[]&gt;<\/code> \u2014 Decodes to: <code>{ success: true, id: \"N\" }<\/code> on success, or <code>{ success: false, error: \"...\" }<\/code> on validation failure. The <code>id<\/code> field is the coordinator-assigned transfer queue ID.<\/p>\n<pre><code>\/\/ After user submits their GRIDNET bridge transaction:\r\nconst r = await gVMContext.postBridgeRequestA(\r\n  receiptID,                   \/\/ GRIDNET tx receipt hash\r\n  'arbitrum',                  \/\/ destination chain\r\n  '0xUserDestinationAddress',  \/\/ EVM destination address\r\n  userGridnetAddress,          \/\/ source GRIDNET address\r\n  1000000000000000             \/\/ amount in smallest units\r\n);\r\nconst result = JSON.parse(new TextDecoder().decode(r[0]));\r\nif (result.success) {\r\n  console.log('Bridge intent registered, transfer ID:', result.id);\r\n}\r\n<\/code><\/pre>\n<h2 id=\"5-data-objects\">5. Data Objects<\/h2>\n<p>The API uses several custom classes to represent blockchain data structures. These classes handle BER serialization\/deserialization and provide convenient getters for accessing data.<\/p>\n<h3 id=\"5-1-cblockdesc-\">5.1 <code>CBlockDesc<\/code><\/h3>\n<p>Represents a blockchain block.<\/p>\n<ul>\n<li><strong>Key Properties\/Getters:<\/strong>\n<ul>\n<li><code>blockID<\/code>: {<code>string<\/code>} Unique block identifier.<\/li>\n<li><code>height<\/code>: {<code>number<\/code>} Block height.<\/li>\n<li><code>keyHeight<\/code>: {<code>number<\/code>} Corresponding key block height.<\/li>\n<li><code>type<\/code>: {<code>eBlockType<\/code>} Type of block (Key or Data).<\/li>\n<li><code>solvedAt<\/code>: {<code>number<\/code>} Unix timestamp (seconds) when mined.<\/li>\n<li><code>minerID<\/code>: {<code>string<\/code>} Address of the miner.<\/li>\n<li><code>parentID<\/code>: {<code>string<\/code>} ID of the previous block.<\/li>\n<li><code>difficulty<\/code>: {<code>number<\/code>} Mining difficulty.<\/li>\n<li><code>transactionsCount<\/code>: {<code>number<\/code>} Number of transactions included.<\/li>\n<li><code>ergUsed<\/code>: {<code>BigInt<\/code>} Computational units used.<\/li>\n<li><code>ergLimit<\/code>: {<code>BigInt<\/code>} Maximum computational units allowed.<\/li>\n<li><code>blockReward<\/code>: {<code>BigInt<\/code>} Base reward for mining the block (attoGNC).<\/li>\n<li><code>totalReward<\/code>: {<code>BigInt<\/code>} Total reward including fees (attoGNC).<\/li>\n<li><code>transactions<\/code>: {<code>Array&lt;CTransactionDesc&gt;<\/code>} Array of transaction objects included (if requested).<\/li>\n<li><code>size<\/code>: {<code>number<\/code>} Size of the block in bytes.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Serialization:<\/strong> <code>getPackedData()<\/code> -&gt; <code>ArrayBuffer<\/code> (BER encoded).<\/li>\n<li><strong>Deserialization:<\/strong> <code>static instantiate(packedData)<\/code> -&gt; <code>CBlockDesc<\/code>.<\/li>\n<\/ul>\n<h3 id=\"5-2-ctransactiondesc-\">5.2 <code>CTransactionDesc<\/code><\/h3>\n<p>Represents a blockchain transaction.<\/p>\n<ul>\n<li><strong>Key Properties\/Getters:<\/strong>\n<ul>\n<li><code>verifiableID<\/code>: {<code>string<\/code>} Unique transaction identifier.<\/li>\n<li><code>blockID<\/code>: {<code>string<\/code>} ID of the block containing the transaction (if confirmed).<\/li>\n<li><code>height<\/code>: {<code>number<\/code>} Height of the block containing the transaction.<\/li>\n<li><code>keyHeight<\/code>: {<code>number<\/code>} Key height of the block containing the transaction.<\/li>\n<li><code>sender<\/code>: {<code>string<\/code>} Sender&#8217;s domain address.<\/li>\n<li><code>receiver<\/code>: {<code>string<\/code>} Receiver&#8217;s domain address.<\/li>\n<li><code>value<\/code>: {<code>BigInt<\/code>} Amount transferred (attoGNC).<\/li>\n<li><code>fee<\/code>: {<code>BigInt<\/code>} Transaction fee paid (attoGNC).<\/li>\n<li><code>tax<\/code>: {<code>BigInt<\/code>} Tax paid (attoGNC).<\/li>\n<li><code>type<\/code>: {<code>eTXType<\/code>} Type of transaction.<\/li>\n<li><code>result<\/code>: {<code>eTransactionValidationResult<\/code>} Validation result code.<\/li>\n<li><code>status<\/code>: {<code>string<\/code>} Human-readable status (e.g., &#8220;Pending&#8221;, &#8220;Finalized (Safe)&#8221;). Use <code>updateStatus()<\/code> or <code>refreshStatus()<\/code> for accuracy.<\/li>\n<li><code>statusColor<\/code>: {<code>string<\/code>} CSS color code for the status.<\/li>\n<li><code>confirmedTimestamp<\/code>: {<code>number<\/code>} Unix timestamp (seconds) when confirmed.<\/li>\n<li><code>unconfirmedTimestamp<\/code>: {<code>number<\/code>} Unix timestamp (seconds) when first seen.<\/li>\n<li><code>sourceCode<\/code>: {<code>string<\/code>} GridScript source code (if applicable).<\/li>\n<li><code>log<\/code>: {<code>Array&lt;string&gt;<\/code>} Execution log entries.<\/li>\n<li><code>ERGUsed<\/code>: {<code>BigInt<\/code>} Computational units consumed.<\/li>\n<li><code>ERGLimit<\/code>: {<code>BigInt<\/code>} Maximum computational units requested.<\/li>\n<li><code>nonce<\/code>: {<code>number<\/code>} Sender&#8217;s transaction sequence number.<\/li>\n<li><code>size<\/code>: {<code>number<\/code>} Size of the transaction in bytes.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Serialization:<\/strong> <code>getPackedData()<\/code> -&gt; <code>ArrayBuffer<\/code> (BER encoded).<\/li>\n<li><strong>Deserialization:<\/strong> <code>static instantiate(packedData)<\/code> -&gt; <code>CTransactionDesc<\/code>.<\/li>\n<li><strong>Helper Methods:<\/strong>\n<ul>\n<li><code>async updateStatus()<\/code>: Asynchronously fetches current heights and updates the status.<\/li>\n<li><code>refreshStatus()<\/code>: Synchronously updates the status based on <em>cached<\/em> heights.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3 id=\"5-3-cdomaindesc-\">5.3 <code>CDomainDesc<\/code><\/h3>\n<p>Represents a domain (account) on the blockchain.<\/p>\n<ul>\n<li><strong>Key Properties\/Getters:<\/strong>\n<ul>\n<li><code>domain<\/code>: {<code>string<\/code>} The domain address.<\/li>\n<li><code>balance<\/code>: {<code>BigInt<\/code>} Current available balance (attoGNC).<\/li>\n<li><code>lockedBalance<\/code>: {<code>BigInt<\/code>} Balance locked in contracts or processes (attoGNC).<\/li>\n<li><code>txCount<\/code>: {<code>number<\/code>} Total number of transactions (in + out).<\/li>\n<li><code>txInCount<\/code>: {<code>number<\/code>} Number of incoming transactions.<\/li>\n<li><code>txOutCount<\/code>: {<code>number<\/code>} Number of outgoing transactions.<\/li>\n<li><code>txTotalReceived<\/code>: {<code>BigInt<\/code>} Total amount received (attoGNC).<\/li>\n<li><code>txTotalSent<\/code>: {<code>BigInt<\/code>} Total amount sent (attoGNC).<\/li>\n<li><code>GNCTotalMined<\/code>: {<code>BigInt<\/code>} Total GNC mined (attoGNC).<\/li>\n<li><code>identityToken<\/code>: {<code>CIdentityToken | null<\/code>} Associated identity token object.<\/li>\n<li><code>securityInfo<\/code>: {<code>COperatorSecurityInfo | null<\/code>} Associated security information.<\/li>\n<li><code>nonce<\/code>: {<code>number<\/code>} Current nonce for the domain.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Serialization:<\/strong> <code>getPackedData()<\/code> -&gt; <code>ArrayBuffer<\/code> (BER encoded).<\/li>\n<li><strong>Deserialization:<\/strong> <code>static instantiate(packedData)<\/code> -&gt; <code>CDomainDesc<\/code>.<\/li>\n<\/ul>\n<h3 id=\"5-4-csearchresults-\">5.4 <code>CSearchResults<\/code><\/h3>\n<p>A container for search results returned by <code>searchBlockchain<\/code>, <code>getRecentBlocks<\/code>, <code>getRecentTransactions<\/code>, and <code>getDomainHistory<\/code>.<\/p>\n<ul>\n<li><strong>Key Properties\/Getters:<\/strong>\n<ul>\n<li><code>resultCount<\/code> \/ <code>getResultCount()<\/code>: {<code>number<\/code>} Number of results in the <em>current page<\/em>.<\/li>\n<li><code>totalResultCount<\/code> \/ <code>getTotalResultCount()<\/code>: {<code>number<\/code>} Total number of results available across all pages.<\/li>\n<li><code>currentPage<\/code> \/ <code>getCurrentPage()<\/code>: {<code>number<\/code>} The current page number.<\/li>\n<li><code>itemsPerPage<\/code> \/ <code>getItemsPerPage()<\/code>: {<code>number<\/code>} Number of items requested per page.<\/li>\n<li><code>results<\/code> \/ <code>getAllResults()<\/code>: {<code>Array&lt;ResultData&gt;<\/code>} Array containing the actual result items for the current page.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Key Methods:<\/strong>\n<ul>\n<li><code>getResult(index)<\/code>: {<code>ResultData<\/code>} Retrieves a specific result item by index. The item is wrapped in <code>ResultData<\/code>. Use <code>result.getValue()<\/code> to get the underlying <code>CBlockDesc<\/code>, <code>CTransactionDesc<\/code>, or <code>CDomainDesc<\/code>.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Serialization:<\/strong> <code>getPackedData()<\/code> -&gt; <code>ArrayBuffer<\/code> (BER encoded).<\/li>\n<li><strong>Deserialization:<\/strong> <code>static instantiate(packedData)<\/code> -&gt; <code>CSearchResults<\/code>.<\/li>\n<\/ul>\n<h3 id=\"5-5-csearchfilter-\">5.5 <code>CSearchFilter<\/code><\/h3>\n<p>Used to specify detailed search criteria beyond simple keywords.<\/p>\n<ul>\n<li><strong>Key Concepts:<\/strong>\n<ul>\n<li><strong>Standard Flags:<\/strong> Predefined flags for common entity types (<code>TRANSACTIONS<\/code>, <code>DOMAINS<\/code>, <code>BLOCKS<\/code>, <code>ADDRESSES<\/code>). Use bitwise OR (<code>|<\/code>) to combine. Access via <code>CSearchFilter.StandardFlags<\/code>. Constants <code>CSearchFilter.NO_STANDARD<\/code> (0n) and <code>CSearchFilter.ALL_STANDARD<\/code> are available.<\/li>\n<li><strong>Arbitrary Flags:<\/strong> Custom key-value pairs for backend-specific filtering.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Key Methods:<\/strong>\n<ul>\n<li><code>constructor(flags)<\/code>: Creates a filter, optionally setting initial standard flags.<\/li>\n<li><code>setStandardFlags(...flags)<\/code>: Adds one or more standard flags.<\/li>\n<li><code>setArbitraryFlag(name, value)<\/code>: Sets a custom flag and its value (value defaults to empty string if omitted, boolean <code>false<\/code> removes the flag).<\/li>\n<li><code>hasStandardFlag(flag)<\/code>: Checks if a standard flag is set.<\/li>\n<li><code>hasArbitraryFlag(name)<\/code>: Checks if a custom flag exists.<\/li>\n<li><code>getArbitraryFlagValue(name)<\/code>: Gets the value of a custom flag.<\/li>\n<li><code>toBytes()<\/code>: Serializes the filter to <code>Uint8Array<\/code>.<\/li>\n<li><code>toString()<\/code>: Serializes the filter to a Base58Check encoded string (used when passing to <code>searchBlockchain<\/code>).<\/li>\n<\/ul>\n<\/li>\n<li><strong>Static Methods:<\/strong>\n<ul>\n<li><code>fromBytes(buffer)<\/code>: Deserializes from <code>Uint8Array<\/code>.<\/li>\n<li><code>fromNumber(number)<\/code>: Creates a filter with only standard flags from a bitmask.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<hr \/>\n<h2 id=\"6-event-handling\">6. Event Handling<\/h2>\n<p>UI dApps interact with the API primarily through events. Register listeners using the <code>add...Listener<\/code> methods on the <code>CVMContext<\/code> instance.<\/p>\n<p><strong>Key Listener Methods for Blockchain Explorer API:<\/strong><\/p>\n<ul>\n<li><code>addNewSearchResultsListener(callback, appID)<\/code>: Handles responses from <code>searchBlockchain<\/code>, <code>getRecentBlocks<\/code>, <code>getRecentTransactions<\/code>, <code>getDomainHistory<\/code>, <code>getMarketData<\/code> (for balances). The callback receives an <code>event<\/code> object where <code>event.results<\/code> is a <code>CSearchResults<\/code> instance. Match <code>event.reqID<\/code> to your original request ID.<\/li>\n<li><code>addNewBlockDetailsListener(callback, appID)<\/code>: Handles responses from <code>getBlockDetails<\/code>. The callback receives <code>event<\/code> where <code>event.data<\/code> is a <code>CBlockDesc<\/code> instance.<\/li>\n<li><code>addNewTransactionDetailsListener(callback, appID)<\/code>: Handles responses from <code>getTransactionDetails<\/code>. The callback receives <code>event<\/code> where <code>event.data<\/code> is a <code>CTransactionDesc<\/code> instance.<\/li>\n<li><code>addNewDomainDetailsListener(callback, appID)<\/code>: Handles responses from <code>getDomainDetails<\/code>. The callback receives <code>event<\/code> where <code>event.data<\/code> is a <code>CDomainDesc<\/code> instance.<\/li>\n<li><code>addBlockchainStatsListener(callback, appID)<\/code>: Handles responses from various statistics methods like <code>getBlockchainStatus<\/code>, <code>getNetworkUtilization24h<\/code>, <code>getHeight<\/code>, <code>getUSDTPrice<\/code>, <code>getLiveness<\/code>, etc. The <code>event<\/code> object contains <code>event.type<\/code> (a string identifying the statistic, e.g., &#8216;blockchainHeight&#8217;) and <code>event.data<\/code> (containing the actual statistic value(s)).<\/li>\n<li><code>addNewGridScriptResultListener(callback, appID)<\/code>: A more general listener for GridScript results. Blockchain Explorer API responses might also trigger this, often containing BER-encoded data within the <code>event.data<\/code> structure that needs further parsing based on the original request context (<code>event.reqID<\/code>).<\/li>\n<\/ul>\n<p><strong>Important:<\/strong> Always remember to unregister listeners when they are no longer needed (e.g., when a UI component is destroyed) to prevent memory leaks, using <code>CVMContext.unregisterEventListenerByID(listenerId)<\/code>.<\/p>\n<hr \/>\n<h2 id=\"7-conclusion-and-best-practices\">7. Conclusion and Best Practices<\/h2>\n<ul>\n<li><strong>Use Async Methods:<\/strong> Prefer the <code>A<\/code> suffix methods (<code>getBlockDetailsA<\/code>, etc.) with <code>async\/await<\/code> for cleaner code.<\/li>\n<li><strong>Handle Process Context:<\/strong> Always pass the UI dApp&#8217;s instance (<code>this<\/code>) as the <code>processHandle<\/code> parameter where required.<\/li>\n<li><strong>Manage Request IDs:<\/strong> When using non-async methods, store the returned <code>reqID<\/code> and use it to correlate responses in your event listeners.<\/li>\n<li><strong>Check Event Data:<\/strong> In listeners, always check the type of the received data (e.g., <code>event.results instanceof CSearchResults<\/code>) before processing.<\/li>\n<li><strong>Unregister Listeners:<\/strong> Clean up listeners using <code>unregisterEventListenerByID<\/code> when they are no longer needed.<\/li>\n<li><strong>Error Handling:<\/strong> Wrap API calls in <code>try...catch<\/code> blocks, especially when using <code>await<\/code>. Implement robust error handling in event listeners.<\/li>\n<li><strong>Use Data Object Getters:<\/strong> Access data using the provided getters (e.g., <code>block.height<\/code>, <code>tx.valueTxt<\/code>) on the <code>CBlockDesc<\/code>, <code>CTransactionDesc<\/code>, etc., objects.<\/li>\n<li><strong>Leverage Caching:<\/strong> Be aware that <code>CVMContext<\/code> performs some internal caching (e.g., for <code>getHeight<\/code>). Use the <code>allowCache<\/code> parameter in async methods if you need to force a refresh.<\/li>\n<li><strong>Consult <code>CTools<\/code>:<\/strong> Utilize methods from <code>CTools.getInstance()<\/code> for common formatting tasks (e.g., <code>formatGNCValue<\/code>, <code>formatByteSize<\/code>, <code>transactionStatusText<\/code>).<\/li>\n<\/ul>\n<p>This API provides a powerful interface for interacting with the GRIDNET blockchain. By understanding its architecture and utilizing the provided methods and data objects correctly, developers can build sophisticated and informative blockchain exploration tools within the GRIDNET OS ecosystem.<\/p>\n<h2>Appendix A<\/h2>\n<hr \/>\n<h2 id=\"-csearchfilter-class-documentation\"><code>CSearchFilter<\/code> Class Documentation<\/h2>\n<h3 id=\"1-overview\">1. Overview<\/h3>\n<p>The <code>CSearchFilter<\/code> class is a fundamental component within the GRIDNET OS ecosystem for specifying criteria when searching the blockchain via the <code>CVMContext<\/code> Blockchain Explorer API. It provides a flexible and efficient mechanism to filter search results based on both predefined standard entity types (Blocks, Transactions, Domains, Addresses) and arbitrary, developer-defined custom flags.<\/p>\n<p>This class is designed for use within UI dApps to construct search parameters that are then serialized and sent to GRIDNET Core nodes for processing. Its support for both standard and dynamic flags allows for powerful and extensible search capabilities across the decentralized network.<\/p>\n<p><strong>Rationale:<\/strong> Instead of using complex query strings or numerous parameters, <code>CSearchFilter<\/code> uses a combination of a bitmask for standard types and a map for custom key-value filters. This structure is easily serializable into a compact format suitable for network transmission within the GRIDNET Meta Data Protocol.<\/p>\n<h3 id=\"2-key-features\">2. Key Features<\/h3>\n<ul>\n<li><strong>Standard Flags:<\/strong> Supports predefined flags for common blockchain entities (Transactions, Domains, Addresses, Blocks) using efficient bitwise operations.<\/li>\n<li><strong>Arbitrary Flags:<\/strong> Allows developers to define and use custom flags (key-value pairs) for more granular or application-specific filtering processed by the backend.<\/li>\n<li><strong>Serialization:<\/strong> Provides methods to serialize the filter state into:\n<ul>\n<li>A compact byte array (<code>toBytes<\/code>).<\/li>\n<li>A Base58Check encoded string (<code>toString<\/code>), suitable for embedding in GridScript commands used by the Blockchain Explorer API.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Deserialization:<\/strong> Allows recreating a <code>CSearchFilter<\/code> instance from:\n<ul>\n<li>A byte array (<code>fromBytes<\/code>).<\/li>\n<li>A number representing <em>only<\/em> standard flags (<code>fromNumber<\/code>).<\/li>\n<\/ul>\n<\/li>\n<li><strong>Flexibility:<\/strong> Combines the ease of use of standard flags with the extensibility of arbitrary flags.<\/li>\n<li><strong>Readability:<\/strong> Offers a method (<code>getSearchDomainDescription<\/code>) to get a human-readable summary of the active filters.<\/li>\n<\/ul>\n<h3 id=\"3-class-definition\">3. Class Definition<\/h3>\n<p><code class=\"lang-javascript\"><span class=\"hljs-keyword\">import<\/span> { CTools } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'\/lib\/tools.js'<\/span>;<\/code><\/p>\n<p><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CSearchFilter<\/span> <\/span>{<br \/>\n<span class=\"hljs-comment\">\/\/ Static properties (StandardFlags, ALL_STANDARD, etc.)<\/span><br \/>\n<span class=\"hljs-comment\">\/\/ Constructor<\/span><br \/>\n<span class=\"hljs-comment\">\/\/ Methods (setStandardFlags, setArbitraryFlag, has&#8230;, toBytes, toString, etc.)<\/span><br \/>\n<span class=\"hljs-comment\">\/\/ Static methods (fromBytes, fromNumber)<\/span><br \/>\n<span class=\"hljs-comment\">\/\/ Private validation methods<\/span><br \/>\n}<\/p>\n<h3 id=\"4-static-properties\">4. Static Properties<\/h3>\n<h4 id=\"-standardflags-\"><code>StandardFlags<\/code><\/h4>\n<p>An object containing predefined <code>BigInt<\/code> values representing standard blockchain entity types. These flags can be combined using the bitwise OR operator (<code>|<\/code>).<\/p>\n<ul>\n<li><code>TRANSACTIONS<\/code>: <code>1n &lt;&lt; 0n<\/code> (Value: <code>1n<\/code>) &#8211; Filter for transactions.<\/li>\n<li><code>DOMAINS<\/code>: <code>1n &lt;&lt; 1n<\/code> (Value: <code>2n<\/code>) &#8211; Filter for domains (accounts).<\/li>\n<li><code>ADDRESSES<\/code>: <code>1n &lt;&lt; 2n<\/code> (Value: <code>4n<\/code>) &#8211; Filter for addresses (often used interchangeably with domains).<\/li>\n<li><code>BLOCKS<\/code>: <code>1n &lt;&lt; 3n<\/code> (Value: <code>8n<\/code>) &#8211; Filter for blocks.<\/li>\n<\/ul>\n<h4 id=\"-no_standard-\"><code>NO_STANDARD<\/code><\/h4>\n<p>A <code>BigInt<\/code> constant representing no standard flags set (Value: <code>0n<\/code>). Useful for starting with a clean slate before adding specific standard flags.<\/p>\n<h4 id=\"-all_standard-\"><code>ALL_STANDARD<\/code><\/h4>\n<p>A <code>BigInt<\/code> constant representing all standard flags combined (Value: <code>15n<\/code>). This is <em>not<\/em> the default constructor value anymore (default is <code>NO_STANDARD<\/code>).<\/p>\n<h4 id=\"constants\">Constants<\/h4>\n<ul>\n<li><code>MAX_ARBITRARY_FLAGS<\/code>: Maximum number of arbitrary flags allowed (currently 1,000,000 &#8211; a high theoretical limit).<\/li>\n<li><code>MAX_FLAG_NAME_LENGTH<\/code>: Maximum length for an arbitrary flag name (256 characters).<\/li>\n<li><code>MAX_FLAG_VALUE_LENGTH<\/code>: Maximum length for an arbitrary flag value (1024 characters).<\/li>\n<\/ul>\n<h3 id=\"5-constructor\">5. Constructor<\/h3>\n<h4 id=\"-constructor-flags-csearchfilter-no_standard-\"><code>constructor(flags = CSearchFilter.NO_STANDARD)<\/code><\/h4>\n<p>Creates a new <code>CSearchFilter<\/code> instance.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>flags<\/code> {<code>bigint<\/code>} [Optional, Default: <code>CSearchFilter.NO_STANDARD<\/code>] &#8211; An initial bitmask of standard flags to set. Only bits corresponding to defined <code>StandardFlags<\/code> are considered.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Throws:<\/strong>\n<ul>\n<li><code>TypeError<\/code>: If <code>flags<\/code> is not a <code>BigInt<\/code>.<\/li>\n<li><code>Error<\/code>: If <code>flags<\/code> contains bits not defined in <code>StandardFlags<\/code>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3 id=\"6-methods\">6. Methods<\/h3>\n<h4 id=\"-setstandardflags-flags-\"><code>setStandardFlags(...flags)<\/code><\/h4>\n<p>Sets one or more standard flags on the filter instance. This method uses bitwise OR, so it adds flags without removing existing ones unless you start with <code>NO_STANDARD<\/code>.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>...flags<\/code> {(keyof typeof CSearchFilter.StandardFlags | bigint)} &#8211; A variable number of arguments, each being either:\n<ul>\n<li>A string matching a key in <code>CSearchFilter.StandardFlags<\/code> (e.g., <code>\"TRANSACTIONS\"<\/code>).<\/li>\n<li>A <code>BigInt<\/code> value corresponding to a standard flag (e.g., <code>CSearchFilter.StandardFlags.BLOCKS<\/code>).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>CSearchFilter<\/code>} &#8211; The <code>CSearchFilter<\/code> instance for method chaining.<\/li>\n<li><strong>Throws:<\/strong>\n<ul>\n<li><code>Error<\/code>: If an invalid flag name or value is provided.<\/li>\n<li><code>TypeError<\/code>: If an argument is not a string or BigInt.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Example:<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-built_in\">filter<\/span> = <span class=\"hljs-keyword\">new<\/span> CSearchFilter(); <span class=\"hljs-comment\">\/\/ Starts with NO_STANDARD<\/span><br \/>\n<span class=\"hljs-built_in\">filter<\/span>.setStandardFlags(<span class=\"hljs-string\">\"TRANSACTIONS\"<\/span>, CSearchFilter.StandardFlags.BLOCKS);<br \/>\n<span class=\"hljs-comment\">\/\/ filter now searches for Transactions OR Blocks<\/span><br \/>\n<\/code><\/li>\n<\/ul>\n<h4 id=\"-setarbitraryflag-flagname-value-\"><code>setArbitraryFlag(flagName, value = '')<\/code><\/h4>\n<p>Sets a custom, arbitrary flag with an associated value. Arbitrary flags are used for backend-specific filtering beyond the standard types. If the <code>value<\/code> is boolean <code>false<\/code>, the flag is removed.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>flagName<\/code> {<code>string<\/code>} &#8211; The name of the custom flag (case-sensitive). Must be non-empty and within length limits.<\/li>\n<li><code>value<\/code> {<code>string<\/code>|<code>number<\/code>|<code>bigint<\/code>|<code>boolean<\/code>|<code>ArrayBuffer<\/code>} [Optional, Default: <code>''<\/code>] &#8211; The value associated with the flag.\n<ul>\n<li>Booleans: <code>true<\/code> sets the flag with an empty string value, <code>false<\/code> removes the flag.<\/li>\n<li>Numbers\/BigInts: Converted to strings.<\/li>\n<li>ArrayBuffers: Decoded as UTF-8 strings.<\/li>\n<li>Strings: Used directly (must be within length limits).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>CSearchFilter<\/code>} &#8211; The <code>CSearchFilter<\/code> instance for method chaining.<\/li>\n<li><strong>Throws:<\/strong>\n<ul>\n<li><code>TypeError<\/code>: If <code>flagName<\/code> is not a string or <code>value<\/code> is an unsupported type.<\/li>\n<li><code>Error<\/code>: If <code>flagName<\/code> or <code>value<\/code> violates length constraints or if the maximum number of arbitrary flags is exceeded.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Example:<\/strong><br \/>\n<code class=\"lang-javascript\"><span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-built_in\">filter<\/span> = <span class=\"hljs-keyword\">new<\/span> CSearchFilter();<br \/>\n<span class=\"hljs-built_in\">filter<\/span>.setArbitraryFlag(<span class=\"hljs-string\">\"block_type\"<\/span>, <span class=\"hljs-string\">\"key\"<\/span>); <span class=\"hljs-comment\">\/\/ Search for key blocks<\/span><br \/>\n<span class=\"hljs-built_in\">filter<\/span>.setArbitraryFlag(<span class=\"hljs-string\">\"min_height\"<\/span>, <span class=\"hljs-number\">100000<\/span>); <span class=\"hljs-comment\">\/\/ Search blocks &gt;= height 100000<\/span><br \/>\n<span class=\"hljs-built_in\">filter<\/span>.setArbitraryFlag(<span class=\"hljs-string\">\"HAS_CODE\"<\/span>, <span class=\"hljs-keyword\">true<\/span>);      <span class=\"hljs-comment\">\/\/ Flag existence (value stored as '')<\/span><br \/>\n<span class=\"hljs-built_in\">filter<\/span>.setArbitraryFlag(<span class=\"hljs-string\">\"HAS_CODE\"<\/span>, <span class=\"hljs-keyword\">false<\/span>);     <span class=\"hljs-comment\">\/\/ Removes the \"HAS_CODE\" flag<\/span><br \/>\n<\/code><\/li>\n<\/ul>\n<h4 id=\"-setarbitraryflagboolean-flagname-value-\"><code>setArbitraryFlagBoolean(flagName, value)<\/code><\/h4>\n<p>A convenience method equivalent to <code>setArbitraryFlag(flagName, value)<\/code> specifically for boolean values. <code>true<\/code> sets the flag (with an empty string value), <code>false<\/code> removes it.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>flagName<\/code> {<code>string<\/code>} &#8211; The name of the custom flag.<\/li>\n<li><code>value<\/code> {<code>boolean<\/code>} &#8211; <code>true<\/code> to set the flag, <code>false<\/code> to remove it.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>CSearchFilter<\/code>} &#8211; The <code>CSearchFilter<\/code> instance for method chaining.<\/li>\n<\/ul>\n<h4 id=\"-getarbitraryflags-\"><code>getArbitraryFlags()<\/code><\/h4>\n<p>Returns an iterator over the arbitrary flags currently set in the filter.<\/p>\n<ul>\n<li><strong>Returns:<\/strong> {<code>IterableIterator&lt;[string, string]&gt;<\/code>} &#8211; An iterator yielding <code>[flagName, flagValue]<\/code> pairs.<\/li>\n<\/ul>\n<h4 id=\"-hasstandardflag-flag-\"><code>hasStandardFlag(flag)<\/code><\/h4>\n<p>Checks if a specific standard flag is currently set.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>flag<\/code> {<code>keyof typeof CSearchFilter.StandardFlags<\/code> | <code>bigint<\/code>} &#8211; The standard flag to check (by name or BigInt value).<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>boolean<\/code>} &#8211; <code>true<\/code> if the flag is set, <code>false<\/code> otherwise.<\/li>\n<li><strong>Throws:<\/strong>\n<ul>\n<li><code>Error<\/code>: If an invalid flag name or value is provided.<\/li>\n<li><code>TypeError<\/code>: If the argument is not a string or BigInt.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4 id=\"-hasarbitraryflag-flagname-\"><code>hasArbitraryFlag(flagName)<\/code><\/h4>\n<p>Checks if a specific arbitrary flag exists (regardless of its value).<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>flagName<\/code> {<code>string<\/code>} &#8211; The name of the arbitrary flag.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>boolean<\/code>} &#8211; <code>true<\/code> if the flag exists, <code>false<\/code> otherwise.<\/li>\n<\/ul>\n<h4 id=\"-getarbitraryflagvalue-flagname-\"><code>getArbitraryFlagValue(flagName)<\/code><\/h4>\n<p>Retrieves the string value associated with a specific arbitrary flag.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>flagName<\/code> {<code>string<\/code>} &#8211; The name of the arbitrary flag.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>string<\/code>} &#8211; The value of the flag, or an empty string (<code>''<\/code>) if the flag does not exist or was set with <code>true<\/code> or an empty string.<\/li>\n<\/ul>\n<h4 id=\"-getarbitraryflagcount-\"><code>getArbitraryFlagCount()<\/code><\/h4>\n<p>Returns the number of arbitrary flags currently set.<\/p>\n<ul>\n<li><strong>Returns:<\/strong> {<code>number<\/code>} &#8211; The count of arbitrary flags.<\/li>\n<\/ul>\n<h4 id=\"-getsearchdomaindescription-\"><code>getSearchDomainDescription()<\/code><\/h4>\n<p>Generates a human-readable string summarizing the currently active standard and arbitrary flags. Useful for logging or debugging.<\/p>\n<ul>\n<li><strong>Returns:<\/strong> {<code>string<\/code>} &#8211; A comma-separated description of the search domain (e.g., <code>\"TRANSACTIONS, BLOCKS, block_type=key\"<\/code>).<\/li>\n<\/ul>\n<h4 id=\"-tobytes-\"><code>toBytes()<\/code><\/h4>\n<p>Serializes the entire filter state (version, standard flags, arbitrary flags count, and all arbitrary flag name-value pairs) into a compact binary format.<\/p>\n<ul>\n<li><strong>Returns:<\/strong> {<code>Uint8Array<\/code>} &#8211; The byte array representing the serialized filter.<\/li>\n<li><strong>Format:<\/strong>\n<ul>\n<li><code>[1 byte]<\/code> Version (currently 1)<\/li>\n<li><code>[8 bytes]<\/code> Standard Flags (BigUint64, little-endian)<\/li>\n<li><code>[4 bytes]<\/code> Number of Arbitrary Flags (Uint32, little-endian)<\/li>\n<li><code>[variable]<\/code> Sequence of Arbitrary Flags:\n<ul>\n<li><code>[variable bytes]<\/code> Flag Name (UTF-8)<\/li>\n<li><code>[1 byte]<\/code> Null Terminator (<code>\\0<\/code>)<\/li>\n<li><code>[variable bytes]<\/code> Flag Value (UTF-8)<\/li>\n<li><code>[1 byte]<\/code> Null Terminator (<code>\\0<\/code>)<\/li>\n<li>&#8230; (repeated for each flag)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4 id=\"-tostring-\"><code>toString()<\/code><\/h4>\n<p>Serializes the filter using <code>toBytes()<\/code> and then encodes the resulting byte array using Base58Check encoding. <strong>This is the format expected by the <code>CVMContext.searchBlockchain<\/code> API method&#8217;s <code>flags<\/code> parameter.<\/strong><\/p>\n<ul>\n<li><strong>Returns:<\/strong> {<code>string<\/code>} &#8211; The Base58Check encoded string representation of the filter.<\/li>\n<li><strong>Dependencies:<\/strong> Relies on <code>CTools.getInstance().encodeBase58Check()<\/code>.<\/li>\n<\/ul>\n<h4 id=\"-static-frombytes-buffer-\"><code>static fromBytes(buffer)<\/code><\/h4>\n<p>Deserializes a <code>CSearchFilter<\/code> instance from a byte array previously created by <code>toBytes()<\/code>. This method restores both standard and arbitrary flags (including names and values).<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>buffer<\/code> {<code>Uint8Array<\/code>} &#8211; The byte array containing the serialized filter data.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>CSearchFilter<\/code>} &#8211; A new <code>CSearchFilter<\/code> instance.<\/li>\n<li><strong>Throws:<\/strong>\n<ul>\n<li><code>TypeError<\/code>: If <code>buffer<\/code> is not a <code>Uint8Array<\/code>.<\/li>\n<li><code>Error<\/code>: If the buffer is invalid, too short, contains an unsupported version, or exceeds limits.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h4 id=\"-static-fromnumber-number-\"><code>static fromNumber(number)<\/code><\/h4>\n<p>Creates a <code>CSearchFilter<\/code> instance setting <em>only<\/em> the standard flags based on a provided number (bitmask). Arbitrary flags are <em>not<\/em> preserved or set by this method.<\/p>\n<ul>\n<li><strong>Parameters:<\/strong>\n<ul>\n<li><code>number<\/code> {<code>bigint<\/code>|<code>number<\/code>} &#8211; A number or BigInt where bits correspond to standard flags.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Returns:<\/strong> {<code>CSearchFilter<\/code>} &#8211; A new <code>CSearchFilter<\/code> instance with only standard flags set.<\/li>\n<\/ul>\n<h3 id=\"7-custom-flag-convention\">7. Custom Flag Convention<\/h3>\n<p>As noted in the specification, while not enforced by the <code>CSearchFilter<\/code> class itself, a recommended convention for naming arbitrary flags when filtering based on object properties is:<\/p>\n<p><code>OBJECT_NAME||_||PROPERTY_NAME<\/code><\/p>\n<p>Where <code>||<\/code> denotes string concatenation.<\/p>\n<ul>\n<li><strong>Examples:<\/strong>\n<ul>\n<li><code>block_height<\/code>: To filter blocks based on the <code>height<\/code> property of <code>CBlockDesc<\/code>.<\/li>\n<li><code>transaction_sender<\/code>: To filter transactions based on the <code>sender<\/code> property of <code>CTransactionDesc<\/code>.<\/li>\n<li><code>block_keyHeight<\/code>: To filter based on the <code>keyHeight<\/code> property.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Adhering to this convention helps maintain consistency when interacting with backend implementations that might expect these specific flag names for property-based filtering.<\/p>\n<h3 id=\"8-usage-example-api-call-\">8. Usage Example (API Call)<\/h3>\n<pre>import { CSearchFilter } from '.\/searchFilter.js'; \/\/ Adjust path as needed\r\nimport { CVMContext } from '.\/VMContext.js';      \/\/ Adjust path as needed\r\nasync function performAdvancedSearch(query) {\r\n    const vmContext = CVMContext.getInstance();\r\n    const processHandle = window.magicButton; \/\/ Assuming magicButton is the process handle\r\n    \r\n    \/\/ Create a filter: search for Transactions OR Blocks, only key blocks\r\n    const filter = new CSearchFilter(CSearchFilter.NO_STANDARD); \/\/ Start empty\r\n    filter.setStandardFlags(\"TRANSACTIONS\", \"BLOCKS\"); \/\/ Add standard flags\r\n    filter.setArbitraryFlag(\"block_type\", \"key\"); \/\/ Add custom flag\r\n    \r\n    console.log(\"Search Domain:\", filter.getSearchDomainDescription());\r\n    \/\/ Output: Search Domain: TRANSACTIONS, BLOCKS, block_type=key\r\n    \r\n    \/\/ Serialize for API call using toString() -&gt; Base58Check(toBytes())\r\n    const filterString = filter.toString();\r\n    console.log(\"Serialized Filter for API:\", filterString);\r\n    \r\n    try {\r\n        \/\/ Use the async API method with the serialized filter string\r\n        const searchResults = await vmContext.searchBlockchainA(\r\n            query,\r\n            20, \/\/ size\r\n            1, \/\/ page\r\n            filterString, \/\/ Pass the Base58Check encoded filter string\r\n            undefined, \/\/ threadID (default)\r\n            processHandle\r\n        );\r\n        \r\n        console.log(`Found ${searchResults.getTotalResultCount()} results.`);\r\n        \/\/ ... process results ...\r\n        \r\n    } catch (error) {\r\n        console.error(\"Blockchain search failed:\", error);\r\n    }\r\n}\r\n\r\n\/\/ Example usage:\r\nperformAdvancedSearch(\"some_query_term\");\r\n<\/pre>\n<h3 id=\"9-best-practices-and-notes\">9. Best Practices and Notes<\/h3>\n<ul>\n<li><strong>Use Standard Flags First:<\/strong> Leverage the predefined <code>StandardFlags<\/code> for common entity types (Transactions, Blocks, Domains, Addresses) as they are optimized and universally understood.<\/li>\n<li><strong>Arbitrary Flags for Extension:<\/strong> Use arbitrary flags for backend-specific or advanced filtering not covered by standard flags. Follow the naming convention (<code>OBJECT_NAME||_||PROPERTY_NAME<\/code>) where applicable.<\/li>\n<li><strong>Serialization for API:<\/strong> Always use the <code>toString()<\/code> method to get the Base58Check encoded representation when passing the filter to <code>CVMContext.searchBlockchain<\/code> or <code>searchBlockchainA<\/code>.<\/li>\n<li><strong>Serialization for Storage:<\/strong> Use <code>toBytes()<\/code> if you need to store the filter&#8217;s binary representation locally or send it through other channels expecting raw bytes. Use <code>fromBytes<\/code> to restore it.<\/li>\n<li><strong><code>fromNumber<\/code> Limitations:<\/strong> Remember that <code>static fromNumber(flags)<\/code> only restores <em>standard<\/em> flags based on the provided bitmask. Arbitrary flags are lost in this conversion.<\/li>\n<li><strong>Immutability:<\/strong> Methods like <code>setStandardFlags<\/code> and <code>setArbitraryFlag<\/code> modify the instance in place and return <code>this<\/code> for chaining.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; 1. Introduction Welcome to the GRIDNET OS Blockchain Explorer API documentation. This API provides UI dApps running within the GRIDNET OS web-browser subsystem the ability to query and interact with the underlying decentralized blockchain state machine. It allows developers to build applications that can visualize, search, and analyze blockchain data, including blocks, transactions, domain [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":666661,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[125],"tags":[],"class_list":["post-666579","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-documentation"],"_links":{"self":[{"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/posts\/666579","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/comments?post=666579"}],"version-history":[{"count":27,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/posts\/666579\/revisions"}],"predecessor-version":[{"id":840113,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/posts\/666579\/revisions\/840113"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/media\/666661"}],"wp:attachment":[{"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/media?parent=666579"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/categories?post=666579"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gridnet.org\/wpp\/index.php\/wp-json\/wp\/v2\/tags?post=666579"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}