Pattern: Every covenant settlement is a trade signal — the funding gives the BCH half, the spend reveals the EUR half + the oracle message (The Settlement Is the Signal). Network discovers price from real economic activity, not external speculation.
Oracle Architecture: The blockchain itself is the oracle. Covenant fundings (on-chain) + reputation-filtered VWAP (off-chain) = permissionless, censorship-resistant price discovery.
Purpose: Enable automatic refund on price drops using market prices from actual Asgaya trades, bootstrapped by Asgaya oracle until network matures.
⚠️ Phase (updated 2026-10-03): aspirational Phase 1+ — it may never be reached. This needs volume and worldwide adoption so trades are a constant trickle. The gate starts at the first organic merchant posting a listing on the bulletin board — far below the volume required. What we do now: document it, and design the Asgaya oracle so this upgrade is an easy rollout later — do not build it, and don’t let it feature-creep.
Problem: Auto-refund requires fast, reliable price feed, but:
Traditional solution: Subscribe to external oracles (Coinbase, Kraken, Bitstamp), calculate consensus, hope they stay online.
Asgaya solution:
Result:
Each trade flows through five steps, creating an on-chain price discovery mechanism:
Passive sellers independently decide their BCH prices:
// Isabel's app (passive seller)
async function updateListingPrice() {
// Isabel chooses: Query Kraken API
const krakenPrice = await fetchKraken('BCH/EUR');
const myPrice = krakenPrice * 1.005; // 0.5% markup
// Post to bulletin board
await updateBulletinBoard({
price: myPrice,
volume_available: 500
});
}
No coordination needed. Market emerges from individual decisions. Each seller chooses their own price source (Kraken, Coinbase, Bitstamp, or even Asgaya VWAP once mature).
When María requests payment info, Isabel sends the agreed price privately:
// Isabel → María (encrypted Nostr DM)
{
"type": "PAYMENT_INFO_RESPONSE",
"covenant_id": "abc123",
"price": 995, // EUR/BCH price
"amount_eur": 100.50, // Total EUR to pay
"amount_bch": 0.0107, // BCH to lock
"payment_method": "Bizum",
"account": "+34600123456",
"reference": "Elena142"
}
Price is known before covenant funded. Privately communicated.
María pays via Bizum. Isabel’s app detects payment, funds covenant:
// Isabel's app funds covenant (on-chain)
const covenantTx = await fundCovenant({
bch_amount: 0.0107,
eur_amount: 100, // Constructor param — P2SH32 hides it until the spend reveals it
recipient: elenaAddress,
expiry: expiryTime
});
// On-chain proof of trade execution
// Price derivable: €100 / 0.0107 BCH = €934.58/BCH
Blockchain consensus guarantees timestamp and trade occurred. Cannot be faked - requires real BCH + transaction fees.
Isabel’s app broadcasts trade signal to network:
// Isabel → Network (public Nostr channel)
nostr.publish('asgaya:market:bch-eur', {
"type": "TRADE",
"price": 995, // From payment instructions
"volume": 100, // EUR traded
"txid": covenantTx.txid, // On-chain proof
"seller_reputation": 98, // Isabel's current reputation
"timestamp": Date.now()
});
Real-time market transparency. Every trade visible to network. Reputation included → Network knows whether to trust this price signal.
All devices subscribe and calculate market price:
// Subscribe to market channel
nostr.sub('asgaya:market:bch-eur', (trade) => {
// Only trust high-reputation sellers
if (trade.seller_reputation >= 90) {
addToVWAPCalculation(trade);
} else {
console.log('Ignoring low-rep seller trade');
}
});
// Calculate volume-weighted average price (last hour)
const trustedTrades = trades.filter(t =>
t.timestamp > Date.now() - 3600000 &&
t.seller_reputation >= 90
);
const vwap = trustedTrades.reduce((acc, t) =>
acc + (t.price * t.volume), 0
) / trustedTrades.reduce((acc, t) => acc + t.volume, 0);
// Result: €994.33 (Asgaya network market price)
Sybil-resistant: Low-reputation sellers ignored. Volume-weighted: Big trades matter more. Decentralized: Every device calculates independently.
This five-step progression transforms each trade into a trusted price signal, creating market-wide consensus from individual economic activity.
The funding tx hides the trade; the spend reveals it. A covenant is P2SH32, so at funding only the script hash and the BCH amount are on-chain — the params (eurCents, initialBchPriceInCents, minPricePercent, the keys) are hidden. When the covenant is spent, the redeem script and the oracle message are revealed. So:
eurCents) and the oracle message (timestamp ‖ price).eur_amount // OP_RETURN sketch in §Step 3 — v2.6 carries no such output. The spend is what unlocks the meaning of the funding.)The split is the clean number — no math. Funding is the unreliable half: the seller locks ~107 % of the face (the buffer is baked in), so the funding amount can’t be read as a price. The settlement separates the trade from the buffer: output[0] = the BCH actually delivered for the EUR face, output[1] = the buffer/remainder back to the funder. And eurCents (revealed in the script) is the fee-excluded EUR notional — the seller’s fee lives off-chain (in the fiat payment), so it never muddies the on-chain number. The effective price is then simply eurCents / output[0] — the covenant computes it for us. The revealed script also carries initialBchPriceInCents (the quote the parties agreed at creation), so a settlement records both the agreed quote and the delivered amount.
Any outcome is a valid signal. The gate to a price is a real fiat↔BCH settlement, and every path is one:
| Path | What actually happened | How to read it |
|---|---|---|
claim / merchantCashout |
The recipient/merchant chose to receive | Voluntary delivery — the cleanest signal |
refund |
The sender paid fiat and the BCH returned to them | The sender bought BCH (a fallback settlement) |
abort |
Price moved past the buffer → BCH to the sender (+ H€ mint) | Fallback settlement |
sellerRecoverBuffer |
The funder recovers its buffer | Buffer recovery (not a sale) |
Weight voluntary delivery, not “number of witnesses”. A claim/cashout is worth more because someone chose the price — not because more parties signed (they all sign the same covenant terms, so they cannot attest a different number). Treat claim/merchantCashout as first-class signals; refund/abort as second-class (real, but forced).
Two caveats for whoever builds it:
eurCents / output[0] — is the trusted oracle’s own price, so the settlement confirms a trade at that price (real volume) rather than discovering a different one. The independent signal is the seller’s own quote — their bulletin-board listing (seller-set). The covenant’s initialBchPriceInCents is sender-set at creation (from the oracle today), so it is not yet that independent signal; recording a seller-set price inside the covenant is the funder-sets-the-price inversion (internal ui-rethink/20), revisited in Phase 1+.eurCents (amount disclosure — consistent with the §Privacy Model).The Asgaya-owned oracle that powers this bootstrap is documented in Asgaya Oracle Husk — it starts as development infrastructure (full control over price + time for testing) and graduates to the production bootstrap oracle at mainnet. Blockchain-as-oracle (this document) is the aspirational end state that lets the trusted signer retire.
Asgaya is the only passive seller:
// Asgaya acts as first seller
const asgayaTrades = await queryCovenantFundings(seller: 'asgaya');
// Every Asgaya trade sets initial price
// Example: 10 trades/day at €995/BCH → Network price: €995
// Asgaya oracle supplements (Kraken API)
setInterval(() => {
const krakenPrice = await fetchKraken('BCH/EUR');
nostr.publish('asgaya:oracle:asgaya', {
type: 'ORACLE_PRICE',
price: krakenPrice,
source: 'kraken',
timestamp: Date.now()
});
}, 60000); // Every minute
// Network price = 100% Asgaya (only source available)
Function: Asgaya provides liquidity + price discovery while network grows.
More sellers join, user trades appear:
// Hybrid price calculation
const asgayaTrades = getTradesFrom(seller: 'asgaya');
const userTrades = getTradesFrom(reputation: '>= 90', exclude: 'asgaya');
const networkVWAP = calculateVWAP([...asgayaTrades, ...userTrades]);
const asgayaOracle = getLatestOraclePrice('asgaya:oracle:asgaya');
// Weight based on user trade volume
const userTradeVolume = sum(userTrades.map(t => t.volume));
const weight = Math.min(userTradeVolume / 2000, 0.95); // Cap at 95%
const marketPrice = (networkVWAP * weight) + (asgayaOracle * (1 - weight));
// Example: €1,200 user volume/day → 60% user VWAP + 40% Asgaya oracle
Gradual transition: As user volume grows, network VWAP gains weight.
Network dominant, Asgaya oracle optional: At full maturity, user VWAP carries 95%+ weight; Asgaya oracle remains as a 5% sanity check or can shut down entirely.
Self-reliant: Network no longer needs Asgaya’s oracle. Fully decentralized price discovery.
Core principle: Users set prices, users provide oracle, users own the market.
What this means:
1. Sellers set their own prices
2. Users provide price discovery
3. Asgaya trains, then exits
This aligns with Asgaya’s philosophy:
The magic: More trades = better price discovery, cost per device stays constant.
Thin market, Asgaya oracle dominant
├─ Asgaya trades: 20/day (€2,000 volume)
├─ User trades: 10/day (€500 volume)
├─ Price: 80% Asgaya oracle + 20% user VWAP
└─ Bootstrap phase - network learning
VWAP stabilizing, hybrid weighting
├─ Asgaya trades: 50/day (€5,000 volume)
├─ User trades: 250/day (€15,000 volume)
├─ Price: 30% Asgaya oracle + 70% user VWAP
└─ Transition phase - network maturing
Network dominant, Asgaya optional
├─ Asgaya trades: 100/day (€10,000 volume)
├─ User trades: 2,900/day (€290,000 volume)
├─ Price: 5% Asgaya oracle + 95% user VWAP
└─ Mature phase - network self-reliant
Individual cost: Sellers broadcast 1 trade signal per trade (constant).
Network benefit: Price discovery improves with every new seller.
const REPUTATION_TIERS = {
ORACLE_TRUSTED: 90, // Price signals trusted for VWAP calculation
ESTABLISHED: 50, // Show in listings without warning
NEW: 0 // Show with "new seller" badge
};
// Only trust high-reputation sellers for price discovery
function calculateMarketVWAP(trades) {
const trustedTrades = trades.filter(t =>
t.seller_reputation >= REPUTATION_TIERS.ORACLE_TRUSTED &&
t.timestamp > Date.now() - 3600000 // Last hour only
);
if (trustedTrades.length === 0) {
// Fallback to Asgaya oracle if no trusted trades
return getAsgayaOraclePrice();
}
// Volume-weighted average from trusted trades
return trustedTrades.reduce((acc, t) =>
acc + (t.price * t.volume), 0
) / trustedTrades.reduce((acc, t) => acc + t.volume, 0);
}
Sybil attack fails:
Volume manipulation limited:
Reputation earned through trades:
Channel: asgaya:market:bch-eur
When: Every covenant funding (seller broadcasts after funding)
Payload:
{
"type": "TRADE",
"price": 995,
"volume": 100,
"txid": "abc123...",
"seller_reputation": 98,
"timestamp": 1721937723
}
Purpose: Real-time price discovery from actual trades.
Channel: asgaya:oracle:asgaya
When: Every minute (until network mature)
Payload:
{
"type": "ORACLE_PRICE",
"price": 995.50,
"source": "kraken",
"timestamp": 1721937723
}
Purpose: Bootstrap price feed until user trades sufficient.
Channel: asgaya:covenant:<covenantId>
Context: These messages are for per-covenant coordination (only the 3 devices monitoring a specific covenant receive them). Separate from market-wide price discovery.
When: Device detects market price < covenant threshold
Payload:
{
"type": "PRICE_DROP_ALERT",
"covenantId": "bchtest:pwyclx...",
"currentPrice": 920,
"threshold": 930,
"dropPercent": 8,
"device": "sender",
"timestamp": 1721937723
}
Effect: Other covenant devices prepare for refund.
When: Device broadcasts refund transaction
Payload:
{
"type": "REFUND_BROADCAST",
"covenantId": "bchtest:pwyclx...",
"txid": "dd743868...",
"reason": "PRICE_DROP",
"device": "sender",
"timestamp": 1721937725
}
Effect: Other devices stop monitoring (refund in progress).
Same schema as before (covenant coordination, not price discovery).
See: Previous message types for complete covenant coordination schema.
t=0: Covenant funded, initial price €1000/BCH
María's device subscribes to:
- asgaya:market:bch-eur (trade signals)
- asgaya:oracle:asgaya (bootstrap oracle)
- asgaya:covenant:abc123 (covenant coordination)
t=0-120: Network trades at stable €995/BCH
Asgaya oracle broadcasts €995/BCH
Market VWAP: €995 (hybrid: 70% user + 30% oracle)
No threshold crossed (€930 floor safe)
t=120.0: Market crash detected
Multiple high-rep sellers trade at €920/BCH
Network VWAP updates: €920/BCH
t=120.2: María's device calculates market price
VWAP (€920) < threshold (€930)
DROP DETECTED!
t=120.3: María broadcasts to covenant channel
PRICE_DROP_ALERT → Elena + Isabel
All 3 devices know: refund incoming
t=120.5: María broadcasts REFUND_BROADCAST
Includes H€ minting transaction
Other devices stop monitoring
t=121.0: Elena detects confirmation
Broadcasts REFUND_CONFIRMED
All devices stop monitoring covenant
Detection latency: ~300ms (trade signal → VWAP update → threshold check)
Coordination: Sub-second (Nostr pub/sub)
Price source: Real Asgaya market trades (not CEX speculation)
// Subscribe to market channel
nostr.sub('asgaya:market:bch-eur', (trade) => {
if (trade.seller_reputation >= 90) {
recentTrades.push(trade);
}
});
// Calculate VWAP (last hour, trusted sellers only)
function getMarketPrice() {
const oneHourAgo = Date.now() - 3600000;
const trustedTrades = recentTrades.filter(t =>
t.timestamp > oneHourAgo &&
t.seller_reputation >= 90
);
if (trustedTrades.length < 10) {
// Fallback to Asgaya oracle if thin market
return getAsgayaOraclePrice();
}
// Volume-weighted average
const totalValue = trustedTrades.reduce((a, t) => a + (t.price * t.volume), 0);
const totalVolume = trustedTrades.reduce((a, t) => a + t.volume, 0);
return totalValue / totalVolume;
}
// Gradual weight transition based on user volume
function calculateMarketPrice() {
const userVWAP = getMarketPrice(); // From user trades
const asgayaOracle = getAsgayaOraclePrice(); // From Kraken API
const userVolume24h = sum(userTrades.map(t => t.volume));
// Weight increases as user volume grows
const userWeight = Math.min(userVolume24h / 2000, 0.95); // Cap at 95%
const oracleWeight = 1 - userWeight;
return (userVWAP * userWeight) + (asgayaOracle * oracleWeight);
}
// Monitor covenant against market price
setInterval(() => {
const marketPrice = calculateMarketPrice();
if (marketPrice < covenant.priceFloor * 0.93) {
// Broadcast alert to covenant channel
nostr.publish(`asgaya:covenant:${covenantId}`, {
type: 'PRICE_DROP_ALERT',
currentPrice: marketPrice,
threshold: covenant.priceFloor * 0.93
});
// Execute refund
await covenant.refund();
}
}, 10000); // Check every 10 seconds
What’s public:
What’s private:
Privacy characteristics across layers:
Bulletin board (pre-trade listings): Seller pseudonym and price are public, but not linked to real identity. Anyone can see “Seller_abc123 offers BCH at €995” but not who runs that account.
Covenant fundings (on-chain): Blockchain shows BCH amount, EUR amount (OP_RETURN), recipient address, and expiry time. Same privacy as Bitcoin transactions - amounts visible, participants pseudonymous.
Nostr trade broadcasts (post-trade): Reputation score is public (needed for VWAP filtering), but still not linked to seller’s real identity. Network sees “98-rep seller traded €100 at €995” without knowing who.
Same privacy as Bitcoin transactions: Aggregate data public, individuals pseudonymous. The blockchain itself is the oracle, so on-chain transparency is required for trustless price discovery.
| Failure | What Happens | Result |
|---|---|---|
| Thin market (<10 trades/hour) | Fallback to Asgaya oracle (Kraken API) | System continues working |
| Asgaya oracle offline | Use cached oracle price or user VWAP only | Graceful degradation |
| Both VWAP + oracle unavailable | Use last known price for up to 1 hour, then alert user | Temporary degradation, safe fallback |
| Low-rep seller spam | Trades ignored (reputation < 90 filtered out) | No impact on price |
| One device offline | Other covenant devices monitor + execute refund | Redundancy works |
| Blockchain reorg | Wait for 1-2 confirmations on covenant fundings | Delayed but safe |
Note: On-chain covenant fundings are canonical. Nostr broadcasts are real-time index for UX but blockchain is source of truth.
Scenario: Network outage or extremely thin market during bootstrap - both user VWAP and Asgaya oracle unavailable.
Device behavior:
Rationale: Price rarely moves >7% in one hour. Stale price is acceptable short-term fallback. User alert ensures transparency if degradation persists.
Maximum level achieved:
Cannot shut down:
Can be disrupted but recoverable:
The network becomes its own oracle - most censorship-resistant design possible. Cannot be censored without a 51% blockchain attack.
The elegant property: Market forces naturally resist price manipulation through rational economic behavior.
Attacker’s goal: Trigger auto-refunds by crashing VWAP
Method: Sell BCH far below market to drop VWAP below covenant thresholds
Scenario:
Market price: €1000/BCH
Attacker: €850/BCH (15% below market)
→ VWAP drops
→ Triggers 7% auto-refund thresholds
→ Network disruption
But attacker faces a dilemma:
1. Attacker posts €850/BCH listing
2. Buyers pay via Bizum
3. Attacker MUST fund covenants (to maintain reputation)
Result:
├─ Attacker loses €150 per BCH sold (15% below market)
├─ Reputation stays high (90+)
├─ VWAP manipulation works
└─ But: Extremely expensive
Example: €10,000 volume = €1,500 loss
Unsustainable: Real financial losses, limited by capital.
1. Attacker posts €850/BCH listing
2. Buyers pay via Bizum
3. Attacker DOESN'T fund covenant (avoids loss)
Result:
├─ Reputation drops rapidly (failed trades)
├─ Falls below 90 threshold within days
├─ Price signals ignored (reputation filter)
└─ Attack fails (no VWAP impact)
Attack fails: Can’t maintain 90+ reputation while rejecting covenants.
The catch: Attacker can’t have it both ways!
Additional defenses:
Attack 1 (Inflate price): High-price sellers get 0 volume because buyers choose cheapest offers. No trades = no VWAP impact. Attack fails.
Attack 2 (Deflate price): Selling below market drains BCH inventory fast, costs real money per trade, and attracts arbitrageurs who profit while stabilizing VWAP. Merchants hold BCH when underpriced (expecting reversion), reducing sell pressure. Attack is expensive and unsustainable.
Attack 3 (Wash trading): Requires 90+ reputation (months to earn), real BCH locked per fake trade, and significant volume to move VWAP. A €1,000 fake against €100,000 real daily volume = 1% weight. Too expensive for minimal effect, patterns detectable.
Four natural defense mechanisms:
1. Rational Buyer Behavior
Buyers choose cheapest price
→ High-price manipulators get 0 volume
→ Can't inflate VWAP
2. Inventory Limits
Low-price manipulators drain BCH inventory
→ Limited by capital + holdings
→ Expensive, unsustainable
3. Merchant Reactions
BCH underpriced:
└─ Merchants hold (expect normalization)
└─ Reduces sell pressure
└─ Stabilizes market
BCH overpriced:
└─ Merchants swap to H€ immediately
└─ Increases sell pressure
└─ Brings price down
4. Arbitrage Opportunities
Price deviates from market:
└─ Arbitrageurs exploit mispricing
└─ Profit while stabilizing
└─ Attack becomes profit opportunity
Defense layers:
Result: Manipulation is either ineffective (ignored by market) or expensive (real financial losses). The market naturally resists attacks through rational economic behavior.
The self-balancing above is real — but it is a function of participation, not a property of the mechanism. Two feeds (a settlement-derived VWAP and the trusted/CEX oracle) converge only when the market is thick enough to arbitrage the spread. In a thin market — Phase 0, where Asgaya is the only seller — a deviation can simply stick, because there is no competing seller or arbitrageur to correct it. So manipulation-resistance grows with volume; it does not exist at bootstrap. (This is exactly why the Asgaya oracle bootstraps: it stands in until the market can correct itself.)
The newcomer path (and its lag): a newcomer can win customers by undercutting — but the reputation filter ignores sub-90-reputation signals, so their price doesn’t count toward the reference until they’ve completed trades (which is how they earn reputation). The path is undercut → win trades → earn reputation → your price starts counting. The reference price therefore lags new entrants — expected, not a bug.
Hypothesis (not established): the miner cost-floor. As adoption grows, miners (and merchants) might quote BCH against their production cost plus scarcity rather than a CEX feed — selling below spot but above their marginal (energy) cost to earn a second revenue stream from fees. If it happened, it would tie the floor to energy cost and decouple the protocol from CEX price feeds. ⚠️ This is a direction, not a guarantee: miners are largely price-takers, and sell/hold behaviour is capital-driven, not cost-driven. Treat it as the aspirational end of the same arc.
Traditional HTTP polling:
Asgaya on-chain + Nostr:
Cost per device: Negligible (Nostr subscription is free, covenant funding already required for trades).
Network cost: Scales with trades, not with users. 1,000 users monitoring doesn’t increase cost if only 100 trades/day.
Implementation:
Research:
Related concepts:
| 🏠 Home | ↑ Nostr Coordination | 📖 Glossary |
| Related: Auto-Refund UX | Device Health | RS078 |
Status: ⚪ Aspirational — Phase 1+ (may never be reached). Needs volume + worldwide adoption (a constant trickle of trades); the gate starts at the first organic merchant listing. Design the oracle so this is an easy upgrade; do not build it now.
Updated: 2026-10-03 (settlement-as-signal; participation gate)
Architecture: On-chain settlement signals + reputation-filtered VWAP, bootstrapped by the Asgaya oracle