Skip to content

docs: Value Transfers and Messages pages#386

Merged
MuncleUscles merged 5 commits into
mainfrom
feat/value-transfer-docs
Apr 7, 2026
Merged

docs: Value Transfers and Messages pages#386
MuncleUscles merged 5 commits into
mainfrom
feat/value-transfer-docs

Conversation

@MuncleUscles

@MuncleUscles MuncleUscles commented Apr 7, 2026

Copy link
Copy Markdown
Member

Summary

  • New Value Transfers page: payable methods, gl.message.value, sending/receiving GEN, balances, __receive__/__handle_undefined_method__, funding accounts, JS client examples
  • New Messages page: three-tier interaction model (transactions → internal messages → external messages), ghost contracts, gl.message context, accepted vs finalized timing, @gl.contract_interface and @gl.evm.contract_interface
  • Updated existing pages with cross-links and value examples
  • Redirected old balances page to value-transfers

Key concepts documented

  • Transactions (EOA/EVM contract → IC via addTransaction on ConsensusMain or ghost)
  • Internal messages (IC → IC via emit/emit_transfer/deploy_contract)
  • External messages (IC → chain layer via ghost contract handleOp)
  • Ghost contract role: balance custody, tx relay, external message execution, address bridging
  • Studio limitations called out where behavior differs from real consensus

Summary by CodeRabbit

  • Documentation
    • Added comprehensive "Messages" guide covering transaction types, internal/external messaging patterns, ghost contracts, and context fields.
    • Added "Value Transfers" guide explaining how to receive, send, and read GEN balances in intelligent contracts with JavaScript examples.
    • Added "Calling Payable Methods" example demonstrating value transfers via JavaScript client integration.
    • Reorganized feature documentation structure and added cross-reference clarifications for related topics.

- External messages: EOA → contract via payable methods, gl.message.value
- Internal messages: contract → contract/EOA via emit_transfer (deferred)
- Complete escrow example showing both patterns
- Payable methods section added to writing-data (JS SDK side)
- Funding table: Studio faucet UI, Studionet auto-fund, testnet faucet
New pages:
- Value Transfers: payable methods, gl.message.value, sending/receiving
  GEN, balances, special handlers, JS client examples
- Messages: three-tier interaction model (transactions, internal messages,
  external messages), ghost contracts, gl.message context, accepted vs
  finalized timing, IC and EVM interfaces

Updated:
- interacting-with-intelligent-contracts: added value param to emit examples
- interacting-with-evm-contracts: added external message context
- special-methods: linked to value transfers
- writing-data: added payable methods JS section
- balances: redirected to value-transfers
- _meta.json: reordered navigation
@netlify

netlify Bot commented Apr 7, 2026

Copy link
Copy Markdown

Deploy Preview for genlayer-docs ready!

Name Link
🔨 Latest commit 49a032a
🔍 Latest deploy log https://app.netlify.com/projects/genlayer-docs/deploys/69d52719340d340008e637f8
😎 Deploy Preview https://deploy-preview-386--genlayer-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0f5fd2e9-3632-46cb-aa90-caea5266ff03

📥 Commits

Reviewing files that changed from the base of the PR and between f4bae64 and 49a032a.

📒 Files selected for processing (2)
  • pages/developers/intelligent-contracts/features/messages.mdx
  • pages/developers/intelligent-contracts/features/value-transfers.mdx
✅ Files skipped from review due to trivial changes (1)
  • pages/developers/intelligent-contracts/features/value-transfers.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
  • pages/developers/intelligent-contracts/features/messages.mdx

📝 Walkthrough

Walkthrough

These changes introduce comprehensive documentation for GenLayer intelligent contract value transfers and messaging architecture. The updates include two new detailed guide pages, restructured navigation, consolidated balance-related content, and added examples demonstrating payable methods and value-bearing message operations across different transaction types and execution layers.

Changes

Cohort / File(s) Summary
Feature Navigation Restructure
pages/developers/intelligent-contracts/features/_meta.json
Removed balances entry, added value-transfers and messages entries, and reordered feature mapping entries in navigation metadata.
New Comprehensive Guides
pages/developers/intelligent-contracts/features/messages.mdx, pages/developers/intelligent-contracts/features/value-transfers.mdx
Added two new detailed documentation pages: Messages covering Transactions, Internal Messages, External Messages, and ghost contracts architecture; Value Transfers explaining receiving/sending GEN, payable methods, and balance management.
Balance Content Consolidation
pages/developers/intelligent-contracts/features/balances.mdx
Replaced existing balance documentation with redirect notice pointing to new Value Transfers page.
Feature Page Cross-References
pages/developers/intelligent-contracts/features/interacting-with-*.mdx, pages/developers/intelligent-contracts/features/special-methods.mdx
Added informational blockquotes and callouts linking to Messages and Value Transfers sections; extended examples with value-bearing message operations.
Decentralized Applications Guide Update
pages/developers/decentralized-applications/writing-data.mdx
Added "Calling Payable Methods" section with example demonstrating writeContract with value parameter for sending native GEN alongside contract writes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • genlayerlabs/genlayer-docs#317: Modifies intelligent-contracts documentation features, including features/_meta.json, balances.mdx, and content about payable contract behavior and value transfers.

