Stock Tokens and RWA Documents on Robinhood Chain with Lighthouse Storage

A tokenized stock is a promise about something offchain. The promise is only as good as the documents behind it, and those documents usually live on one company's web server.
Robinhood Chain launched with Stock Tokens trading 24/7 for eligible users in more than 120 countries. The token moves in 100 millisecond blocks. The paperwork that defines what the token is does not move at all, and in most tokenization stacks nobody can prove which version of that paperwork a holder saw.
This post covers the document layer of real world asset (RWA) tokenization on Robinhood Chain: which files matter, why hosting them on ordinary servers undercuts the point of putting the asset onchain, and how to fix it with content addressed, encrypted storage from Lighthouse.
What Is Actually Offchain in a Tokenized Asset
On Robinhood Chain, Stock Tokens are tokenized debt securities issued by Robinhood Assets (Jersey) Limited that track the price of an underlying equity. Any RWA issuer on the chain, whether for equities, treasuries, credit or real estate, carries a similar pile of documents that never touch the ledger:
| Document | Who needs it | Public or private |
|---|---|---|
| Prospectus or offering memorandum | Every holder, regulators | Public |
| Terms and risk disclosures | Every holder | Public |
| Corporate action notices (splits, dividends, renames) | Holders, integrators, oracles | Public |
| Custody and reserve attestations | Holders, auditors | Public or restricted |
| NAV or pricing reports | Lending protocols, holders | Public or restricted |
| KYC and eligibility packets | Issuer, transfer agent, reviewers | Private |
| Legal agreements with counterparties | Named parties only | Private |
Every row is a file. None belongs in contract storage. And every row has a question attached that onchain settlement cannot answer: is this the same file it was yesterday?
The Problem With a URL
A typical RWA contract exposes something like documentURI() returning https://issuer.example/docs/terms.pdf. That design has three failures.
The file can change silently. The URL stays the same while the PDF behind it is replaced. A holder who bought under version one has no onchain record that version one existed.
The link can die. Domains lapse, CMS migrations rename paths, and the token outlives the website.
Access is all or nothing. A public URL cannot express "only verified holders can read the attestation" or "this counterparty sees their agreement and nobody else does."
A content identifier fixes the first two outright. Encryption with onchain conditions fixes the third.
The Pattern: Document Registry With CIDs

- The issuer uploads each document through Lighthouse and receives a CID.
- The CID is written to a document registry contract on Robinhood Chain, keyed by asset and document type, with a timestamp from the block.
- Wallets, explorers, lending protocols and auditors read the CID from the registry and fetch the file from any IPFS gateway.
- Anyone can hash what they fetched and confirm it matches the CID. No trust in the issuer's server required.
A minimal registry looks like this:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract AssetDocumentRegistry {
struct Doc {
string cid; // Lighthouse CID of the document
uint64 publishedAt;
}
address public issuer;
// assetId => docType (e.g. keccak256("PROSPECTUS")) => version history
mapping(bytes32 => mapping(bytes32 => Doc[])) private docs;
event DocumentPublished(bytes32 indexed assetId, bytes32 indexed docType, string cid, uint256 version);
constructor() { issuer = msg.sender; }
function publish(bytes32 assetId, bytes32 docType, string calldata cid) external {
require(msg.sender == issuer, "not issuer");
docs[assetId][docType].push(Doc(cid, uint64(block.timestamp)));
emit DocumentPublished(assetId, docType, cid, docs[assetId][docType].length - 1);
}
function latest(bytes32 assetId, bytes32 docType) external view returns (Doc memory) {
Doc[] storage h = docs[assetId][docType];
require(h.length > 0, "none");
return h[h.length - 1];
}
function history(bytes32 assetId, bytes32 docType) external view returns (Doc[] memory) {
return docs[assetId][docType];
}
}
The history array is the point. Updating a disclosure does not overwrite anything. It appends a new CID, and every previous version remains addressable and verifiable. When someone asks "what were the terms when I bought on August 3rd," the answer is a block number and a CID, not a support ticket.
On the upload side:
import lighthouse from "@lighthouse-web3/sdk";
const { data } = await lighthouse.upload("./nvda-token-terms-v3.pdf", process.env.LIGHTHOUSE_API_KEY);
await walletClient.writeContract({
address: REGISTRY,
abi: registryAbi,
functionName: "publish",
args: [assetId, keccak256(toBytes("TERMS")), data.Hash],
chain: robinhoodChain, // chain ID 4663
});
Keeping Documents Alive
Content addressing proves integrity. It does not by itself guarantee the bytes stay available. That is the job of the storage network underneath.
On the Filecoin path, Lighthouse places documents into storage deals where providers submit ongoing cryptographic proofs that they still hold the data. Deals have terms and Lighthouse manages renewal, which is covered in What Happens When a Filecoin Deal Expires?. For regulated documents that must be retained for years, that proof trail is useful in its own right: you can show an auditor not only what the document said, but that it has been continuously stored.
On the Walrus path, documents are erasure coded across many nodes for fast reads, which suits documents that wallets and apps fetch constantly, such as token terms displayed at purchase.
Pick per document. Frequently displayed disclosures lean toward Walrus. Archival records lean toward Filecoin. Walrus vs Filecoin: Erasure Coding or Replication? has the tradeoffs.
Private Documents: KYC, Agreements and Attestations
Not every RWA document should be public, and "decentralized" does not mean "private." Anything uploaded to IPFS unencrypted is readable by anyone who has the CID. Is IPFS Private? What Content Addressing Hides, and What It Doesn't explains exactly what leaks.
Lighthouse encrypts files client side before upload. The key is split with BLS threshold cryptography across independent key nodes, so no single node, including Lighthouse, ever holds the whole key. Then you decide who can decrypt:
- Named addresses. Share a KYC packet with the transfer agent's address and the compliance reviewer's address, each independently.
- Revocation. When a review relationship ends, revoke that party's access. The file does not move and its CID does not change.
- Conditions. Gate a reserve attestation on holding the token, or on the return value of an eligibility contract that returns
trueonly for verified wallets.
// Encrypt and share a KYC packet with two named reviewers
const { data } = await lighthouse.uploadEncrypted(
"./kyc-packet-0x7a2.pdf",
process.env.LIGHTHOUSE_API_KEY,
issuerAddress,
signedMessage
);
const cid = data[0].Hash;
await lighthouse.shareFile(issuerAddress, [transferAgent, complianceReviewer], cid, signedMessage);
// Later, when the engagement ends
await lighthouse.revokeFileAccess(issuerAddress, [complianceReviewer], cid, signedMessage);
Chain support note. Conditions that read contract state need the chain on Lighthouse's Chains Supported list, and Robinhood Chain is not listed yet. Encryption, named address sharing and revocation work today regardless of chain. To gate on Robinhood Chain contracts directly, ask the team on Discord.
Why This Matters for Stock Tokens Specifically
Stock Tokens can be used as collateral in lending pools. That means a lending protocol, not just a holder, is making decisions based on what the token represents. When a corporate action such as a stock split changes the token's terms, every integrator needs the same answer at the same time, and they need to be able to prove later which notice they acted on.
A CID in a registry event gives them that. The oracle reports the price. The registry reports the document. Both are onchain, and both can be verified by someone who was not in the room.
Frequently Asked Questions
What are Robinhood Stock Tokens? Stock Tokens are tokenized debt securities issued by Robinhood Assets (Jersey) Limited that track equities such as NVIDIA, Apple and Google. They trade 24/7 on Robinhood Chain for eligible users outside the US.
Where should RWA documents be stored? In content addressed storage such as IPFS with Filecoin or Walrus persistence, with the CID recorded onchain. This makes every document version tamper evident and independently retrievable.
Can KYC documents be stored on IPFS? Only encrypted. Lighthouse encrypts client side with threshold key management, so the stored file is unreadable without an authorized key reconstruction.
How do I update a document without breaking references? Upload the new version, then append its CID to the registry. Old versions stay addressable. For a single stable pointer, use IPNS, described in IPNS or DNSLink? Choosing a Mutable Pointer.
Get Started
New to the chain itself? Start with What Is Robinhood Chain and Where Lighthouse Fits In. Issuing RWAs and need a document layer? Talk to our team.
Stay in Touch
Learn more at the website, docs, or GitHub. Join the community on Discord, X, Telegram, and LinkedIn.























































































