From 08513747081561df35f3675d4a26807bbd8aee9f Mon Sep 17 00:00:00 2001 From: "Bob (Clawdbot)" Date: Thu, 5 Mar 2026 17:57:58 +0100 Subject: [PATCH 1/5] docs: improve validators section - fix config field name, update version defaults, add missing API keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix genvm.manage_modules → genvm.start_manager to match actual config.yaml field - Update NODE_VERSION default from v0.4.0 to v0.5.1 (latest release) - Add COMPUT3KEY and IOINTELLIGENCE_API_KEY to .env example (mentioned in setup but missing from docker env) Co-Authored-By: Claude Opus 4.6 --- pages/validators/setup-guide.mdx | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/pages/validators/setup-guide.mdx b/pages/validators/setup-guide.mdx index a1288eb3..f5e5ec90 100644 --- a/pages/validators/setup-guide.mdx +++ b/pages/validators/setup-guide.mdx @@ -225,12 +225,12 @@ One full node can be shared between multiple validators. The optimal validator-t 3. Extract the node software ```sh copy mkdir -p ${version} - tar -xzvf `genlayer-node-linux-amd64-${version}.tar.gz` -C `./${version}` + tar -xzvf genlayer-node-linux-amd64-${version}.tar.gz -C ./${version} ``` 4. Change the directory ```sh copy - cd `./${version}` + cd ./${version} ``` 5. Run Genvm setup @@ -382,8 +382,7 @@ Any configuration value in `config.yaml` can be overridden using environment var |------------|---------------------| | `rollup.genlayerchainrpcurl` | `GENLAYERNODE_ROLLUP_GENLAYERCHAINRPCURL` | | `rollup.genlayerchainwebsocketurl` | `GENLAYERNODE_ROLLUP_GENLAYERCHAINWEBSOCKETURL` | -| `consensus.contractmainaddress` | `GENLAYERNODE_CONSENSUS_CONTRACTMAINADDRESS` | -| `consensus.contractdataaddress` | `GENLAYERNODE_CONSENSUS_CONTRACTDATAADDRESS` | +| `consensus.consensusaddress` | `GENLAYERNODE_CONSENSUS_CONSENSUSADDRESS` | | `consensus.genesis` | `GENLAYERNODE_CONSENSUS_GENESIS` | | `node.mode` | `GENLAYERNODE_NODE_MODE` | | `node.validatorWalletAddress` | `GENLAYERNODE_NODE_VALIDATORWALLETADDRESS` | @@ -394,8 +393,8 @@ Any configuration value in `config.yaml` can be overridden using environment var **Usage example:** ```sh copy -# Override the RPC port -export GENLAYERNODE_CONSENSUS_CONTRACTMAINADDRESS="0x..." +# Override the consensus address +export GENLAYERNODE_CONSENSUS_CONSENSUSADDRESS="0x..." # Set validator wallet address export GENLAYERNODE_NODE_VALIDATORWALLETADDRESS="0x..." @@ -520,14 +519,14 @@ Once you have configured everything, you are ready to start the node. ``` 3. (Optional) Run two services (modules) in background (this is a crucial step for running _Intelligent_ contracts). This can be done automatically or manually. - - To start them automatically in node configuration set `genvm.manage_modules` to `true` + - To start them automatically in node configuration set `genvm.start_manager` to `true` - To start them manually run ```bash copy ./third_party/genvm/bin/genvm-modules web & ./third_party/genvm/bin/genvm-modules llm & ``` - Note: If you are using the default configuration, `genvm.manage_modules` is + Note: If you are using the default configuration, `genvm.start_manager` is set to `true` by default, meaning the node will manage these modules automatically. @@ -649,7 +648,7 @@ WEBDRIVER_PORT=4444 # Node Service Configuration (optional - use node profile) # ============================================================================= # Docker image version -NODE_VERSION=v0.4.0 +NODE_VERSION=v0.5.1 # Keystore password (used to unlock the pre-imported wallet) NODE_PASSWORD=12345678 @@ -666,6 +665,8 @@ NODE_OPS_PORT=9153 # LLM API Key (required for GenVM LLM module) HEURISTKEY= +COMPUT3KEY= +IOINTELLIGENCE_API_KEY= ANTHROPICKEY= XAIKEY= GEMINIKEY= @@ -681,7 +682,7 @@ To ensure your node is correctly configured, you can run the following command: ```sh copy source .env && docker run --rm --env-file ./.env \ -v ${NODE_CONFIG_PATH:-./configs/node/config.yaml}:/app/configs/node/config.yaml \ - yeagerai/genlayer-node:${NODE_VERSION:-v0.4.0} \ + yeagerai/genlayer-node:${NODE_VERSION:-v0.5.1} \ ./bin/genlayernode doctor ``` From 9fccf031300e78492d3e56eaaefd48a7cbad8cd4 Mon Sep 17 00:00:00 2001 From: "Bob (Clawdbot)" Date: Thu, 5 Mar 2026 17:59:41 +0100 Subject: [PATCH 2/5] docs: improve intelligent contracts features - fix outdated VecDB import, fix mermaid diagram - vector-storage: Remove wrong import path (backend.node.genvm.std.vector_store), clarify VecDB comes from genlayer package - special-methods: Add missing label to fallback_defined node in mermaid diagram Co-Authored-By: Claude Opus 4.6 --- .../intelligent-contracts/features/special-methods.mdx | 2 +- .../intelligent-contracts/features/vector-storage.mdx | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/pages/developers/intelligent-contracts/features/special-methods.mdx b/pages/developers/intelligent-contracts/features/special-methods.mdx index 03b53014..1e65af20 100644 --- a/pages/developers/intelligent-contracts/features/special-methods.mdx +++ b/pages/developers/intelligent-contracts/features/special-methods.mdx @@ -42,7 +42,7 @@ graph TD fallback_is_payable -->|yes| fallback1{{call __handle_undefined_method__}} fallback_is_payable -->|no| error1{{error}} - has_value -->|no| fallback_defined + has_value -->|no| fallback_defined[is __handle_undefined_method__ defined?] fallback_defined -->|yes| fallback2{{call __handle_undefined_method__}} fallback_defined -->|no| error2{{error}} ``` diff --git a/pages/developers/intelligent-contracts/features/vector-storage.mdx b/pages/developers/intelligent-contracts/features/vector-storage.mdx index 5c412c83..eb2df097 100644 --- a/pages/developers/intelligent-contracts/features/vector-storage.mdx +++ b/pages/developers/intelligent-contracts/features/vector-storage.mdx @@ -19,15 +19,11 @@ The Vector Store provides standard CRUD (Create, Read, Update, Delete) operation ## How to Use Vector Store in Your Contracts To use the Vector Store in your Intelligent Contracts, you will interact with its methods to add and retrieve text data, calculate similarities, and manage vector storage. Below are the details of how to use this feature. -#### Importing Vector Store -First, import the VectorStore class from the standard library in your contract: - -```python -from backend.node.genvm.std.vector_store import VectorStore -``` +#### Using VecDB in Your Contract +The `VecDB` type is available through the `genlayer` package. Import it with `from genlayer import *` along with other GenLayer types. #### Creating a Contract with Vector Store -Here’s an example of a contract using the Vector Store for indexing and searching text logs: +Here’s an example of a contract using `VecDB` for indexing and searching text logs: ```python # { From 4049085c118ea7508a73cacae6b1fe3107137a54 Mon Sep 17 00:00:00 2001 From: "Bob (Clawdbot)" Date: Thu, 5 Mar 2026 18:02:25 +0100 Subject: [PATCH 3/5] docs: improve API references - fix Python syntax, add missing params, add Direct Mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - genlayer-py: Fix colon-instead-of-equals syntax error in read_contract example - genlayer-py: Add missing state_status param to read_contract, full_transaction to wait_for_transaction_receipt - genlayer-py: Add studionet and testnet_asimov chain imports - genlayer-test: Add Direct Mode section (fast in-memory testing without Docker) - genlayer-test: Fix mock LLM key names (response → nondet_exec_prompt) to match SDK Co-Authored-By: Claude Opus 4.6 --- pages/api-references/genlayer-py.mdx | 18 +++-- pages/api-references/genlayer-test.mdx | 94 ++++++++++++++++++++++++-- 2 files changed, 102 insertions(+), 10 deletions(-) diff --git a/pages/api-references/genlayer-py.mdx b/pages/api-references/genlayer-py.mdx index e1e94921..ca17857e 100644 --- a/pages/api-references/genlayer-py.mdx +++ b/pages/api-references/genlayer-py.mdx @@ -48,12 +48,14 @@ Waits for a transaction receipt. receipt = client.wait_for_transaction_receipt( transaction_hash=transaction_hash, status='FINALIZED', # or 'ACCEPTED' + full_transaction=False, # Optional: False for simplified receipt, True for complete ) ``` **Parameters:** - `transaction_hash`: The transaction hash - `status`: The desired transaction status ('FINALIZED' or 'ACCEPTED') +- `full_transaction`: (Optional) `False` (default) returns a simplified receipt with binary data removed; `True` returns the complete receipt with all fields **Returns:** Transaction receipt object @@ -65,8 +67,9 @@ Reads data from a deployed contract. ```python result = client.read_contract( address=contract_address, - function_name: 'get_complete_storage', - args: [], + function_name='get_complete_storage', + args=[], + state_status='accepted', # Optional: 'accepted' or 'finalized' ) ``` @@ -75,6 +78,7 @@ result = client.read_contract( - `address`: The contract address - `function_name`: The name of the function to call - `args`: An array of arguments for the function call +- `state_status`: (Optional) The state to query against (`'accepted'` or `'finalized'`) **Returns:** The result of the contract function call
@@ -132,11 +136,15 @@ account_with_key = create_account('0x1234...') # Replace with actual private key ## Chain Information -### localnet +### Available Chains -Provides configuration for the local GenLayer Studio chain. ```python -from genlayer_py.chains import localnet +from genlayer_py.chains import localnet, studionet, testnet_asimov ``` + +- **localnet**: Local development network (GenLayer Studio) +- **studionet**: Hosted development environment +- **testnet_asimov**: Public test network + **Usage:** Used when creating a client to specify the chain diff --git a/pages/api-references/genlayer-test.mdx b/pages/api-references/genlayer-test.mdx index e4fad593..6aa52bd6 100644 --- a/pages/api-references/genlayer-test.mdx +++ b/pages/api-references/genlayer-test.mdx @@ -10,6 +10,88 @@ For comprehensive test examples and implementation patterns, see our [Test Suite pip install genlayer-test ``` +## Two Testing Modes + +The testing suite provides two execution modes: + +| | Direct Mode | Studio Mode | +|---|---|---| +| **How it works** | Runs contract Python code directly in-memory | Deploys to GenLayer Studio, interacts via RPC | +| **Speed** | ~milliseconds per test | ~minutes per test | +| **Prerequisites** | Python >= 3.12 | Python >= 3.12 + GenLayer Studio (Docker) | +| **Best for** | Unit tests, rapid development, CI/CD | Integration tests, consensus validation, testnet | + +**Start with Direct Mode** — it's faster, simpler, and doesn't require Docker. Use Studio Mode when you need full network behavior or multi-validator consensus. + +## Direct Mode + +Run contracts directly in Python — no simulator, no Docker, no network. Tests execute in milliseconds. + +### Quick Start + +```python +def test_storage(direct_vm, direct_deploy): + # Deploy contract in-memory + storage = direct_deploy("contracts/Storage.py", "initial") + + # Read state directly + assert storage.get_storage() == "initial" + + # Write state directly + storage.update_storage("updated") + assert storage.get_storage() == "updated" +``` + +Run with pytest: + +```bash +pytest tests/ -v +``` + +### Direct Mode Fixtures + +| Fixture | Description | +|---------|-------------| +| `direct_vm` | VM context with cheatcodes | +| `direct_deploy` | Deploy contracts directly | +| `direct_alice`, `direct_bob`, `direct_charlie` | Test addresses | +| `direct_owner` | Default sender address | +| `direct_accounts` | List of 10 test addresses | + +### Cheatcodes + +```python +# Change sender +direct_vm.sender = alice + +# Prank (temporary sender change) +with direct_vm.prank(bob): + contract.method() # Called as bob + +# Snapshots (captures full state: storage, mocks, sender, validators) +snap_id = direct_vm.snapshot() +contract.modify_state() +direct_vm.revert(snap_id) # Full state restored + +# Expect revert +with direct_vm.expect_revert("Insufficient balance"): + contract.transfer(bob, 1000000) + +# Mock web/LLM (regex pattern matching) +direct_vm.mock_web(r"api\.example\.com", {"status": 200, "body": "{}"}) +direct_vm.mock_llm(r"analyze.*", "positive sentiment") + +# Test validator consensus logic +contract.update_price() # Runs leader_fn, captures validator +direct_vm.clear_mocks() # Swap mocks for validator +direct_vm.mock_llm(r".*", "different result") +assert direct_vm.run_validator() is False # Validator disagrees +``` + +## Studio Mode + +The rest of this document covers Studio Mode — deploying contracts to a running GenLayer Studio instance and interacting via RPC. + ## Configuration The GenLayer Testing Suite can be configured using an optional `gltest.config.yaml` file in your project root. While not required, this file helps manage network configurations, contract paths, and environment settings. @@ -493,7 +575,7 @@ The Mock LLM system allows you to simulate Large Language Model responses in Gen ```python mock_response = { - "response": {}, # Optional: mocks gl.nondet.exec_prompt + "nondet_exec_prompt": {}, # Optional: mocks gl.nondet.exec_prompt "eq_principle_prompt_comparative": {}, # Optional: mocks gl.eq_principle.prompt_comparative "eq_principle_prompt_non_comparative": {} # Optional: mocks gl.eq_principle.prompt_non_comparative } @@ -503,9 +585,11 @@ setup_validators(mock_response) ### Method Mappings -- "response" -> gl.nondet.exec_prompt -- "eq_principle_prompt_comparative" -> gl.eq_principle.prompt_comparative -- "eq_principle_prompt_non_comparative" -> gl.eq_principle.prompt_non_comparative +| Mock Key | GenLayer Method | +|----------|----------------| +| `"nondet_exec_prompt"` | `gl.nondet.exec_prompt` | +| `"eq_principle_prompt_comparative"` | `gl.eq_principle.prompt_comparative` | +| `"eq_principle_prompt_non_comparative"` | `gl.eq_principle.prompt_non_comparative` | ### How It Works @@ -534,7 +618,7 @@ from gltest import get_contract_factory def test_with_mocked_llm(setup_validators): mock_response = { - "response": { + "nondet_exec_prompt": { "What is the weather?": "It's sunny today", "Calculate 2+2": "4" }, From 7aab5c8031b9193f3b078d8a6dc39155515ee5cb Mon Sep 17 00:00:00 2001 From: "Bob (Clawdbot)" Date: Thu, 5 Mar 2026 18:05:32 +0100 Subject: [PATCH 4/5] docs: update all examples to use current GenLayer API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update wizard-of-coin: gl.exec_prompt → gl.nondet.exec_prompt, gl.eq_principle_strict_eq → gl.eq_principle.prompt_comparative (matches source) - Update prediction: gl.get_webpage → gl.nondet.web.render, gl.exec_prompt → gl.nondet.exec_prompt, gl.eq_principle_strict_eq → gl.eq_principle.strict_eq - Update llm-hello-world: gl.exec_prompt → gl.nondet.exec_prompt, gl.eq_principle_strict_eq → gl.eq_principle.strict_eq - Update llm-hello-world-non-comparative: gl.eq_principle_prompt_non_comparative → gl.eq_principle.prompt_non_comparative - Update fetch-web-content, fetch-github-profile, github-profile-projects, github-profile-summary: same API updates - Update user-storage: contract_runner.from_address → gl.message.sender_address - Fix GitHub links to point to genlayer-testing-suite repo Co-Authored-By: Claude Opus 4.6 --- .../examples/fetch-github-profile.mdx | 10 +-- .../examples/fetch-web-content.mdx | 18 ++-- .../examples/github-profile-projects.mdx | 8 +- .../examples/github-profile-summary.mdx | 8 +- .../llm-hello-world-non-comparative.mdx | 6 +- .../examples/llm-hello-world.mdx | 10 +-- .../examples/prediction.mdx | 90 ++++++++++--------- .../examples/user-storage.mdx | 4 +- .../examples/wizard-of-coin.mdx | 25 +++--- 9 files changed, 92 insertions(+), 87 deletions(-) diff --git a/pages/developers/intelligent-contracts/examples/fetch-github-profile.mdx b/pages/developers/intelligent-contracts/examples/fetch-github-profile.mdx index 126cc8a1..26382e2e 100644 --- a/pages/developers/intelligent-contracts/examples/fetch-github-profile.mdx +++ b/pages/developers/intelligent-contracts/examples/fetch-github-profile.mdx @@ -20,9 +20,9 @@ class FetchGitHubProfile(gl.Contract): github_profile_url = "https://github.com/"+github_handle def fetch_github_profile_page_content() -> str: - return gl.get_webpage(github_profile_url, mode="text") + return gl.nondet.web.render(github_profile_url, mode="text") - self.github_profile = gl.eq_principle_strict_eq(fetch_github_profile_page_content) + self.github_profile = gl.eq_principle.strict_eq(fetch_github_profile_page_content) @gl.public.view def show_github_profile(self) -> str: @@ -35,14 +35,14 @@ class FetchGitHubProfile(gl.Contract): - **Write Method**: - `fetch_github_profile(github_handle)` takes a GitHub username and retrieves their profile content. - Constructs the profile URL using the provided handle. - - Uses `gl.eq_principle_strict_eq()` to ensure all nodes agree on the same profile content. + - Uses `gl.eq_principle.strict_eq()` to ensure all nodes agree on the same profile content. - **Read Method**: - `show_github_profile()` returns the stored profile content. ## Key Components -1. **GitHub Integration**: The contract uses `gl.get_webpage()` to fetch content from GitHub profiles. -2. **Deterministic Execution**: `gl.eq_principle_strict_eq()` ensures that all nodes in the network arrive at the same exact content. +1. **GitHub Integration**: The contract uses `gl.nondet.web.render()` to fetch content from GitHub profiles. +2. **Deterministic Execution**: `gl.eq_principle.strict_eq()` ensures that all nodes in the network arrive at the same exact content. 3. **State Management**: The contract maintains a single string state variable that stores the profile content. ## Deploying the Contract diff --git a/pages/developers/intelligent-contracts/examples/fetch-web-content.mdx b/pages/developers/intelligent-contracts/examples/fetch-web-content.mdx index 9f28cd50..2d90bb3c 100644 --- a/pages/developers/intelligent-contracts/examples/fetch-web-content.mdx +++ b/pages/developers/intelligent-contracts/examples/fetch-web-content.mdx @@ -19,9 +19,9 @@ class FetchWebContent(gl.Contract): def fetch_web_content(self) -> typing.Any: def fetch_web_url_content() -> str: - return gl.get_webpage("https://example.com/", mode="text") + return gl.nondet.web.render("https://example.com/", mode="text") - self.content = gl.eq_principle_strict_eq(fetch_web_url_content) + self.content = gl.eq_principle.strict_eq(fetch_web_url_content) @gl.public.view def show_content(self) -> str: @@ -33,15 +33,15 @@ class FetchWebContent(gl.Contract): - **Initialization**: The `FetchWebContent` class initializes with an empty string in the `content` variable. - **Write Method**: - `fetch_web_content()` retrieves content from a web page and stores it. - - It contains an inner function `fetch_web_url_content()` that uses `gl.get_webpage()` to fetch content. - - Uses `gl.eq_principle_strict_eq()` to ensure all nodes agree on the same content. + - It contains an inner function `fetch_web_url_content()` that uses `gl.nondet.web.render()` to fetch content. + - Uses `gl.eq_principle.strict_eq()` to ensure all nodes agree on the same content. - **Read Method**: - `show_content()` returns the stored web content. ## Key Components -1. **Web Integration**: The contract uses `gl.get_webpage()` to fetch content from web URLs. -2. **Deterministic Execution**: `gl.eq_principle_strict_eq()` ensures that all nodes in the network arrive at the same exact content. +1. **Web Integration**: The contract uses `gl.nondet.web.render()` to fetch content from web URLs. +2. **Deterministic Execution**: `gl.eq_principle.strict_eq()` ensures that all nodes in the network arrive at the same exact content. 3. **State Management**: The contract maintains a single string state variable that stores the web content. ## Deploying the Contract @@ -101,7 +101,7 @@ You can monitor the contract's behavior through transaction logs, which will sho ## HTML Mode for Web Content -The `gl.get_webpage()` function supports different modes for retrieving web content. While `mode="text"` returns the plain text content, `mode="html"` allows you to retrieve the complete HTML `` of the webpage. +The `gl.nondet.web.render()` function supports different modes for retrieving web content. While `mode="text"` returns the plain text content, `mode="html"` allows you to retrieve the complete HTML `` of the webpage. Here's an example of using HTML mode: @@ -115,9 +115,9 @@ class FetchHTMLContent(gl.Contract): @gl.public.write def fetch_html_content(self) -> typing.Any: def fetch_web_url_html() -> str: - return gl.get_webpage("https://example.com/", mode="html") + return gl.nondet.web.render("https://example.com/", mode="html") - self.html_content = gl.eq_principle_strict_eq(fetch_web_url_html) + self.html_content = gl.eq_principle.strict_eq(fetch_web_url_html) @gl.public.view def show_html_content(self) -> str: diff --git a/pages/developers/intelligent-contracts/examples/github-profile-projects.mdx b/pages/developers/intelligent-contracts/examples/github-profile-projects.mdx index 00fc79ca..156986b6 100644 --- a/pages/developers/intelligent-contracts/examples/github-profile-projects.mdx +++ b/pages/developers/intelligent-contracts/examples/github-profile-projects.mdx @@ -20,7 +20,7 @@ class GitHubProfilesRepositories(gl.Contract): github_profile_url = "https://github.com/"+github_handle def fetch_github_profile_repositories() -> int: - profile_web_page = gl.get_webpage(github_profile_url, mode="text") + profile_web_page = gl.nondet.web.render(github_profile_url, mode="text") # Regular expression to find the number between "Repositories" and "Projects" pattern = r"Repositories\s+(\d+)\s+Projects" @@ -33,7 +33,7 @@ class GitHubProfilesRepositories(gl.Contract): else: return 0 - repositories = gl.eq_principle_strict_eq(fetch_github_profile_repositories) + repositories = gl.eq_principle.strict_eq(fetch_github_profile_repositories) if repositories > 25: self.github_profiles.append(github_handle) @@ -55,9 +55,9 @@ class GitHubProfilesRepositories(gl.Contract): ## Key Components -1. **GitHub Integration**: Uses `gl.get_webpage()` to fetch profile content. +1. **GitHub Integration**: Uses `gl.nondet.web.render()` to fetch profile content. 2. **Pattern Matching**: Employs regular expressions to extract repository counts. -3. **Deterministic Execution**: Uses `gl.eq_principle_strict_eq()` to ensure network consensus. +3. **Deterministic Execution**: Uses `gl.eq_principle.strict_eq()` to ensure network consensus. 4. **Conditional Storage**: Only stores profiles meeting specific criteria. ## Deploying the Contract diff --git a/pages/developers/intelligent-contracts/examples/github-profile-summary.mdx b/pages/developers/intelligent-contracts/examples/github-profile-summary.mdx index de0606b4..bf4aca09 100644 --- a/pages/developers/intelligent-contracts/examples/github-profile-summary.mdx +++ b/pages/developers/intelligent-contracts/examples/github-profile-summary.mdx @@ -25,9 +25,9 @@ class GitHubProfilesSummaries(gl.Contract): github_profile_url = "https://github.com/"+github_handle def fetch_github_profile_summaries() -> str: - return gl.get_webpage(github_profile_url, mode="text") + return gl.nondet.web.render(github_profile_url, mode="text") - profile_content = gl.eq_principle_strict_eq(fetch_github_profile_summaries) + profile_content = gl.eq_principle.strict_eq(fetch_github_profile_summaries) task = """Given the web page content of a github profile in HTML format, generate a comprehensive summary of the profile mentioning the key meta attributes and the GitHub contribution most important metrics""" @@ -35,7 +35,7 @@ summary of the profile mentioning the key meta attributes and the GitHub contrib criteria = """The summary provided should include different metrics and a summary of a GitHub profile""" profile_summary = ( - gl.eq_principle_prompt_non_comparative( + gl.eq_principle.prompt_non_comparative( lambda: profile_content, task=task, criteria=criteria, @@ -61,7 +61,7 @@ summary of the profile mentioning the key meta attributes and the GitHub contrib ## Key Components 1. **Data Storage**: Uses `TreeMap` for efficient key-value storage of profile summaries. -2. **Web Fetching**: Uses `gl.get_webpage()` with strict equivalence for deterministic content retrieval. +2. **Web Fetching**: Uses `gl.nondet.web.render()` with strict equivalence for deterministic content retrieval. 3. **AI Analysis**: Uses non-comparative equivalence for generating profile summaries. 4. **Duplicate Prevention**: Includes checks to prevent regenerating existing summaries. diff --git a/pages/developers/intelligent-contracts/examples/llm-hello-world-non-comparative.mdx b/pages/developers/intelligent-contracts/examples/llm-hello-world-non-comparative.mdx index e33f5658..0335bb1a 100644 --- a/pages/developers/intelligent-contracts/examples/llm-hello-world-non-comparative.mdx +++ b/pages/developers/intelligent-contracts/examples/llm-hello-world-non-comparative.mdx @@ -17,7 +17,7 @@ class LlmHelloWorldNonComparative(gl.Contract): @gl.public.write def set_message(self) -> typing.Any: - self.message = gl.eq_principle_prompt_non_comparative( + self.message = gl.eq_principle.prompt_non_comparative( lambda: "There is no context, I just want you to answer with truthy value in python (for example: 'yes', 'True', 1)", task="Answer with truthy value in python (for example: 'yes', 'True', 1)", criteria="Answer should be a truthy value in python" @@ -33,7 +33,7 @@ class LlmHelloWorldNonComparative(gl.Contract): - **Initialization**: The `LlmHelloWorldNonComparative` class initializes with an empty string in the `message` variable. - **Write Method**: - `set_message()` uses AI functionality to generate and store a message. - - Uses `gl.eq_principle_prompt_non_comparative()` with three parameters: + - Uses `gl.eq_principle.prompt_non_comparative()` with three parameters: - A lambda function providing the prompt - A task description - Validation criteria for the response @@ -43,7 +43,7 @@ class LlmHelloWorldNonComparative(gl.Contract): ## Key Components 1. **AI Integration**: The contract uses non-comparative equivalence principle to interact with an AI model. -2. **Deterministic Execution**: `gl.eq_principle_prompt_non_comparative()` ensures that all nodes in the network accept responses that meet the specified criteria. +2. **Deterministic Execution**: `gl.eq_principle.prompt_non_comparative()` ensures that all nodes in the network accept responses that meet the specified criteria. 3. **State Management**: The contract maintains a single string state variable that stores the AI response. ## Deploying the Contract diff --git a/pages/developers/intelligent-contracts/examples/llm-hello-world.mdx b/pages/developers/intelligent-contracts/examples/llm-hello-world.mdx index d79a2995..e5bc60ee 100644 --- a/pages/developers/intelligent-contracts/examples/llm-hello-world.mdx +++ b/pages/developers/intelligent-contracts/examples/llm-hello-world.mdx @@ -20,11 +20,11 @@ class LlmHelloWorld(gl.Contract): def get_message() -> str: task = "There is no context, I just want you to answer with a string equal to 'yes'" - result = gl.exec_prompt(task) + result = gl.nondet.exec_prompt(task) print(result) return result - self.message = gl.eq_principle_strict_eq(get_message) + self.message = gl.eq_principle.strict_eq(get_message) @gl.public.view def get_message(self) -> str: @@ -37,14 +37,14 @@ class LlmHelloWorld(gl.Contract): - **Write Method**: - `set_message()` uses AI functionality to generate and store a message. - It contains an inner function `get_message()` that prompts an AI model with a simple task. - - Uses `gl.eq_principle_strict_eq()` to ensure deterministic AI responses across the network. + - Uses `gl.eq_principle.strict_eq()` to ensure deterministic AI responses across the network. - **Read Method**: - `get_message()` returns the stored message. ## Key Components -1. **AI Integration**: The contract uses `gl.exec_prompt()` to interact with an AI model. -2. **Deterministic Execution**: `gl.eq_principle_strict_eq()` ensures that all nodes in the network arrive at the same exact result. +1. **AI Integration**: The contract uses `gl.nondet.exec_prompt()` to interact with an AI model. +2. **Deterministic Execution**: `gl.eq_principle.strict_eq()` ensures that all nodes in the network arrive at the same exact result. 3. **State Management**: The contract maintains a single string state variable that stores the AI response. ## Deploying the Contract diff --git a/pages/developers/intelligent-contracts/examples/prediction.mdx b/pages/developers/intelligent-contracts/examples/prediction.mdx index 37968087..e381910e 100644 --- a/pages/developers/intelligent-contracts/examples/prediction.mdx +++ b/pages/developers/intelligent-contracts/examples/prediction.mdx @@ -3,7 +3,7 @@ The Prediction Market contract sets up a scenario to determine the outcome of a football game between two teams. The contract uses the Equivalence Principle to ensure accurate and consistent decision-making based on the game's resolution data. ```python filename="PredictionMarket" copy -# { "Depends": "py-genlayer:test" } +# { "Depends": "py-genlayer:latest" } from genlayer import * @@ -13,34 +13,21 @@ import typing class PredictionMarket(gl.Contract): has_resolved: bool - game_date: str team1: str team2: str resolution_url: str + winner: u256 + score: str def __init__(self, game_date: str, team1: str, team2: str): - """ - Initializes a new instance of the prediction market with the specified game date and teams. - - Args: - game_date (str): The date of the game in the format 'YYYY-MM-DD'. - team1 (str): The name of the first team. - team2 (str): The name of the second team. - - Attributes: - has_resolved (bool): Indicates whether the game's resolution has been processed. Default is False. - game_date (str): The date of the game. - resolution_url (str): The URL to the game's resolution on BBC Sport. - team1 (str): The name of the first team. - team2 (str): The name of the second team. - """ self.has_resolved = False - self.game_date = game_date self.resolution_url = ( "https://www.bbc.com/sport/football/scores-fixtures/" + game_date ) self.team1 = team1 self.team2 = team2 + self.winner = u256(0) + self.score = "" @gl.public.write def resolve(self) -> typing.Any: @@ -48,36 +35,43 @@ class PredictionMarket(gl.Contract): if self.has_resolved: return "Already resolved" - def nondet() -> str: - web_data = gl.get_webpage(self.resolution_url, mode="text") + market_resolution_url = self.resolution_url + team1 = self.team1 + team2 = self.team2 + + def get_match_result() -> typing.Any: + web_data = gl.nondet.web.render(market_resolution_url, mode="text") print(web_data) - task = f"""In the following web page, find the winning team in a matchup between the following teams: - Team 1: {self.team1} - Team 2: {self.team2} - - Web page content: - {web_data} - End of web page data. - - If it says "Kick off [time]" between the names of the two teams, it means the game hasn't started yet. - If you fail to extract the score, assume the game is not resolved yet. - - Respond with the following JSON format: - {{ - "score": str, // The score with numbers only, e.g, "1:2", or "-" if the game is not resolved yet - "winner": int, // The number of the winning team, 0 for draw, or -1 if the game is not yet finished - }} - It is mandatory that you respond only using the JSON format above, - nothing else. Don't include any other words or characters, - your output must be only JSON without any formatting prefix or suffix. - This result should be perfectly parsable by a JSON parser without errors. + task = f""" +In the following web page, find the winning team in a matchup between the following teams: +Team 1: {team1} +Team 2: {team2} + +Web page content: +{web_data} +End of web page data. + +If it says "Kick off [time]" between the names of the two teams, it means the game hasn't started yet. +If you fail to extract the score, assume the game is not resolved yet. + +Respond with the following JSON format: +{{ + "score": str, // The score with numbers only, e.g, "1:2", or "-" if the game is not resolved yet + "winner": int, // The number of the winning team, 0 for draw, or -1 if the game is not yet finished +}} +It is mandatory that you respond only using the JSON format above, +nothing else. Don't include any other words or characters, +your output must be only JSON without any formatting prefix or suffix. +This result should be perfectly parsable by a JSON parser without errors. """ - result = gl.exec_prompt(task).replace("```json", "").replace("```", "") + result = ( + gl.nondet.exec_prompt(task).replace("```json", "").replace("```", "") + ) print(result) - return json.dumps(json.loads(result), sort_keys=True) + return json.loads(result) - result_json = json.loads(gl.eq_principle_strict_eq(nondet)) + result_json = gl.eq_principle.strict_eq(get_match_result) if result_json["winner"] > -1: self.has_resolved = True @@ -85,9 +79,17 @@ class PredictionMarket(gl.Contract): self.score = result_json["score"] return result_json + + @gl.public.view + def get_resolution_data(self) -> dict[str, typing.Any]: + return { + "winner": self.winner, + "score": self.score, + "has_resolved": self.has_resolved, + } ``` -You can check out this code on our [GitHub](https://github.com/genlayerlabs/genlayer-studio/blob/main/examples/contracts/football_prediction_market.py) +You can check out this code on our [GitHub](https://github.com/genlayerlabs/genlayer-testing-suite/blob/main/tests/examples/contracts/football_prediction_market.py) ## Deploying the Contract diff --git a/pages/developers/intelligent-contracts/examples/user-storage.mdx b/pages/developers/intelligent-contracts/examples/user-storage.mdx index 91f07ce3..3c9d3e09 100644 --- a/pages/developers/intelligent-contracts/examples/user-storage.mdx +++ b/pages/developers/intelligent-contracts/examples/user-storage.mdx @@ -35,7 +35,7 @@ class UserStorage(gl.Contract): - **Read Methods**: - `get_complete_storage()` returns the entire storage dictionary, containing all user data. - `get_account_storage(account_address)` returns the stored value for a specific user account. -- **Write Method**: `update_storage(new_storage)` allows updating the stored value for the user who called the contract (identified by `contract_runner.from_address`). +- **Write Method**: `update_storage(new_storage)` allows updating the stored value for the user who called the contract (identified by `gl.message.sender_address`). ## Deploying the Contract @@ -58,7 +58,7 @@ To interact with the deployed contract, go to the **Write Methods** section. Her When the `update_storage` method is executed: -- The contract updates the `self.storage` dictionary, associating the new value with the address of the user who called the function (`contract_runner.from_address`). +- The contract updates the `self.storage` dictionary, associating the new value with the address of the user who called the function (`gl.message.sender_address`). - You can then use the `get_account_storage()` or `get_complete_storage()` methods to verify that the value has been updated for the specific user. ## Handling Different Scenarios diff --git a/pages/developers/intelligent-contracts/examples/wizard-of-coin.mdx b/pages/developers/intelligent-contracts/examples/wizard-of-coin.mdx index bc242985..3d33fbe4 100644 --- a/pages/developers/intelligent-contracts/examples/wizard-of-coin.mdx +++ b/pages/developers/intelligent-contracts/examples/wizard-of-coin.mdx @@ -3,7 +3,7 @@ The Wizard of Coin contract sets up a scenario where a wizard possesses a valuable coin, which adventurers try to obtain. The wizard must decide whether to give the coin away based on specific conditions. ```python -# { "Depends": "py-genlayer:test" } +# { "Depends": "py-genlayer:latest" } from genlayer import * import json @@ -19,6 +19,7 @@ class WizardOfCoin(gl.Contract): def ask_for_coin(self, request: str) -> None: if not self.have_coin: return + prompt = f""" You are a wizard, and you hold a magical coin. Many adventurers will come and try to get you to give them the coin. @@ -42,23 +43,25 @@ your output must be only JSON without any formatting prefix or suffix. This result should be perfectly parseable by a JSON parser without errors. """ - def nondet(): - res = gl.exec_prompt(prompt) - res = res.replace("```json", "").replace("```", "") - print(res) - dat = json.loads(res) - return dat["give_coin"] + def get_wizard_answer(): + result = gl.nondet.exec_prompt(prompt) + result = result.replace("```json", "").replace("```", "") + print(result) + return result - result = gl.eq_principle_strict_eq(nondet) - assert isinstance(result, bool) - self.have_coin = result + result = gl.eq_principle.prompt_comparative( + get_wizard_answer, "The value of give_coin has to match" + ) + parsed_result = json.loads(result) + assert isinstance(parsed_result["give_coin"], bool) + self.have_coin = not parsed_result["give_coin"] @gl.public.view def get_have_coin(self) -> bool: return self.have_coin ``` -You can check out this code on our [GitHub](https://github.com/genlayerlabs/genlayer-studio/blob/main/examples/contracts/wizard_of_coin.py) +You can check out this code on our [GitHub](https://github.com/genlayerlabs/genlayer-testing-suite/blob/main/tests/examples/contracts/wizard_of_coin.py) ## Deploying the Contract From 8e4acf868412222509fe266c3b3d62ed94c6929a Mon Sep 17 00:00:00 2001 From: "Bob (Clawdbot)" Date: Thu, 5 Mar 2026 18:20:59 +0100 Subject: [PATCH 5/5] docs: fix dApp section - broken links and typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix SDK reference link: /references/genlayer-js → /api-references/genlayer-js - Fix first contract link: your-first-contract → first-contract - Fix typo: instace → instance Co-Authored-By: Claude Opus 4.6 --- .../decentralized-applications/dapp-development-workflow.mdx | 4 ++-- pages/developers/decentralized-applications/genlayer-js.mdx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pages/developers/decentralized-applications/dapp-development-workflow.mdx b/pages/developers/decentralized-applications/dapp-development-workflow.mdx index ce4ecf97..69b87092 100644 --- a/pages/developers/decentralized-applications/dapp-development-workflow.mdx +++ b/pages/developers/decentralized-applications/dapp-development-workflow.mdx @@ -13,8 +13,8 @@ It provides an interactive environment that serves as a comprehensive sandbox fo The platform runs a simulated network with customizable validators that accurately mirror the GenLayer consensus mechanism. This feature allows developers to test their contracts under conditions that closely resemble the actual blockchain environment, ensuring reliable deployment outcomes. ### Getting Started: -1. **Set Up the Studio**: Developers initialize the Studio using `genlayer cli` command `genlayer init` which configures the environment and spawns a local validator network. GenLayer Studio is also available as a hosted instace at [studio.genlayer.com](https://studio.genlayer.com/). -2. **Write Your First Contract**: Intelligent Contracts in GenLayer are written in Python, utilizing its extensive libraries and GenVM capabilities like LLM calls and web integration. Refer to [Your First Contract](/developers/intelligent-contracts/your-first-contract) guide for more information. +1. **Set Up the Studio**: Developers initialize the Studio using `genlayer cli` command `genlayer init` which configures the environment and spawns a local validator network. GenLayer Studio is also available as a hosted instance at [studio.genlayer.com](https://studio.genlayer.com/). +2. **Write Your First Contract**: Intelligent Contracts in GenLayer are written in Python, utilizing its extensive libraries and GenVM capabilities like LLM calls and web integration. Refer to [Your First Contract](/developers/intelligent-contracts/first-contract) guide for more information. 3. **Deploy and Test**: Deploy your Intelligent Contracts through the Studio interface and test them in the simulated network. --- diff --git a/pages/developers/decentralized-applications/genlayer-js.mdx b/pages/developers/decentralized-applications/genlayer-js.mdx index ec480ecd..226dca20 100644 --- a/pages/developers/decentralized-applications/genlayer-js.mdx +++ b/pages/developers/decentralized-applications/genlayer-js.mdx @@ -78,4 +78,4 @@ You can find the GenLayerJS SDK repository on GitHub: ## Full Reference -The full reference for the GenLayerJS SDK is available in the [GenLayerJS SDK Reference](/references/genlayer-js). \ No newline at end of file +The full reference for the GenLayerJS SDK is available in the [GenLayerJS SDK Reference](/api-references/genlayer-js). \ No newline at end of file