Skip to content

Research Report: 22 Improvement Suggestions Across the GenLayer Ecosystem #346

@luch91

Description

@luch91

GenLayer SDK & Ecosystem Improvement Report

Research-based analysis identifying concrete improvements across the GenLayer SDK, JavaScript SDK, CLI, Studio, and documentation. Based on GitHub issues, SDK API review, and hands-on development experience.


Critical Issues (Blocking Developers Now)

1. Float values crash writeContract in genlayer-js

Issue: genlayer-js #27

Passing floating-point values in writeContract args throws TypeError: invalid calldata input '0.5'. This blocks any contract that uses decimal parameters (AMMs, pricing, percentages).

Suggestion: Fix float serialization in the calldata encoder. Support JavaScript number and BigInt types properly.

2. Gemini provider name mismatch in CLI

Issue: genlayer-cli #271

The CLI sends "geminiai" but the backend expects "google". Completely blocks Gemini as a validator LLM provider. Reported January 2026, still open.

Suggestion: Fix the provider name mapping. Add integration tests that verify every listed provider can initialize.

3. Outdated API names in documentation

Issue: genlayer-docs #305

Docs still reference gl.ContractAt() (renamed to gl.get_contract_at() in SDK v0.1.3). New developers following the docs get immediate errors.

Suggestion: Sweep all documentation for deprecated API names from v0.1.3 migration: RollbackUserError, gl.advanced.rollback_immediate()gl.advanced.user_error_immediate(), @gl.eth_contract@gl.evm.contract_interface, etc.


High Priority (Major Developer Pain Points)

4. Read methods return Maps instead of typed objects

Issue: genlayer-js #43

readContract returns JavaScript Map objects for Python TreeMap data. Every frontend must write this boilerplate:

if (claims instanceof Map) {
  return Array.from(claims.entries()).map(([id, data]: any) => {
    const obj = data instanceof Map ? Object.fromEntries(data.entries()) : data;
    return { id, ...obj };
  });
}

This pattern appears in every single read method of every frontend built on GenLayer.

Suggestion: Implement schema-based response parsing. The contract schema is available — use it to automatically return typed JavaScript objects instead of Maps.

5. Client TypeScript safety is broken

Issue: genlayer-js #30

The client uses as unknown type assertions internally. Does not follow established patterns like viem's createPublicClient/createWalletClient separation.

Suggestion: Refactor into separate createPublicClient (reads), createWalletClient (writes), createTestClient (studionet) with proper TypeScript generics.

6. No event querying or filtering in SDK

The SDK has emit_raw_event() but no way to query historical events, filter by topic, or subscribe to event streams.

Suggestion: Add gl.events.query(contract_address, event_name, filters, from_block, to_block) and WebSocket subscription for real-time listening.

7. No best practices / common patterns guide

Issue: genlayer-docs #345

Developers have specifically requested a guide covering non-deterministic patterns, prompt engineering for consensus, access control, storage patterns, and common mistakes.

Suggestion: Accept community-contributed content for this. (We've already submitted one via issue on genlayer-docs.)


Medium Priority (Significant Improvements)

8. No gas estimation

No way to predict execution costs before submitting a transaction. Critical for user-facing dApps.

Suggestion: Add gl.estimate_gas(contract_address, function_name, args) including NLP/web call cost estimates.

9. No genlayer new scaffolding command

Issue: genlayer-cli #263

No command to scaffold a new project. Developers must manually clone the boilerplate. Every modern CLI has this (npx create-next-app, forge init).

Suggestion: Implement genlayer new my-project that clones the boilerplate and prompts for configuration.

10. Storage types are limited

  • TreeMap has no range queries
  • No Set type for membership checks
  • DynArray never releases memory
  • Nested storage requires manual Indirection wrapping

Suggestion: Add TreeMap.range(start, end), a Set[T] type, and improve DynArray with shrink_to_fit().

11. No permission/access control primitives

Every contract manually implements owner checks. No built-in ACL system.

Suggestion: Provide @gl.only_owner and @gl.requires_role("admin") decorators, plus a gl.access.Ownable mixin class.

12. No timeout/retry controls for web and LLM calls

gl.nondet.web.get(), gl.nondet.web.render(), and gl.nondet.exec_prompt() have no timeout, retry, or rate-limit parameters.

Suggestion: Add timeout_ms, retries, and retry_delay_ms parameters to all web and LLM methods.

13. Transaction receipt polling is awkward

The waitForTransactionReceipt requires status: "ACCEPTED" as any — the TypeScript types don't enumerate valid statuses.

Suggestion: Fix the status type. Add a progress callback so frontends can show consensus progress.

14. Cannot send value in Studio UI

Issue: genlayer-studio #1026

No way to send GEN with transactions in Studio. Blocks testing any payable method.

Suggestion: Add a "Value" input field next to function arguments.

15. No contract transaction history in Studio

Issue: genlayer-studio #988

Cannot see transactions sent to/from a contract. Must manually track hashes.

Suggestion: Add a "Transaction History" tab per contract.

16. Appeal/failure state reversion missing

Issue: genlayer-studio #1038

When an appeal succeeds or transaction fails, state is not reverted. Breaks transactional atomicity.


Low Priority (Nice to Have)

17. Equivalence principle lacks numeric tolerance

No fuzzy numeric comparison mode — only string/NLP-based.

Suggestion: Add gl.eq_principle.numeric_tolerance(fn, tolerance=0.05).

18. Naming inconsistencies in the API

get_contract_at() vs deploy_contract() — verb position differs. Module organization inconsistent.

19. Client recreation required on account change

Switching MetaMask accounts requires destroying and recreating the GenLayer client.

Suggestion: Allow client.setAccount(newAddress) without full reconstruction.


Ecosystem-Wide Gaps

20. No contract upgrade/proxy pattern

No documented or supported pattern for upgrading deployed contracts. Dealbreaker for production dApps.

Suggestion: Document a proxy pattern using __handle_undefined_method__ or implement first-class upgradeability.

21. No block explorer

The ecosystem has no block explorer for inspecting transactions, contract state, or network activity.

22. No testing framework for JS frontend integration

Python contracts have gltest, but nothing exists for testing frontend contract interactions.

Suggestion: Provide a genlayer-js/testing module with mock clients and assertion helpers.


Priority Summary

Priority Count Examples
Critical 3 Float crash, Gemini broken, outdated docs
High 4 Map returns, broken types, no events, no patterns guide
Medium 9 No gas estimation, no scaffolding, limited storage, no Studio value-send
Low 3 Numeric tolerance, naming, client recreation
Ecosystem 3 No upgrades, no explorer, no JS testing

Sources

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions