Bittensor EVM
Get receipts of your finished Beam transfers and Room deliveries recorded on Bittensor EVM, where any smart contract can read them, for 1 credit each.
Beam runs a relay on Bittensor EVM mainnet. It records receipts of finished Beam transfers and Room deliveries in Beam's receipts contract, where any contract can read them. Your organization gets receipts in one of two ways, or both:
- Every transfer. Turn on one switch in the console, and every transfer your organization creates while it is on gets a receipt when it finishes.
- Contract requests. A contract or wallet of yours, approved by Beam, asks for the receipts it needs.
Each recorded receipt costs 1 credit. Payloads never go onchain. A receipt holds metadata only: status, size, completion time and fingerprints.
What a receipt proves
A receipt on Bittensor EVM is Beam-reported: it records what Beam's API reported about the transfer, written by one operator, Beam's relay. A Room receipt can also carry target-signed receipts from the agents that received the file. Nothing independently checks Beam's answer, and no receipt proves that the content is correct.
Beam's mainnet deployment
| Chain | Bittensor EVM mainnet, chain id 964 |
| RPC | https://lite.chain.opentensor.ai |
| Receipts contract | 0x52c7d4c0d7462562295bbf2e55d3350ca30ba992 |
| Relay account | 0x5c5F0264Ed98FabBfF41C921c6C0f18189E2f373 |
| Mode | Receipts only: donAttested() is false, so receipts are level 1, or 3 for Room receipts that every target signed |
The relay records receipts only. It does not start transfers: start them with an SDK, the CLI or Studio as usual.
Set up your organization
Members who manage billing set this up in the console, because receipts spend credits.
- Create a read-only key. On the console's API keys page, create a key and apply the Read-only: transfers + Room evidence preset in its permission matrix, and nothing else. Beam's relay reads your transfers with this key and charges your receipts to it. The console refuses a key that can do more than read.
- Register it. Open Organization → Onchain receipts and paste the key. The console seals it so that only Beam's relay can read it; Beam's website stores it but cannot use it.
- Choose how you get receipts, below. You can use both.
Every transfer
Turn on Record a receipt for every transfer. Every transfer your organization creates while it is on gets a receipt once it finishes, whether it completed, failed or was cancelled. Nobody sends a transaction: the relay finds your finished transfers and records their receipts, usually within a minute or two of each one finishing, several in one transaction when it can.
Turning the switch off stops receipts for transfers created afterwards. A transfer that was already running still gets its receipt.
Every receipt costs a credit, so an organization that runs many transfers pays for each of them. Turn the switch on for the period or the workload whose transfers you need proven.
Contract requests
Register the contract or wallet address that will ask for receipts, under Contracts that
request receipts. Beam reviews and approves it, and the relay then allows the address on
the receipts contract (setRequester). The tab shows when it is allowed onchain.
An approved address asks with:
| Call | For |
|---|---|
requestReceipt(bytes16 transferId) | A standard transfer. transferId is the transfer's UUID as 16 bytes. |
requestRoomReceipt(string room, string channel, string publication) | A Room delivery, named by its Room, object channel and publication ids. |
cast send 0x52c7d4c0d7462562295bbf2e55d3350ca30ba992 \
'requestReceipt(bytes16)' 0x0123456789abcdef0123456789abcdef \
--rpc-url https://lite.chain.opentensor.ai --private-key "$REQUESTER_KEY"The address pays the gas of its request. The relay checks every open request at Beam on each pass. Once Beam reports the transfer finished, the receipt is recorded, usually within a minute or two. A request for a transfer that is still running stays open until it finishes; a repeated request, or a request for a receipt already recorded, changes nothing. A request is answered only for your own organization's transfers and Room deliveries.
Beam's relay records receipts only. It closes a request it will never answer with
cancelRequest, at 1 credit to your organization, so Beam pays no gas for requests it
cannot serve:
requestTransfer, because Beam's relay never starts transfers;- a request from an address that is no longer approved;
- a receipt request for a transfer or Room delivery your read-only key still cannot see an hour after the request.
When your organization is out of credits, the request stays open instead. To avoid the
charge, cancel a mistaken request yourself within the hour with cancelRequest(key), paying
only your own gas. The contract computes the key:
| Request | Key |
|---|---|
| A transfer's receipt | receiptRequestKey(transferId) |
| A Room delivery's receipt | roomRequestKey(roomReceiptKey(room, channel, publication)) |
Pricing
| Every transfer | Contract request | |
|---|---|---|
| Beam's charge | 1 credit per recorded receipt | 1 credit per recorded receipt |
| Gas to ask | none | about 164,000 gas, about 0.0008 TAO at 5 gwei, paid by your address |
| Gas to record | paid by Beam | paid by Beam |
| A request Beam's relay closes | none | 1 credit per closed request |
| Reading a receipt | free | free |
- A credit is charged only once the receipt is onchain, and a receipt asked for both ways is charged once.
- When your organization is out of credits, nothing is recorded: requests stay open and every-transfer receipts wait. Both are recorded after you top up.
- The transfer itself is priced as usual, whether or not anything goes onchain. The console's Onchain receipts tab shows your price.
Read a receipt
BeamTransferReceipts.StandardReceipt memory receipt = receipts.getReceipt(transferId);
bool finished = receipt.status == BeamTransferReceipts.Status.Completed;A standard receipt holds status (completed, failed, cancelled), totalBytes,
bytesTransferred, completedAtMs, planFingerprint, coordinateChecksum and
level. A Room receipt, read with getRoomReceipt(roomReceiptKey(room, channel, publication)), holds the status, file size, manifest hash, target count, the
evidence and assignment hashes, and level.
Run your own relay
The contract and the relay are open source, in packages/cre of the
Beam SDK repository.
To record receipts without Beam's relay, deploy your own receipts contract with
donAttested false and the relay's account as its forwarder, then run the relay with
a read-only key of your organization. You then pay every transaction yourself, and Beam
charges nothing beyond the transfer. It can run receipts only, as Beam's does, or also
start transfers through your own Studio. See the package README.
Onchain data is public
Everything the contract stores or emits is public and permanent: transfer ids, byte counts, completion times, fingerprints, and Room, channel and publication ids. With Record a receipt for every transfer on, that holds for every transfer your organization creates. Do not record receipts of transfers whose metadata must stay private.