Suggested reviewers

  • kp2pml30
  • cristiam86

Poem

🐰 New paths through messages bright,
Value transfers done just right,
Payable methods, GEN in flight,
Docs reorganized with delight!
Ghost contracts bridge the chain—
Architecture made plain! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'docs: Value Transfers and Messages pages' directly and clearly summarizes the main changes—adding two new documentation pages on value transfers and messages with supporting updates.
Description check ✅ Passed The PR description provides a comprehensive summary of changes including the two new pages, key concepts, and updates to existing pages; however, it does not follow the Conventional Commits template structure or explicitly close any linked issues.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/value-transfer-docs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
pages/developers/decentralized-applications/writing-data.mdx (1)

91-92: Use bigint literals for wei constants in examples.

In JavaScript, BigInt(10 ** 18) computes 10 ** 18 as a Number first (IEEE-754 double), which cannot represent all integers exactly beyond 2^53 (~9e15). The Number intermediate loses precision, and BigInt() cannot recover it. Use bigint literals instead: 5n * 10n ** 18n.

Suggested fix
-  value: BigInt(5) * BigInt(10 ** 18), // 5 GEN in wei
+  value: 5n * 10n ** 18n, // 5 GEN in wei
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pages/developers/decentralized-applications/writing-data.mdx` around lines 91
- 92, The example uses BigInt(5) * BigInt(10 ** 18) which loses precision
because 10 ** 18 is computed as a Number first; replace this with bigint
literals so the multiplication is done purely in BigInt (e.g., use 5n * 10n **
18n) and update the value assignment (the symbol to change is the value property
in that example).
pages/developers/intelligent-contracts/features/value-transfers.mdx (4)

92-92: Clarify "both layers" reference.

The phrase "The balance is visible on both layers" could be more explicit about which layers are being referenced (intelligent contract layer and chain layer).

📝 Proposed clarification
-On the GenLayer network, an IC's GEN balance is held by its [ghost contract](/developers/intelligent-contracts/features/messages#ghost-contracts) on the chain layer. `self.balance` reads from this. The balance is visible on both layers.
+On the GenLayer network, an IC's GEN balance is held by its [ghost contract](/developers/intelligent-contracts/features/messages#ghost-contracts) on the chain layer. `self.balance` reads from this. The balance is visible on both the intelligent contract layer and the chain layer.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pages/developers/intelligent-contracts/features/value-transfers.mdx` at line
92, The sentence referencing "both layers" is ambiguous; update the text that
follows "self.balance reads from this" to explicitly name the two layers as "the
intelligent contract layer and the chain layer" (mentioning the ghost contract
and self.balance for context) so it reads e.g. "The balance is visible on both
the intelligent contract layer and the chain layer." Ensure the terms "ghost
contract" and "self.balance" remain referenced for clarity.

55-68: Add explanation for the empty interface pattern.

The empty _Recipient interface class (lines 56-60) and its usage at line 68 may confuse readers. While the callout at lines 71-73 mentions future simplification, adding a brief comment explaining why the empty interface is currently required would improve clarity.

📝 Proposed enhancement
 `@gl.evm.contract_interface`
 class _Recipient:
+    # Empty interface required for external message routing
+    # (will be simplified in a future version)
     class View:
         pass
     class Write:
         pass
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pages/developers/intelligent-contracts/features/value-transfers.mdx` around
lines 55 - 68, Add a short inline comment explaining the empty interface
pattern: why the _Recipient class with empty View and Write nested classes
exists and is used to call _Recipient(Address(recipient)).emit_transfer(value=v)
in Faucet.send; mention that it serves as a temporary/explicit contract
interface placeholder required by the current gl.evm.contract_interface
mechanism and will be simplified later. Place the comment above the _Recipient
class definition (referencing _Recipient and Faucet.send) so readers immediately
understand the intent and link to the existing call site.

50-69: Consider adding error handling documentation.

The documentation covers successful value transfer scenarios comprehensively but doesn't address failure cases such as:

  • Insufficient balance in the sending contract
  • Target contract reverting during execution
  • How failures propagate in internal vs external messages

While not critical for the initial release, adding a brief section on error scenarios would help developers build more robust contracts.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pages/developers/intelligent-contracts/features/value-transfers.mdx` around
lines 50 - 69, Add a short "Error handling" subsection after the "Sending Value
to an EOA or EVM Contract" example describing failure scenarios: document
insufficient balance (what happens when Faucet.send lacks funds and how
gl.message.value is validated), target contract reverts (behavior when
_Recipient.emit_transfer triggers a revert), and how failures propagate
differently for internal vs external messages (finalization semantics and
whether exceptions like gl.vm.UserError bubble up or are swallowed). Reference
the example symbols Faucet.send, _Recipient.emit_transfer, Address(recipient),
and gl.message.value so readers can map behaviors to the provided code snippet
and include recommended mitigations (pre-check balances, try/catch patterns or
fallback handling) briefly.

