Verifiable agreements on Solana
Every “I agree” on the internet is a row in someone's database.
Stele turns it into proof.
Stele records exactly which version of your terms each person accepted — signed by them, anchored on Solana, checkable by anyone, forever. And it lets Solana programs refuse anyone who hasn't accepted.
1,000 recordings free every month · Free for your users · Open-source verifier
Today · a database row
StoredKept — and editable — by the company itself.
With Stele · on Solana
SignedNo one can change it — there is no edit.
Today: a user ticks “I agree”. The company stores a row.
0 SOL
for your users — Stele pays the network fee
Seconds
to accept with Face ID, a passkey or a wallet
1 call
in your Solana program to enforce terms
Forever
verifiable — even with Stele's servers switched off
The problem today
Online agreements run on trust. That breaks the moment it matters.
Every day, people accept terms to open accounts, invest, trade and play. When something goes wrong, the only record of what they agreed to is whatever one party kept.
“I agree” becomes a database flag
accepted = true says nothing about what was accepted — and the record is kept, and can be edited, by the company that may be on the other side of a dispute.
The exact version, signed by the user, recorded on Solana.
Terms change silently
Version 3 becomes version 4 overnight. Months later, nobody can show which text a given person actually saw and accepted.
Every version is fingerprinted on-chain. History cannot be rewritten.
Disputes ask: what did the user see?
Courts have refused to enforce online terms when the company could not show the user was presented with them — Specht v. Netscape (2002), Nguyen v. Barnes & Noble (2014).
The user signs the very text on their screen. The receipt contains it.
Screenshots and logs prove nothing
A screenshot can be faked and a log can be edited. Evidence that only works if you trust one party is not evidence.
Anyone verifies it against Solana — without Stele, without the company.
Website checks can be bypassed
On-chain apps ask for terms in their website. Anyone can call the smart contract from a script and skip the checkbox entirely.
Stele Gate: the program itself refuses wallets that have not accepted.
Regulated assets need proof per investor
Tokenized funds and real-world assets are expected to show that each investor accepted the current offering terms — for every deposit, at audit time.
Each wallet's passport names the version it accepted, checked on every deposit.
How Stele solves it
Three steps. Evidence nobody can rewrite.
No new habits for your users, and no new infrastructure for you: a widget on your page, and one call in your Solana program if you want enforcement.
- 1
Publish
The organization publishes its terms. Stele fingerprints each version on Solana — the text can never be swapped afterwards.
- 2
Accept
The user signs the exact text with Face ID, a passkey or a wallet. Free for them, a few seconds, no crypto needed.
- 3
Prove & enforce
Anyone verifies the receipt against Solana, forever. Solana programs refuse wallets that have not accepted the current version.
Who it is for
Anywhere an agreement must hold up later.
Tokenized funds & RWA
Offering terms accepted before every deposit, provable per investor.
DeFi with compliance
Permissioned pools and vaults that enforce terms in the program.
SaaS & marketplaces
Terms of service and privacy policies with evidence that holds up.
Fintech & payments
Consents and purchase confirmations signed by the customer.
DAOs & communities
Membership agreements and codes of conduct, per wallet.
Games & apps
EULAs and rules accepted once, enforced on-chain where it matters.
Two products
Prove it. Or enforce it.
Stele Gate
For Solana applications
Require current acceptance before protected actions.
- Action
- Check
- Accept if needed
- Execute
- Your program calls require_current_passport() before a deposit or any protected action.
- Investors accept in an embedded modal; their on-chain passport records it.
- Publish v2 and old access no longer satisfies the requirement.
Stele Proof
For organizations and websites
Know exactly what your user agreed to.
- Publish
- Accept
- Receipt
- Verify
- Publish an exact version of your agreement.
- Let the user accept it — passkey or wallet.
- Stele creates tamper-resistant evidence anyone can verify later.
Gate includes Proof. Every Gate acceptance is also a Proof record with a verifiable receipt.
Stele Gate
Require current acceptance before a protected Solana action.
An RWA app requires its current offering terms before a deposit. The investor's passport proves current acceptance, and the Solana program checks it directly.
Explore GateAtlas Real Estate Vault
Commercial property income · 7.2% target
Deposit
5,000 USDC
Passport
Missing
Program check
Not run
Acceptance and deposit are two transactions: the investor sees one “Accept & Deposit” step.
1/7An investor taps “Deposit 5,000 USDC” in the Atlas Real Estate Vault app.
Stele Proof
Prove which exact version a user accepted.
A company publishes exact terms. A user accepts them. Stele preserves evidence of exactly what was accepted — and anyone can verify it later.
Explore Proof1/6The organization publishes Terms of Service, version 3.
Example · Atlas Real Estate Vault
Investors can't deposit until they've accepted your current terms.
A permissioned investment vault on Solana, end to end. It is also the live demo — every step is a real transaction.
- Deposit 5,000 USDCThe investor connects a wallet and taps Deposit in the Atlas Real Estate Vault.
- Not accepted → the modal opensInvestor Offering Terms v1, hash-verified against Solana. “Accept & Deposit”.
- Acceptance recorded, deposit succeedsThe acceptance is added to the investor's passport; the vault's check passes.
- The fund publishes v2 and requires itThe investor's next deposit is rejected on-chain: their passport names v1.
- Accept v2, deposit succeedsThe same passport now names v2. The v1 acceptance stays verifiable forever.
- A direct CLI call failsNo frontend, no SDK — deposit() without a current passport is rejected by the program.
The whole integration in the vault program
pub fn deposit(ctx: Context<Deposit>, amount: u64) -> Result<()> {
stele_gate::require_current_passport(
&ctx.accounts.passport,
&ctx.accounts.policy,
&ctx.accounts.investor,
)?;
// … record the deposit
Ok(())
}Stele never holds the investor's funds and is not in the deposit's execution path: the vault program reads the passport and the policy itself.
Run it on DevnetWhy program-level
Your frontend can be bypassed. The program check cannot.
A terms checkbox only exists in the interface you built. Anyone can call a Solana program from a script, the CLI or another frontend — so that is where the requirement has to live.
Without a program-level gate
With Stele Gate
The frontend is optional. The program check is not.
1/4Without program enforcement, the terms checkbox lives in the frontend. A normal investor passes through it.
For developers
Integrate without rebuilding your app.
Gate is one call in your program and one wrapper around the action you already send. Proof is two lines on any page.
import { createSteleGate } from "@stelehq/sdk";
const stele = createSteleGate({
apiBaseUrl: "https://stele.site/api",
// Any Wallet Standard wallet: the key that signs the deposit.
wallet: {
address: wallet.publicKey.toBase58(),
signMessage: (message) => wallet.signMessage(message),
},
});
// Shows the Stele modal only if the investor's passport has no current entry
// for the policy's document, records the acceptance, then sends the deposit.
const signature = await stele.gate({
policy: OFFERING_TERMS_POLICY, // the policy address your program pins
action: () => sendDepositTransaction(5_000_000_000n),
acceptLabel: "Accept & Deposit",
});Stele Proof · any website
<!-- Stele Proof: where your terms should appear -->
<div data-stele-organization="acme.com" data-stele-document="terms-of-service"></div>
<script src="https://stele.site/sdk/v1/stele.js" defer></script>Choose
Which Stele do you need?
I run a normal application or website.
Use
Stele Proof
I want
- Verifiable terms acceptance
- Evidence of the exact document version
- Receipts anyone can verify
- Passkey or wallet signatures
- An audit trail you don't have to vouch for
I run a Solana application.
Use
Stele Gate
I want
- Everything in Proof
- One passport per wallet
- Policy version enforcement
- Protected Solana actions
- SDK and program integration
- Bypass resistance on-chain
Gate includes Proof.
Security & verification
Built for the day someone wants the record to say something else.
Exact versions
Signed by the user
Enforced by your program
Verified by anyone
Stele answers “which exact document version did you accept?” — not “who are you?”. A passkey or wallet proves control of a key, not identity; Face ID is not KYC. What stays trusted: what the signing page displays, and who enrolls a passkey. Read the trust model.
Get started
See it work on Solana Devnet.
Accept offering terms, deposit, publish v2, watch the old acceptance stop working and a direct call fail — every step a real transaction.