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:

  1. Generate a keypair — Create an Ed25519 keypair for your bot's identity
  2. Pay the fee — Send SOL to the treasury wallet
  3. 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