Skip to content

Repository files navigation

StateSet AdGrid

Stablecoin-Native Commerce Advertising Infrastructure

AdGrid is a programmable advertising platform where every ad is an executable commerce intent. Companies purchase QR-code placements (AdSlots) at physical and digital locations. Consumers scan codes to instantly purchase products, settling in USDC/USDT via the StateSet payment rails. StateSet collects a 3% protocol fee on every settled transaction.

No impressions. No clicks. No chargebacks. Just scan, settle, done.

How It Works

┌─────────────┐     ┌──────────────┐     ┌─────────────────┐     ┌────────────────┐
│  Merchant    │     │   AdGrid     │     │   Consumer      │     │  Settlement    │
│  creates     │────▶│   generates  │────▶│   scans QR      │────▶│  Engine splits │
│  campaign    │     │   signed QR  │     │   one-tap buy   │     │  97% / 3%      │
└─────────────┘     └──────────────┘     └─────────────────┘     └────────────────┘
  1. Merchant creates a campaign with commerce offers and bids on ad slots
  2. AdGrid runs a Generalized Second-Price auction and generates Ed25519-signed QR codes
  3. Consumer scans a QR code and authorizes a stablecoin purchase
  4. Settlement Engine atomically splits payment: 97% to merchant, 3% to protocol treasury

Architecture

AdGrid is built as a Rust workspace with seven crates:

Crate Purpose
stateset-adgrid-core Domain types — AdSlot, AdCampaign, CommerceOffer, SettlementSplit, QrPayload
stateset-adgrid-qr Ed25519-signed QR payloads, PNG/base64 encoding, nonce replay protection
stateset-adgrid-auction GSP auction engine — highest bid wins, pays second price + $0.01
stateset-adgrid-settlement Multi-party USDC/USDT settlement, escrow, refunds
stateset-adgrid-analytics Deterministic on-chain attribution, scan-to-settle funnel, ROAS
stateset-adgrid-api Axum REST API with 14 endpoints
stateset-adgrid-agent AI agent interface with NSR primitives for autonomous ad management

Quick Start

# Build
cargo build

# Run tests
cargo test

# Start the API server
cargo run --bin adgrid-server

# Server binds to 0.0.0.0:8080 by default
# Override with ADGRID_BIND=127.0.0.1:3000

Dashboard

The operator dashboard lives in dashboard/ and targets Node 22.12.0 via .nvmrc.

cd dashboard
npm ci
npm run lint
npm run build

Set VITE_ENABLE_DEMO_DATA=true only when you intentionally want seeded demo records in the UI. The first dashboard screen now bootstraps a merchant session directly from the API:

  • Create a new merchant with a browser-generated Ed25519 keypair
  • Import an existing merchant ID and private key to restore access
  • Export the active merchant session from the top bar for secret backup

API Reference

All endpoints are under /v1. Authentication is via Ed25519 signature headers.

Campaigns

POST   /v1/campaigns              Create a campaign with escrowed USDC budget
GET    /v1/campaigns/{id}         Get campaign details and real-time analytics
POST   /v1/campaigns/{id}/offers  Add a commerce offer to a campaign

Slots & Auctions

POST   /v1/slots                  Create an ad slot (physical or digital)
GET    /v1/slots                  Query available slots by location and time
POST   /v1/slots/{id}/bid         Submit or update a bid for an ad slot

QR Codes

POST   /v1/qr/generate            Generate a signed QR code for a commerce offer
POST   /v1/qr/verify              Verify and decode a scanned QR payload

Settlement

POST   /v1/settle                  Execute a stablecoin settlement for a purchase
POST   /v1/refunds                 Initiate a refund through escrow release

Analytics

GET    /v1/analytics/campaign/{id} Campaign performance: scans, conversions, revenue, ROAS
GET    /v1/analytics/platform      Platform-wide metrics: GMV, protocol revenue, utilization

Agent Discovery

GET    /v1/agent/capabilities      Machine-readable tool catalog for external AI agents
GET    /.well-known/agent.json     Public discovery manifest for agent runtimes
POST   /v1/agent/recommendations   Generate preview-safe next actions for a merchant or campaign
POST   /v1/agent/preview           Dry-run one primitive and inspect the derived outcome without mutating state
POST   /v1/agent/execute           Execute one NSR primitive with Ed25519-authenticated merchant context
GET    /v1/agent/actions           List recent agent actions executed for the authenticated merchant
GET    /v1/agent/context           Load merchant balance, campaigns, offers, auctions, and recent actions in one response

Merchants

POST   /v1/merchants               Onboard a new merchant
GET    /v1/merchants/{id}/balance   Merchant stablecoin balance and pending settlements

Fee Structure

Fee Rate Payer When
Protocol Transaction Fee 3.00% Consumer (included in price) On every QR-initiated purchase
Slot Auction Fee 5.00% of clearing price Winning Merchant On auction settlement
Merchant Onboarding Free Account creation
Refund Processing 0.50% Merchant On refund execution

