# The Off-Chain Wire

*Decoding Solana Transaction Logs for the Sentinel Network*

By [Chakra](https://paragraph.com/@chakra-papers) · 2026-06-11

@solana, @web3, @anchor, @rust

---

_CHAKRA SERIES - 6_
-------------------

_Welcome to Day 6._

_Day 4 was_ [_state.rs_](http://state.rs)_. The data model. The containers. Day 5 was_ [_errors.rs_](http://errors.rs)_. The ten promises. The safety guarantees._

_Today is_ [_events.rs_](http://events.rs)_. And this one is different from the last two._

[_state.rs_](http://state.rs) _and_ [_errors.rs_](http://errors.rs) _are about what CHAKRA remembers and what CHAKRA refuses to do. They are internal. They define the shape and the limits of the protocol._

[_events.rs_](http://events.rs) _is about how CHAKRA talks._

_Specifically - how the on-chain Solana program talks to the off-chain Sentinel Network without any trusted intermediary between them._

_This is one of the most underrated design problems in all of cross-chain development. You have a Solana program running inside the Solana Virtual Machine. You have Rust processes running on three different servers. How do they communicate? Who tells the servers when to start working? How do the servers know what work to do?_

_The answer is in this file. Three structs. Thirty lines of code. Let me show you._

* * *

**_Part 1: What Is a Solana Event_**

_Before the code, the concept._

_When an Anchor program emits an event, it writes structured data to the transaction logs of that transaction. Not to an account. Not to storage. To the logs._

_Every Solana transaction produces logs. They are public. Anyone watching the network can read them. And crucially anyone can subscribe to them in real time via WebSocket._

_So when CHAKRA's on-chain program emits a ControlIntent event, it is not sending a message to anyone specifically. It is publishing structured data to a public channel. The Sentinel Nodes are subscribed to that channel. They hear it. They act on it._

_No intermediary. No message broker. No trusted relay. Just a public log and three processes listening to it._

_This design means the communication channel itself cannot be corrupted. The Sentinel Nodes read directly from Solana. If they hear a ControlIntent event it is because the CHAKRA program actually emitted it, which means a user actually called initialize\_intent, which means funds are actually locked in an escrow PDA. The Sentinel Nodes do not need to trust anyone who tells them to start working. They verify the source themselves._

* * *

**_Part 2: The File_**

_rust_

    use anchor_lang::prelude::*;
    
    #[event]
    pub struct ControlIntent {
        pub owner: Pubkey,
        pub target_chain_id: u64,
        pub nonce: u64,
        pub amount: u64,
        pub source_chain: [u8; 32],
        pub target_chain: [u8; 32],
        pub target_address: [u8; 64],
        pub escrow_pda: Pubkey,
        pub timeout_slot: u64,
    }
    
    #[event]
    pub struct IntentFinalized {
        pub escrow_pda: Pubkey,
        pub tx_hash: [u8; 64],
    }
    
    #[event]
    pub struct IntentCancelled {
        pub escrow_pda: Pubkey,
    }

_Three events. Each one marks a different moment in the lifecycle of a cross-chain intent._

* * *

**_Part 3: ControlIntent — The Starting Gun_**

_rust_

    #[event]
    pub struct ControlIntent {
        pub owner: Pubkey,
        pub target_chain_id: u64,
        pub nonce: u64,
        pub amount: u64,
        pub source_chain: [u8; 32],
        pub target_chain: [u8; 32],
        pub target_address: [u8; 64],
        pub escrow_pda: Pubkey,
        pub timeout_slot: u64,
    }

_This is the event that starts everything._

_When a user calls initialize\_intent and it succeeds funds locked, escrow created, all validations passed - the CHAKRA Controller emits this event to the transaction logs._

_The Sentinel Nodes are watching. They parse it. They start the signing ceremony._

_Let me walk through every field and explain why it is here._

**_owner_** _— the Pubkey of the user who created the intent. The Sentinel Nodes need this to verify that the escrow PDA they are about to work on actually belongs to the person they think it belongs to. It is also in the escrow account on-chain. The Sentinel cross-references both._

**_target\_chain\_id_** _— which blockchain to execute on. Base Sepolia is 84532. This number goes into the message payload that the Sentinel Nodes sign. The same number goes into the ChakraReceiver.sol call on the target chain. The ChakraReceiver verifies it. If the Sentinel tried to execute on a different chain than the one the user specified, the signature would not verify because the chain ID would be wrong._

**_nonce_** _— the uniqueness identifier for this specific intent. Combined with the owner's address and the chain ID it is part of the PDA seed. So when the Sentinel has the nonce, it can deterministically compute the escrow PDA address and fetch the account to cross-check all the other fields._

**_amount_** _— how many lamports are locked. This also goes into the signing payload. The ChakraReceiver contract verifies the signature over this amount. If a Sentinel tried to execute a different amount than what the user specified, the signature would fail verification on the target chain._

**_source\_chain and target\_chain_** _— both 32-byte arrays identifying the chains involved. source\_chain is always "solana" in the current implementation. target\_chain is "base" or "ethereum" etc. These go into the event so the Sentinel Nodes can route the execution correctly. If CHAKRA supports five target chains in the future, the Sentinel Network uses this field to know which chain's RPC to call._

**_target\_address_** _— 64 bytes. The destination address on the target chain where the execution should happen or the funds should go. This is the most sensitive field in the event. If this were tampered with, the execution would go to the wrong address. The fact that it is signed as part of the TSS payload means any tampering would invalidate the signature and the ChakraReceiver would reject it._

**_escrow\_pda_** _— the address of the escrow account holding the user's funds. The Sentinel Nodes use this to verify the event data matches what is actually on-chain before starting the signing ceremony. This is the cross-check. The event data could theoretically be crafted. But the escrow account on-chain cannot be faked. The Sentinel fetches the escrow by this PDA and verifies everything matches._

**_timeout\_slot_** _— the absolute deadline. The Sentinel Network must complete execution and submit proof before this slot. The coordinator checks the current slot against this value before starting work. If it is already past the deadline — maybe the event was delayed, maybe the signing took too long — the coordinator aborts rather than wasting gas on an execution that can never be verified on time._

_Every field in ControlIntent has a job. Nothing is there by accident._

* * *

**_Part 4: IntentFinalized — The Confirmation_**

_rust_

    #[event]
    pub struct IntentFinalized {
        pub escrow_pda: Pubkey,
        pub tx_hash: [u8; 64],
    }

_This event fires when submit\_proof succeeds._

_The TSS signature verified. The escrow closed. The lamports went to treasury._

_Two fields._

**_escrow\_pda_** _— which intent was finalized. Any indexer, any dashboard, any monitoring tool watching CHAKRA's program logs can use this to track intent states in real time._

**_tx\_hash_** _— the transaction hash of the execution on the target chain. This is the receipt. When a user wants to verify that their intent was actually executed on Base Sepolia, this is the hash they take to the Base Sepolia block explorer. It is stored in the event so it is permanently on-chain as part of the Solana transaction record._

_This matters for auditability. In a world where "trust me it happened on the other chain" is not acceptable, IntentFinalized puts the cross-chain receipt permanently on Solana. Every intent execution is publicly verifiable from the Solana side._

* * *

**_Part 5: IntentCancelled — The Safe Exit_**

_rust_

    #[event]
    pub struct IntentCancelled {
        pub escrow_pda: Pubkey,
    }

_The simplest event. One field._

_This fires when cancel\_intent succeeds. The timeout passed. The Sentinel Network did not complete in time. The user called cancel. The funds returned._

_One field because there is nothing else to record. The escrow PDA tells you which intent was cancelled. There is no target chain transaction hash because no target chain execution happened. There is no amount because the amount went back to the user and that is a Solana-side operation recorded in the cancel transaction itself._

_The simplicity of IntentCancelled is actually a design signal. If you see mostly IntentFinalized events in the logs, the protocol is working well. If you start seeing a lot of IntentCancelled events, something is wrong with the Sentinel Network. The events tell the story of protocol health in real time._

* * *

**_Part 6: How the Sentinel Actually Reads These_**

_This is the part most people do not think about._

_Anchor events are emitted as base64-encoded binary data in the transaction logs. They look like garbage to a human reading the raw logs. The Sentinel Nodes have to:_

1.  _Subscribe to Solana transaction logs for the CHAKRA program via WebSocket_
    
2.  _Filter for logs that contain "Program data:" — that is where Anchor encodes events_
    
3.  _Base64-decode the data_
    
4.  _Check the first 8 bytes he Anchor event discriminator_
    
5.  _Verify it matches the discriminator for ControlIntent specifically_
    
6.  _Deserialize the remaining bytes into the ControlIntent struct_
    

_The discriminator is computed as the first 8 bytes of SHA256("event:ControlIntent"). This is how the Sentinel knows it is looking at a ControlIntent and not some other event or log line._

_If the discriminator does not match, the Sentinel ignores it and moves on. If it does match, the Sentinel trusts the data not because the event claimed to be valid, but because the event came from the CHAKRA program's address and the Solana validator already verified that the program executed correctly._

_This is the security model of Solana events. You do not trust the data in isolation. You trust it because of where it came from and the fact that it is permanently embedded in a finalized transaction._

* * *

* * *

### _Part 7: The Core Foundations Are Set_

_With_ `state.rs`_,_ `errors.rs`_, and now_ `events.rs` _completely laid out, you have seen the entire structural anatomy of CHAKRA:_

1.  **_The Container:_** _How we pack every byte tightly on-chain to minimize user rent._
    
2.  **_The Guardrails:_** _The ten strict promises that make our protocol refuse to collapse._
    
3.  **_The Voice:_** _How we broadcast cryptographically verifiable signals to the off-chain world without middlemen._
    

_We are officially done with the setup files. The architectural blueprint is complete._

_In the upcoming days, things turn even more interesting. We are shifting from structure to action opening up the heavy-hitting instruction engines, starting with the file that triggers the entire machine:_ `initialize_intent.rs`_. Every read from here on out gets closer to the live mainframe._

_and see y'all for Day 7._

* * *

_Thankyou for reading. And here are some resources you can refer to_

[

Transaction Confirmation & Expiration
-------------------------------------

Understand how Solana transaction confirmation and when a transaction expires (including recent blockhash checks).

https://solana.com

![Transaction Confirmation & Expiration](https://storage.googleapis.com/papyrus_images/2e7300e63afb3d87f0c75673e8b53a75dcd024be0231df43559cb663d6748c58.png)

](https://solana.com/developers/guides/advanced/confirmation)

[

anchor\_lang - Rust
-------------------

Anchor ⚓ is a framework for Solana's Sealevel runtime providing several convenient developer tools.

https://docs.rs



](https://docs.rs/anchor-lang/latest/anchor_lang/)

[

logsSubscribe
-------------

Subscribe to transaction log messages that match a log filter.

https://solana.com

![logsSubscribe](https://storage.googleapis.com/papyrus_images/2e91cc25824280a68f22fc901f6290cb7e1c1f169fccb6858d3f761b0918c65d.png)

](https://solana.com/docs/rpc/websocket/logssubscribe)

[_https://solanacookbook.com/references/programs.html#how-to-transfer-sol-in-a-program_](https://solanacookbook.com/references/programs.html#how-to-transfer-sol-in-a-program)

* * *

![](https://storage.googleapis.com/papyrus_images/b34c4310ed4a8429f54429ccfb1ffb8f03bc3657fa9f8f332bb4e2ae58b0ab84.avif)

  

_Written by Maha.._

---

*Originally published on [Chakra](https://paragraph.com/@chakra-papers/the-off-chain-wire)*
