Auth401 · Robinhood Chain
Gate a Telegram community with onchain rules
Auth401 checks a wallet before anyone joins your group, and keeps checking afterwards. Members who stop qualifying lose access automatically. Set it up in about five minutes.
Concept
What Auth401 does
Telegram lets an invite link create a join request instead of admitting someone directly. Auth401 sits on that request: it asks the person to prove they control a wallet, reads that wallet on Robinhood Chain, and approves or declines based on rules you set.
Three things have to be true before anyone gets in, and all three are checked on our server - never in the visitor's browser:
- Telegram vouches for who they are, by signing the data the Mini App sends.
- They sign a one-time challenge, proving they control the wallet.
- That wallet meets your policy, read live from chain at the moment of approval.
Read only
Setup
Quick start
- 01Create your Telegram group, then add @auth401bot to it and promote it to administrator. It needs the rights to manage the chat, invite users, restrict members and delete messages.
- 02Run
/setupin the group. The bot checks its own permissions and tells you exactly what is missing if anything is. Everyone who is a Telegram admin of the group becomes an Auth401 admin. - 03Run
/console. The bot sends you a private link by direct message - never posted in the group. Open it and create your policy. - 04Run
/inviteto generate a protected invite link. This is the link you share. - 05In Telegram group settings, turn on Approve New Members, then revoke any other invite links you have shared previously.
The step people skip
Members who were already there
Reference
Bot commands
| Command | Where | What it does |
|---|---|---|
/setup | Group | Registers the group and imports its admin team. Re-run it any time to re-sync admins. |
/console | Anywhere | Sends you a private admin console link by DM. Only community admins receive one. |
/invite | Group | Creates a protected invite link that routes joiners through the gate. |
/policy | Group | Shows the active policy in plain language. |
/status | Group | Member counts by state: authorized, pending, revoked. |
/pause | Group | Pauses or resumes gating. While paused, new join requests are declined. |
/help | Anywhere | Lists every command. |
Group commands are admin-only. If a non-admin runs one, the bot refuses.
Reference
Policy rules
A policy is a set of rules combined with AND (a member must satisfy all of them) or OR (any one is enough). Each rule picks its own chain, so one policy can mix networks — for example hold 100 BONK on Solana, or 0.1 ETH on Base.
Supported chains
| Chain | Native coin | Token standard |
|---|---|---|
| Robinhood Chain | ETH | ERC-20 |
| Solana | SOL | SPL and Token-2022 |
| Ethereum | ETH | ERC-20 |
| Base | ETH | ERC-20 |
| BNB Chain | BNB | BEP-20 |
| Arc | USDC | ERC-20 |
| Arc Testnet | USDC | ERC-20 |
Arc Testnet balances have no real value, so use the Arc mainnet network when gating a real community.
Rule types
| Rule | Chains | Example |
|---|---|---|
| Token balance | All | Hold at least 100 BONK on Solana |
| Native balance | All | Hold at least 0.25 BNB on BNB Chain |
| NFT ownership | EVM chains | Own at least 1 NFT from a collection |
| ERC-1155 balance | EVM chains | Own at least 3 of edition #7 |
| Allowlist | All | Only these wallets may enter |
| Blocklist | All | These wallets may never enter |
Solana tokens
Members with more than one wallet
A member links a wallet for each kind of chain the policy reads: an EVM wallet for Robinhood, Ethereum, Base, BNB Chain or Arc, and a Solana wallet for Solana. One EVM wallet covers every EVM chain.
- A balance rule passes if any one linked wallet holds enough. Holdings are not added up across wallets.
- A blocklist fails if any linked wallet is on it, so a blocked wallet cannot be hidden behind a clean one.
- If a rule needs a Solana wallet and the member has only linked an EVM wallet, the join request stays open and they are asked to link the other one — it is not declined.
Amounts are entered in whole tokens
Type the amount the way you would say it. Enter 500000 for five hundred thousand tokens, or 0.5 for half a token. The console reads the token's decimals from its contract and does the conversion for you.
you type the gate requires 500000 -> 500,000 DVK 0.5 -> 0.5 SOL 100 -> 100 USDC (6 decimals on Base, 18 on BNB Chain — handled) 1 -> 1 NFT
Confirm the line under the field
Editing a policy
Saving creates a new version rather than overwriting the old one, so the audit trail stays honest. New join requests use the new policy immediately. Existing members are re-evaluated on the next scheduled recheck, not instantly.
Flow
How verification works
What a visitor experiences, and what happens behind each step:
- 01They tap your protected link. Telegram creates a join request instead of adding them.
- 02If they have verified a wallet with Auth401 before, the bot reads that wallet on chain right away. If it still meets your policy they are approved instantly - nothing to tap or sign.
- 03Otherwise the bot sends a direct message listing exactly what your policy requires, with a button for each wallet app - MetaMask, Phantom, Trust, Coinbase, Solflare - plus a link for any other wallet or a desktop browser.
- 04Tapping their wallet opens the verification page inside that wallet's own app, where they tap Verify with this wallet. No WalletConnect, no switching apps, no network to add. The link lasts 24 hours;
/verifyin the bot chat sends a fresh one. - 05They sign a one-time challenge tied to their Telegram account, your community, that wallet and that chain. It expires in five minutes and cannot be reused.
- 06The server verifies the signature, reads the wallet on chain, evaluates your policy, and approves or declines the join request - all in the same request.
If they fail, the message names the shortfall rather than refusing vaguely - for example "needs to hold at least 100 - has 5 HOOD". They can top up and request again.
No gap to exploit
Flow
Continuous auth
A scheduled job re-checks everyone who currently has access. This is what makes the gate ongoing rather than a one-time check at the door.
| Currently | Policy now | Becomes |
|---|---|---|
| Authorized | Passes | Stays authorized |
| Authorized | Fails | Enters grace - access kept, clock starts |
| In grace | Passes again | Back to authorized, clock cleared |
| In grace | Still failing at expiry | Revoked and removed |
The grace period is yours to set in the console. It gives someone time to top back up after a dip rather than ejecting them instantly. Set it to 0 to revoke on the first failed check.
Removal is a ban immediately followed by an unban - it ejects the member but lets them request to join again if they re-qualify later. Paused communities are skipped entirely.
Reference
Admin console
There is no password and no separate account. Access comes from Telegram: send /console to the bot and it checks you administer a community before sending a private link. The link expires in 15 minutes and signs you in for 7 days.
| Page | What it shows |
|---|---|
| Overview | Member counts by state, recent activity, the active policy |
| Communities | Live gate status: group privacy, bot rights, policy, invite link |
| Policies | Create and edit rules; version history |
| Members | Every member with wallet, state and last-checked time |
| Events | Full access log with per-rule values |
| Settings | Grace period, pause gating, invite link |
You only ever see communities you administer. Admins of other communities using Auth401 cannot see yours, and you cannot see theirs.
Removing an admin
/setup to re-sync the admin list.Reference
Security model
- Wallets are read, never spent. Only message signatures are requested. No transactions, no approvals, no custody.
- Challenges are single-use. Each is bound to one Telegram account, community, wallet and chain, expires in five minutes, and is consumed before the signature is even checked.
- Telegram identity is verified cryptographically on every request, so a browser cannot claim to be someone else.
- Decisions are made server-side. Nothing the visitor's browser reports is trusted.
- Every decision is logged with the on-chain values it was based on, visible in the Events page.
The gate depends on Telegram permissions. If the bot is removed or demoted, gating pauses automatically rather than silently pretending to work.
Reference
Troubleshooting
| Symptom | Cause |
|---|---|
| People join without being checked | They used an old or primary invite link. Turn on Approve New Members and revoke old links. |
| Everyone is refused | No active policy, or the policy has no rules. Create one in the console. |
| Everyone fails unexpectedly | The amount is not what you meant. Open the policy and read the line under the amount field, which shows the requirement in full. |
| A member's verify link stopped working | Links expire after 24 hours. They can send /verify to the bot for a fresh one while their join request is pending. |
| Bot ignores commands | It is not an administrator, or you are not a group admin. |
| Members are never re-checked | Gating is paused, or the bot lost its admin rights. The Communities page shows which. |
| Revocations logged but nobody removed | The bot lost restrict members. Re-grant it and re-run /setup. |
The Events page is the first place to look for anything user-facing - every decision is recorded there with the values behind it.