QR Payload Security

Every QR code is a cryptographically signed commerce intent, not a simple URL:

  • Ed25519 signatures — payload is signed with the merchant's private key and verified before any settlement
  • Nonce-based replay protection — each QR code contains a unique 32-byte nonce, consumed on settlement
  • Time-bounded expiry — payloads expire after a configurable window (default 60 minutes)
  • Atomic settlement — all-or-nothing execution prevents partial state
pub struct QrPayload {
    pub version: u8,
    pub offer_id: OfferId,
    pub merchant_id: MerchantId,
    pub price_usdc: Decimal,
    pub slot_id: AdSlotId,
    pub nonce: [u8; 32],
    pub expiry: DateTime<Utc>,
    pub signature: Ed25519Signature,
}

Auction Engine

Slots are allocated via continuous Generalized Second-Price (GSP) auctions:

  • Bid currency: USDC, escrowed on submission
  • Time granularity: 1-hour minimum slots
  • Reserve price: Set per-slot by location owner
  • Winner determination: Highest bid wins, pays second price + $0.01
  • Auction fee: 5% of clearing price to protocol treasury

AI Agent Interface

AdGrid exposes operations as Neuro-Symbolic Reasoning (NSR) primitives for autonomous campaign management:

CreateCampaign(merchant, products, budget)     — Analyze catalog, generate offers, set budgets
AdjustBid(campaign, slot, target_roas)         — Monitor auctions, optimize bids for ROI targets
OptimizeOffer(offer, metric, constraint)       — A/B test pricing, adjust discounts
DetectAnomaly(campaign, window, threshold)     — Flag unusual scan patterns, potential fraud
ReallocateBudget(campaign, performance_data)   — Shift budget to high-converting slots
GenerateReport(campaign, period, format)       — Human-readable performance reports

External agent runtimes can discover and call these primitives without scraping docs:

curl http://127.0.0.1:8080/.well-known/agent.json

Each signed execution request wraps exactly one primitive:

{
  "merchant_id": "merchant-uuid",
  "primitive": {
    "AdjustBid": {
      "campaign_id": "campaign-uuid",
      "slot_id": "slot-uuid",
      "target_roas": "3.00",
      "auto_apply": false
    }
  }
}

The merchant_id in the body must match the X-Merchant-Id header used for Ed25519 request signing. For retry safety, agents should also send X-Idempotency-Key on POST /v1/agent/execute; AdGrid will replay the cached action response for 24 hours instead of applying the primitive twice. Agents can call POST /v1/agent/preview with the same request body before execution; preview forces auto_apply and auto_pause off, and execution now re-checks campaign and offer ownership against the authenticated merchant instead of trusting embedded IDs inside the primitive.

When the next step is unclear, agents can ask AdGrid for a plan first:

{
  "merchant_id": "merchant-uuid",
  "strategy": "Balanced",
  "limit": 4
}

The planner returns executable requests for preview-safe primitives such as AdjustBid, OptimizeOffer, DetectAnomaly, and GenerateReport. Executed actions are then available through GET /v1/agent/actions.

Agents that need working state before planning or execution can hydrate a merchant-scoped context snapshot first:

curl -H "X-Merchant-Id: merchant-uuid" \
     -H "X-Timestamp: 1710000000" \
     -H "X-Signature: <hex>" \
     "http://127.0.0.1:8080/v1/agent/context?campaign_limit=6&offer_limit_per_campaign=3&auction_limit=8&action_limit=6"

The context response includes the authenticated merchant's balance, recent campaigns with offer snapshots, open-auction summaries, and recent agent actions so external runtimes can decide on the next primitive without making a half-dozen separate API calls.

Agent-created offers now start from a category-based baseline price instead of 0, so downstream optimization primitives can refine real price points immediately.

Auction bid history is merchant-scoped: GET /v1/slots/{id}/bids returns the authenticated merchant's bids plus market-level summary fields, rather than exposing every bidder on the slot.

Core Metrics

Metric Definition
Scan Rate QR scans per impression-hour per slot
Scan-to-Settle Rate % of scans that result in completed purchases
Gross Merchandise Volume Total USDC settled through AdGrid
Protocol Revenue 3% of GMV collected by StateSet
ROAS (merchant revenue − slot cost) / slot cost
Time-to-Settle Median time from QR scan to settlement finality
Slot Utilization % of available slot-hours occupied by campaigns

Why AdGrid

Dimension Legacy Ad Platforms AdGrid
Revenue Model CPM / CPC (impression-based) 3% on settled commerce only
Settlement Speed Net-30/60 advertiser billing Sub-second stablecoin finality
Attribution Probabilistic multi-touch Deterministic on-chain proof
Physical Commerce Limited Native QR-to-settle
AI Integration Black-box automated bidding Full NSR Engine autonomy
Fee Transparency Opaque interchange + processing Flat 3%, fully auditable

License

Apache-2.0


StateSet Inc. — San Francisco, CA

About

StateSet AdGrid

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages