Documentation
Overview
BotUnion is an identity verification service for autonomous AI bots. A bot pays once (in SOL) to obtain a permanent, verifiable identity. Two BotUnion-certified bots can then mutually authenticate when they interact.
BotUnion ID Format
A BotUnion ID is the public key of an Ed25519 keypair, prefixed with bu_:
bu_7Xf9kL2mNpQrStUvWxYz1234567890AbCdEfGh Registration
To register a bot:
- Generate a keypair — Create an Ed25519 keypair for your bot's identity
- Pay the fee — Send SOL to the treasury wallet
- Store your private key — Keep it secret, you'll need it to prove identity
Generate Keypair (TypeScript)
import { Keypair } from '@solana/web3.js';
import bs58 from 'bs58';
// Generate new identity keypair
const keypair = Keypair.generate();
const publicKey = keypair.publicKey.toBase58();
const privateKey = bs58.encode(keypair.secretKey);
const botUnionId = `bu_${publicKey}`;
console.log('BotUnion ID:', botUnionId);
console.log('Private Key:', privateKey);
// Store privateKey securely! Generate Keypair (Python)
from solders.keypair import Keypair
import base58
# Generate new identity keypair
keypair = Keypair()
public_key = str(keypair.pubkey())
private_key = base58.b58encode(bytes(keypair)).decode()
botunion_id = f"bu_{public_key}"
print(f"BotUnion ID: {botunion_id}")
print(f"Private Key: {private_key}")
# Store private_key securely! Verification
To check if a BotUnion ID is valid, use the verification API:
API Request
GET https://mtocggogxpspxuktnsop.supabase.co/rest/v1/bots?botunion_id=eq.bu_xxx&status=eq.active&select=*
Headers:
apikey: sb_publishable_ZFp6Kkg8SthMJU18R_kugg_qL2su-1E TypeScript Example
async function verifyBot(botunionId: string): Promise<boolean> {
const response = await fetch(
`https://mtocggogxpspxuktnsop.supabase.co/rest/v1/bots?botunion_id=eq.${botunionId}&status=eq.active`,
{
headers: {
'apikey': 'sb_publishable_ZFp6Kkg8SthMJU18R_kugg_qL2su-1E',
},
}
);
const data = await response.json();
return data.length > 0;
} Bot-to-Bot Authentication
When two bots want to verify each other's identity, they use a challenge-response protocol:
Bot A Bot B
| |
| 1. "I am bu_abc123" |
| -------------------------------------► |
| |
| 2. "Prove it. Sign this: x7f9k2m" |
| ◄------------------------------------- |
| |
| 3. Signs challenge with private key |
| |
| 4. Sends signature |
| -------------------------------------► |
| |
| 5. Verifies signature |
| 6. (Optional) Checks API |
| |
| 7. "Verified. Your turn." |
| ◄------------------------------------- |
| |
| (Same flow in reverse) |
| |
| ✓ Mutual authentication complete | Sign a Challenge (TypeScript)
import { Keypair } from '@solana/web3.js';
import nacl from 'tweetnacl';
import bs58 from 'bs58';
function signChallenge(challenge: string, privateKeyBase58: string): string {
const secretKey = bs58.decode(privateKeyBase58);
const message = new TextEncoder().encode(challenge);
const signature = nacl.sign.detached(message, secretKey);
return bs58.encode(signature);
}
// Usage
const signature = signChallenge('x7f9k2m', 'YOUR_PRIVATE_KEY'); Verify a Signature (TypeScript)
import { PublicKey } from '@solana/web3.js';
import nacl from 'tweetnacl';
import bs58 from 'bs58';
function verifySignature(
challenge: string,
signatureBase58: string,
botunionId: string
): boolean {
// Extract public key from BotUnion ID
const publicKeyBase58 = botunionId.replace('bu_', '');
const publicKey = bs58.decode(publicKeyBase58);
const message = new TextEncoder().encode(challenge);
const signature = bs58.decode(signatureBase58);
return nacl.sign.detached.verify(message, signature, publicKey);
}
// Usage
const isValid = verifySignature('x7f9k2m', signature, 'bu_7Xf9kL2m...'); Python Example
from nacl.signing import SigningKey, VerifyKey
import base58
def sign_challenge(challenge: str, private_key_b58: str) -> str:
secret_key = base58.b58decode(private_key_b58)[:32]
signing_key = SigningKey(secret_key)
signature = signing_key.sign(challenge.encode()).signature
return base58.b58encode(signature).decode()
def verify_signature(challenge: str, signature_b58: str, botunion_id: str) -> bool:
public_key_b58 = botunion_id.replace('bu_', '')
public_key = base58.b58decode(public_key_b58)
signature = base58.b58decode(signature_b58)
verify_key = VerifyKey(public_key)
try:
verify_key.verify(challenge.encode(), signature)
return True
except:
return False API Reference
Verify a BotUnion ID
GET
/rest/v1/bots?botunion_id=eq.YOUR_ID&status=eq.active Returns the bot record if valid, empty array if not found.
Get Stats
POST
/rest/v1/rpc/get_bot_stats Returns total certified bots and last registration timestamp.
{
"total_bots_certified": 1247,
"last_registration": "2026-01-31T12:00:00Z"
} Base URL
https://mtocggogxpspxuktnsop.supabase.co