πŸ” BTSBots Decentralized Identity (DID) OAuth Developer Guide

This document details how third-party merchants can integrate BTSBots Decentralized Identity (DID) authentication using BitShares blockchain accounts and ECDSA signatures.


βš™οΈ 1. OAuth Workflow Architecture

[ User Browser / PC ] ------ (1) Initiate Login / Show QR -------> [ Merchant Web Site ]
        |                                                                 |
 (2) Redirect to OAuth                                            (3) Poll Login Status
     or Scan with Mobile App                                              |
        v                                                                 v
[ BTSBots Client / Web ] - (4) Sign Intent via WebCrypto -> [ BTSBots DDP Cloud Server ]
                                                                          |
 (5) Fetch & Verify Signature                                             v
[ Merchant BizBots Daemon ] <---- (6) HTTP POST Push Signed Proof --------+

πŸ› οΈ 2. Option A: Zero-Code Proxy Mode with biz_proxy.py (Recommended)

1. Mandatory biz_rules.json Configuration

Crucial Note: When using biz_proxy, merchants MUST STILL configure biz_rules.json to point the oauth_endpoint URL directly to the /biz-proxy/sync-login endpoint provided by biz_proxy.py:

{
  "description": "BTSBots OAuth Rules",
  "updated_at": "2026-08-12 19:54:52",
  "oauth_endpoint": {
    "my-shop.com": "https://my-shop.com/biz-proxy/sync-login"
  }
}

2. Start biz_proxy.py

uv run python biz_proxy.py \
  --host 127.0.0.1 \
  --port 9000 \
  <merchant_bts_account> \
  <merchant_bts_pubkey>

πŸ’» 3. Option B: Custom Web API Callbacks

1. Configure biz_rules.json

{
  "description": "Merchant App OAuth Rules",
  "updated_at": "2026-08-12 20:00:00",
  "oauth_endpoint": {
    "my-shop.com": "https://api.my-shop.com/v1/auth/bts-callback"
  }
}

2. Python Verification Example (FastAPI)

import json
import time
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from btsbots.graphene_light import verify_message as bts_verify_message

app = FastAPI()

TRUSTED_BIZ_BOT_PUBKEY = "BTS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"

class OAuthCallbackPayload(BaseModel):
    data: str
    pubkey: str
    signature: str

@app.post("/v1/auth/bts-callback")
async def bts_oauth_callback(payload: OAuthCallbackPayload):
    if payload.pubkey != TRUSTED_BIZ_BOT_PUBKEY:
        raise HTTPException(status_code=403, detail="Untrusted public key source")

    if not bts_verify_message(payload.data, payload.signature, payload.pubkey):
        raise HTTPException(status_code=400, detail="Invalid cryptographic signature")

    auth_info = json.loads(payload.data)
    username = auth_info.get("username")
    token = auth_info.get("token")
    auth_time = auth_info.get("time")

    if abs(time.time() - auth_time) > 300:
        raise HTTPException(status_code=400, detail="Authorization request expired")

    print(f"πŸŽ‰ User {username} logged in successfully via BitShares DID! Token: {token}")

    return {"status": "success", "username": username}