7-7: Consider using LaTeX or explicit notation for the exponent.

The superscript notation "10¹⁸" may not render consistently across all contexts. Since LaTeX is supported in the Nextra configuration per coding guidelines, consider using $10^{18}$ or explicitly write "10^18" for better compatibility.

📝 Proposed alternatives

Option 1 (LaTeX):

-GenLayer uses GEN as its native token. Values are denominated in wei (1 GEN = 10¹⁸ wei). Use the `u256` type for value amounts in contract code.
+GenLayer uses GEN as its native token. Values are denominated in wei (1 GEN = $10^{18}$ wei). Use the `u256` type for value amounts in contract code.

Option 2 (explicit):

-GenLayer uses GEN as its native token. Values are denominated in wei (1 GEN = 10¹⁸ wei). Use the `u256` type for value amounts in contract code.
+GenLayer uses GEN as its native token. Values are denominated in wei (1 GEN = 10^18 wei). Use the `u256` type for value amounts in contract code.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pages/developers/intelligent-contracts/features/value-transfers.mdx` at line
7, Replace the superscript "10¹⁸" with a renderer-safe notation in the sentence
about GenLayer/GEN/wei and the `u256` type—either use LaTeX `$10^{18}$` or the
plain text `10^18` so the value denomination "1 GEN = 10^18 wei" renders
consistently; update the string that currently reads "1 GEN = 10¹⁸ wei" in the
value-transfers content to one of these alternatives.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pages/api-references/genlayer-node.mdx`:
- Around line 812-819: Close the unclosed code/JSON fence immediately before the
gen_dbg_traceTransaction section and demote the heading level by changing the
top-level heading "gen_dbg_traceTransaction" to a level-3 heading (###
gen_dbg_traceTransaction) so the JSON block is properly terminated and the
heading becomes a subsection; locate the heading string
"gen_dbg_traceTransaction" in the document and insert a closing ``` for the open
JSON/code fence just above it, then replace the leading "#" with "###" on the
heading line.
- Around line 826-892: The JSON examples in the gen_dbg_traceTransaction
request/response blocks are escaped (they use "\{" and "\}") which makes them
invalid for copy/paste; update the fenced json blocks for the example request
and response to use normal JSON braces (remove all backslash-escaped braces and
any extraneous escaping around keys/values) so the examples become valid JSON
while preserving the existing fields like "jsonrpc", "method":
"gen_dbg_traceTransaction", "params", and the "result" object with keys such as
"transaction_id", "result_code", "return_data", "genvm_log", "storage_proof",
"run_time", and "eq_outputs".

---

Nitpick comments:
In `@pages/developers/decentralized-applications/writing-data.mdx`:
- Around line 91-92: The example uses BigInt(5) * BigInt(10 ** 18) which loses
precision because 10 ** 18 is computed as a Number first; replace this with
bigint literals so the multiplication is done purely in BigInt (e.g., use 5n *
10n ** 18n) and update the value assignment (the symbol to change is the value
property in that example).

In `@pages/developers/intelligent-contracts/features/value-transfers.mdx`:
- Line 92: The sentence referencing "both layers" is ambiguous; update the text
that follows "self.balance reads from this" to explicitly name the two layers as
"the intelligent contract layer and the chain layer" (mentioning the ghost
contract and self.balance for context) so it reads e.g. "The balance is visible
on both the intelligent contract layer and the chain layer." Ensure the terms
"ghost contract" and "self.balance" remain referenced for clarity.
- Around line 55-68: Add a short inline comment explaining the empty interface
pattern: why the _Recipient class with empty View and Write nested classes
exists and is used to call _Recipient(Address(recipient)).emit_transfer(value=v)
in Faucet.send; mention that it serves as a temporary/explicit contract
interface placeholder required by the current gl.evm.contract_interface
mechanism and will be simplified later. Place the comment above the _Recipient
class definition (referencing _Recipient and Faucet.send) so readers immediately
understand the intent and link to the existing call site.
- Around line 50-69: Add a short "Error handling" subsection after the "Sending
Value to an EOA or EVM Contract" example describing failure scenarios: document
insufficient balance (what happens when Faucet.send lacks funds and how
gl.message.value is validated), target contract reverts (behavior when
_Recipient.emit_transfer triggers a revert), and how failures propagate
differently for internal vs external messages (finalization semantics and
whether exceptions like gl.vm.UserError bubble up or are swallowed). Reference
the example symbols Faucet.send, _Recipient.emit_transfer, Address(recipient),
and gl.message.value so readers can map behaviors to the provided code snippet
and include recommended mitigations (pre-check balances, try/catch patterns or
fallback handling) briefly.
- Line 7: Replace the superscript "10¹⁸" with a renderer-safe notation in the
sentence about GenLayer/GEN/wei and the `u256` type—either use LaTeX `$10^{18}$`
or the plain text `10^18` so the value denomination "1 GEN = 10^18 wei" renders
consistently; update the string that currently reads "1 GEN = 10¹⁸ wei" in the
value-transfers content to one of these alternatives.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 72cde97c-e844-4b9a-96a8-20894968c62d

📥 Commits

Reviewing files that changed from the base of the PR and between b9b7f80 and f4bae64.

📒 Files selected for processing (9)
  • pages/api-references/genlayer-node.mdx
  • pages/developers/decentralized-applications/writing-data.mdx
  • pages/developers/intelligent-contracts/features/_meta.json
  • pages/developers/intelligent-contracts/features/balances.mdx
  • pages/developers/intelligent-contracts/features/interacting-with-evm-contracts.mdx
  • pages/developers/intelligent-contracts/features/interacting-with-intelligent-contracts.mdx
  • pages/developers/intelligent-contracts/features/messages.mdx
  • pages/developers/intelligent-contracts/features/special-methods.mdx
  • pages/developers/intelligent-contracts/features/value-transfers.mdx

Comment thread pages/api-references/genlayer-node.mdx Outdated
Comment thread pages/api-references/genlayer-node.mdx Outdated
The transaction enters the consensus pipeline: activation → proposal → commit → reveal → finalization.

<Callout type="warning">
**Studio:** Transactions are submitted via JSON-RPC, not as EVM calls to a ghost contract. The consensus pipeline is simulated in Python.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong, you still call eth_sendRawTransaction or whatever it's called, the studio emulates the flow. check in the studio exactly how its defined, but as stated is wrong

**Studio:** Transactions are submitted via JSON-RPC, not as EVM calls to a ghost contract. The consensus pipeline is simulated in Python.
</Callout>

## Internal Messages (IC → IC)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important to understand messages are async. maybe explained in messages, but probably good to have a note here as well

def transfer(self, to: Address, amount: u256) -> None: ...

# Read from an EVM contract
balance = ERC20(token_address).view().balance_of(my_address)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how do I actually get my address?

balance = ERC20(token_address).view().balance_of(my_address)

# Write to an EVM contract
ERC20(token_address).emit(value=u256(0)).transfer(recipient, amount)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't value optional here?

The message executes as soon as the parent transaction is accepted by initial consensus, before the appeal window closes.

<Callout type="warning">
If the parent transaction is appealed, the re-execution may emit the message again — potentially multiple times across appeal rounds. The receiving contract must be **idempotent**: it must handle duplicate or unexpected messages gracefully.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, of course if the parent tx is appealed and in the end has a different outcome, the message might be "invalid" (ie would not have been emitted if this was the original outcome), but it cannot be taken back. contrac design must account for this possibiilty

other_balance = gl.get_contract_at(addr).balance

# EVM contract balance
evm_balance = EthContract(addr).balance

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also is the same even if the target is an EOA not a contract


In `write` methods, `self.balance` reflects the current state including any value received in the current call. In `view` methods, it shows a snapshot without modifications.

### Where Balance Lives

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if here is the best place to explain, but also, when a message is emitted - balance is taken from the contract, put into the message, and only applied to target when the message is activated

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So value goes from sender balance -> message -> recipient balance

- Fix transaction flow: SDK sends signed addTransaction via eth_sendRawTransaction
- Clarify messages are async (caller doesn't wait)
- Show how to get own address (gl.message.contract_address)
- Make value optional in EVM emit example
- Expand appeal risk callout: invalid messages can't be taken back
- Explain value flow: sender balance → message → recipient balance
- Note EOA transfers use same mechanism as EVM contract calls
@MuncleUscles MuncleUscles merged commit f48f8a2 into main Apr 7, 2026
8 checks passed
@MuncleUscles MuncleUscles deleted the feat/value-transfer-docs branch April 7, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant