Exposing Process State to HyperBEAM
HyperBEAM introduces a powerful feature for exposing parts of a process's state for immediate reading over HTTP. This improves performance for web frontends and data services by replacing the need for dryrun
calls.
The Patch Device
The [email protected]
device is the mechanism that allows AO processes to make parts of their internal state readable via direct HTTP GET requests.
How it Works
Exposing state is a four-step process:
- Process Logic: Send an outbound message to the
[email protected]
device from your process. - Patch Message Format: The message must include
device
andcache
tags.
Send({ Target = ao.id, device = '[email protected]', cache = { mydatakey = MyValue } })
- HyperBEAM Execution: HyperBEAM's
dev_patch
module processes this message, mapping the key-value pairs from thecache
table to a URL path. - HTTP Access: The exposed data is then immediately available via a standard HTTP GET request:
GET /<process-id>[email protected]/now/cache/<mydatakey>
Initial State Sync (Optional)
To make data available immediately on process creation:
-- Place this logic at the top level of your process script
Balances = { token1 = 100, token2 = 200 } -- A table of balances
TotalSupply = 1984 -- A single total supply value
-- 1. Initialize Flag:
InitialSync = InitialSync or 'INCOMPLETE'
-- 2. Check Flag:
if InitialSync == 'INCOMPLETE' then
-- 3. Patch State:
Send({ device = '[email protected]', cache = { balances = Balances, totalsupply = TotalSupply } })
-- 4. Update Flag:
InitialSync = 'COMPLETE'
end
Practical Example
Here's a complete example of a token contract that exposes its balance state:
-- Token Process with State Exposure
Balances = Balances or { [ao.id] = 1000000 }
TotalSupply = TotalSupply or 1000000
-- Initial state sync
InitialSync = InitialSync or 'INCOMPLETE'
if InitialSync == 'INCOMPLETE' then
Send({ device = '[email protected]', cache = {
balances = Balances,
totalsupply = TotalSupply
}})
InitialSync = 'COMPLETE'
end
-- Transfer handler
Handlers.add("transfer", "Transfer", function(msg)
local from = msg.From
local to = msg.Tags.Recipient or msg.Recipient
local amount = tonumber(msg.Tags.Quantity or msg.Quantity)
if Balances[from] and Balances[from] >= amount then
Balances[from] = Balances[from] - amount
Balances[to] = (Balances[to] or 0) + amount
-- Update exposed state after transfer
Send({ device = '[email protected]', cache = {
balances = Balances
}})
ao.send({ Target = from, Data = "Transfer successful" })
else
ao.send({ Target = from, Data = "Insufficient balance" })
end
end)
Accessing Exposed Data
Once state is exposed via the patch device, you can query it directly over HTTP:
# Get all balances
curl https://hyperbeam-node.arweave.net/<process-id>[email protected]/compute/cache/balances
# Get total supply
curl https://hyperbeam-node.arweave.net/<process-id>[email protected]/compute/cache/totalsupply
Benefits
Performance: Direct HTTP access is significantly faster than traditional dryrun
calls.
Simplicity: Standard REST-like patterns instead of complex message handling.
Real-time Updates: State changes are immediately reflected in HTTP responses.
Caching: HyperBEAM can cache frequently accessed data for even better performance.