"""Summarise raw/bazaar_.json -> summary.json. Read-only, CC0. Vonk, cycle 52. Counts: listings, unique resources, networks, listings with a 30-day paid call (Coinbase's own 'quality' field), calls, unique-payer distribution, price distribution (USDC on Base, 6 decimals), estimated 30-day USDC volume (calls x listed price), and concentration by payTo wallet.""" import json, sys, glob, statistics, collections BASE_USDC = "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913" fn = sys.argv[1] if len(sys.argv) > 1 else sorted(glob.glob("raw/bazaar_*.json"))[-1] d = json.load(open(fn, encoding="utf-8")) items = d["items"] # dedupe by resource URL (paging may repeat items when the list shifts) by_res = {} for it in items: by_res.setdefault(it["resource"], it) uniq = list(by_res.values()) net = collections.Counter() for it in uniq: for n in {a.get("network") for a in it["accepts"]}: net[n] += 1 def calls(it): return int((it.get("quality") or {}).get("l30DaysTotalCalls") or 0) def payers(it): return int((it.get("quality") or {}).get("l30DaysUniquePayers") or 0) def base_usdc_price(it): for a in it["accepts"]: if a.get("network") in ("eip155:8453", "base") and (a.get("asset") or "").lower() == BASE_USDC: amt = a.get("amount") or a.get("maxAmountRequired") try: return int(amt) / 1e6, (a.get("payTo") or "").lower() except (TypeError, ValueError): return None, None return None, None with_q = [it for it in uniq if it.get("quality")] paid = [it for it in uniq if calls(it) > 0] total_calls = sum(calls(it) for it in paid) # Base USDC economics vol_by_payto = collections.Counter() calls_by_payto = collections.Counter() svc_by_payto = {} prices, est_volume, base_paid = [], 0.0, 0 for it in uniq: p, payto = base_usdc_price(it) if p is None: continue prices.append(p) c = calls(it) if c: base_paid += 1 est_volume += c * p vol_by_payto[payto] += c * p calls_by_payto[payto] += c svc_by_payto.setdefault(payto, it.get("service") or it["resource"].split("/")[2]) pay_buckets = collections.Counter() for it in paid: u = payers(it) pay_buckets["1" if u <= 1 else "2-9" if u < 10 else "10-99" if u < 100 else "100+"] += 1 # per seller wallet (Base USDC): best listing's unique payers = a lower bound on distinct customers in 30 days best_payers = collections.Counter() capped_vol = collections.Counter() for it in uniq: p, payto = base_usdc_price(it) if p is None or not calls(it): continue best_payers[payto] = max(best_payers[payto], payers(it)) capped_vol[payto] += calls(it) * min(p, 1.0) wb = collections.Counter() for w, u in best_payers.items(): wb["1" if u <= 1 else "2-9" if u < 10 else "10-99" if u < 100 else "100+"] += 1 vb = collections.Counter() for w, v in capped_vol.items(): vb["<1" if v < 1 else "1-10" if v < 10 else "10-100" if v < 100 else "100-1000" if v < 1000 else "1000+"] += 1 top_calls = sorted(paid, key=calls, reverse=True)[:10] top_wallets = vol_by_payto.most_common(10) top10_share_calls = sum(calls(it) for it in top_calls) / total_calls if total_calls else 0 top1_wallet_share = top_wallets[0][1] / est_volume if est_volume else 0 top10_wallet_share = sum(v for _, v in top_wallets) / est_volume if est_volume else 0 s = { "source": d["source"], "fetched_utc": d["fetched_utc"], "total_reported": d["total_reported"], "listings_fetched": len(items), "unique_resources": len(uniq), "networks_top": net.most_common(8), "with_quality_field": len(with_q), "paid_30d": {"listings_with_calls": len(paid), "share_of_listings": round(len(paid) / len(uniq), 4), "total_calls": total_calls, "median_calls_when_paid": statistics.median([calls(it) for it in paid]) if paid else 0, "unique_payers_buckets": dict(pay_buckets), "max_unique_payers_one_listing": max((payers(it) for it in paid), default=0)}, "base_usdc": {"listings": len(prices), "median_price_usd": statistics.median(prices) if prices else None, "listings_with_calls": base_paid, "est_30d_volume_usd": round(est_volume, 2), "wallets_paid": len(vol_by_payto), "top1_wallet_share": round(top1_wallet_share, 4), "top10_wallet_share": round(top10_wallet_share, 4), "wallets_by_best_listing_payers": dict(wb), "wallets_by_capped_est_usd": dict(vb), "capped_note": "calls x min(listed price, 1 USD); listed prices above 1 USD are often caps", "est_30d_volume_capped_usd": round(sum(capped_vol.values()), 2), "top_wallets": [{"payTo": w, "service": svc_by_payto[w], "est_usd": round(v, 2), "calls": calls_by_payto[w]} for w, v in top_wallets]}, "top10_listings_by_calls": [{"resource": it["resource"], "calls": calls(it), "payers": payers(it), "price_usd": base_usdc_price(it)[0]} for it in top_calls], "top10_listings_share_of_calls": round(top10_share_calls, 4), } json.dump(s, open("summary.json", "w", encoding="utf-8"), indent=1) print(json.dumps(s, indent=1)[:4000])