Seller-Relay Re-Locks: Guaranteed Fast Refunds Without Oracle Key Custody (Deep Dive)

A thorough analysis of the seller-relay re-lock mechanism for Cashu path-oracle auctions, including game-theoretic analysis, key material breakdown, liveness requirements, and comparison against moving-bound and coordinator approaches.

Seller-Relay Re-Locks: Guaranteed Fast Refunds Without Oracle Key Custody

Date: May 24, 2026 Companion to: AUCTIONS.md (v1 codex), auctions-moving-bound-early-refund.md (moving-bound analysis) Related proposals: SatsAndSports SIG_ALL gist, SIG_INPUTs gist


1. The Problem

The v1 path-oracle auction (AUCTIONS.md) has two known UX gaps:

  1. Losing bidders wait for the full locktime (max_end_at + settlement_grace, typically 1–3 hours) to reclaim their ecash.
  2. Capital-inefficient rebidding: a bidder who raises their own bid has both old and new amounts locked simultaneously for hours.

The moving-bound design (per-bid locktimes, documented in auctions-moving-bound-early-refund.md) partially addresses these: each bid gets its own locktime, and losers’ locktimes are relatively shorter when bidding is active. However, moving-bound refunds are best-effort, not guaranteed. With sparse bidding (e.g., two bidders, one bid each), losers wait just as long as in v1.

The coordinator proposals from SatsAndSports give guaranteed instant refunds but require the coordinator to hold a Cashu signing key. This adds a new trust assumption: the coordinator now holds key material, not just information.

We want all three:

  • Guaranteed fast refunds for losers (not best-effort)
  • Oracle holds no Cashu key material (only derivation paths)
  • Seller claims independently after path reveal (no coordinator signature needed)

2. Why Previous Approaches Fall Short

2.1 The irreducible tension

There is an irreducible tension between three properties:

Proofs locked to seller’s key Short locktime (fast refund) Async (no liveness requirement)
v1
Moving-bound Partial (depends on activity)
1-of-2 P2PK ✗ (bidder can retract)
Coordinator (SatsAndSports) ✗ (needs coordinator sig)
Seller-relay re-lock ✗ (seller daemon during auction)

You can have any two. The seller-relay design picks properties 1 and 2, and accepts a liveness requirement for the seller.

2.2 Why per-bid short locktimes alone don’t work

If every bid starts with a short locktime (e.g., now + 5 min), losers get fast refunds. But the standing (highest) bidder’s locktime also expires in 5 minutes. If nobody extends it, the standing bid evaporates and the auction has no valid commitment.

The standing bidder cannot extend their own locktime because the proofs are locked 1-of-1 to the seller’s HD-derived child pubkey. Only the holder of the child privkey can spend those proofs. The bidder doesn’t hold it — the seller does (after path reveal).

Attempts to work around this:

Approach Why it fails
Bidder re-locks to own key Bidder can retract. Breaks irrevocable commitment.
Oracle re-locks with coordinator key Oracle holds signing key. New trust assumption.
Pre-stage multiple paths per bid Bidder can’t spend old proofs to swap to new ones. Same wall.
Seller re-locks during auction Works — but requires seller liveness.

The seller-relay design accepts the seller liveness requirement and builds a clean mechanism around it.


3. The Seller-Relay Re-Lock Mechanism

3.1 Overview

Every bid starts with a short locktime (now + minimum_bid_duration). The oracle monitors the standing (highest) bid and coordinates with the seller’s daemon to re-lock it before the locktime expires. Losing bidders’ short locktimes are never extended — they expire and the bidder reclaims.

       Bid placed              Re-lock 1              Re-lock 2           Settlement
       (locktime T+5)          (locktime T+10)        (locktime T+15)
Alice: |----path_A----|                            (outbid at T+6)
                         |----path_B----|         (outbid at T+11)
Bob:                                            |----path_C----|----> seller claims
Carol:              (outbid at T+3, refunds at T+5)

3.2 Bid flow (same as v1, different locktime)

  1. Bidder requests path from oracle (via request_path ContextVM tool).
  2. Oracle issues path_A, child_pubkey_A, locktime = now + minimum_bid_duration (e.g., 5 minutes).
  3. Bidder verifies HDKey(xpub).derive(path_A).publicKey == child_pubkey_A (§5.6, same as v1).
  4. Bidder locks proofs 1-of-1 to child_pubkey_A with locktime = now + 5 min and refund to bidder’s refund key.
  5. Bidder publishes kind-1023 bid event + submits token to oracle via submit_bid_token.

Lock profile is identical to v1: 1-of-1 P2PK, timelocked refund, SIG_INPUTS. No multisig. No coordinator keys.

3.3 Re-lock flow (new — standing bid only)

The oracle monitors all bids for the auction. When the standing bid’s locktime approaches (e.g., within 1 minute of expiry):

  1. Oracle issues a new path. path_B, child_pubkey_B, locktime = now + minimum_bid_duration.
  2. Oracle early-reveals path_A to the seller. The seller can now derive child_privkey_A.
  3. Seller’s daemon performs the re-lock swap:
    • Derives child_privkey_A from the seller’s xpriv + path_A.
    • Swaps the old proofs (locked to child_pubkey_A) at the mint.
    • New proofs are locked to child_pubkey_B with the new locktime.
  4. Oracle records the re-lock. The registry entry for this bid advances from path_A to path_B. path_A is marked expired_relocked.
  5. Oracle does NOT reveal path_B. It stays secret until settlement.

The old proofs are consumed at the mint (spent during the swap). They no longer exist. The new proofs are locked to a fresh child pubkey with a fresh short locktime.

Repeat as needed: when locktime_B approaches, the oracle issues path_C, early-reveals path_B, seller re-locks to child_pubkey_C, etc.

3.4 Settlement (same as v1)

  1. After the auction’s effective end (defined by the last re-lock or bid time), the seller requests settlement via request_settlement.
  2. Oracle reveals the final derivation path for the winning bid.
  3. Seller derives the child privkey from the final path.
  4. Seller claims the proofs. Done.

The settlement flow is identical to v1. The only difference is that the “winning path” is the path from the most recent re-lock, not the original bid path.

3.5 Refund for losers

Losing bidders are never re-locked. Their locktime = bid_time + minimum_bid_duration.

  • When outbid, their locktime is still bid_time + minimum_bid_duration.
  • When that time arrives, the bidder reclaims via their refund key.
  • Guaranteed within minimum_bid_duration of bid placement, regardless of:
    • Bidding activity (sparse or dense)
    • Seller liveness (online or offline)
    • Oracle liveness (as long as oracle was alive to issue the original path)
    • Any other party’s behavior

3.6 Seller offline fallback

If the seller’s daemon does not respond to a re-lock request:

  • The standing bid’s locktime expires.
  • The standing bidder reclaims via their refund key. Their funds are safe.
  • The auction continues with the next-highest bid as the new standing bid.
  • The oracle attempts re-lock for the new standing bid with the seller’s daemon.

If the seller is persistently offline, all standing bids evaporate one by one as their locktimes expire. Eventually no bids remain. The auction ends with no winner. All bidders recover all funds.

No party loses funds due to seller offline. The seller loses the auction (no sale). Bidders lose time, not money. The worst case for any bidder is waiting minimum_bid_duration (minutes, not hours).

3.7 What happens to re-locked proofs if the seller goes offline permanently?

Suppose the seller re-locks from path_A to path_B, then goes permanently offline.

  • The new proofs are locked to child_pubkey_B with locktime_B.
  • The oracle never reveals path_B to the seller (seller is offline).
  • The bidder’s refund key on the new proofs activates at locktime_B.
  • At locktime_B, the bidder reclaims via refund key. Funds are safe.

The worst case for the standing bidder: wait until locktime_B (which is at most relock_time + minimum_bid_duration — minutes after the last successful re-lock). This is no worse than v1’s waiting period and vastly better in the common case.

The bidder does NOT need to trust the seller for refund. The refund is enforced by the mint’s locktime mechanism. If the seller goes offline after re-locking, the bidder’s refund key on the new proofs guarantees recovery.


4. Key Material and Trust Analysis

4.1 What the oracle holds

The oracle holds:

  • Derivation paths for all bids (same as v1)
  • Encrypted bid tokens (same as v1)
  • Re-lock state: which bids have been re-locked, which paths have been early-revealed

The oracle does NOT hold:

  • Any Cashu signing key
  • Any child privkey (seller’s key material)
  • Any xpriv material
  • Any bidder privkey or refund key

The oracle’s role is purely informational: it assigns paths, tracks the standing bid, early-reveals old paths to the seller for re-lock, and reveals the final path at settlement. Even a fully compromised oracle cannot steal funds. It can only:

  • Refuse to issue new paths (DoS — same as v1)
  • Reveal paths to the seller prematurely (enables early claim — but only for the standing bid, which the seller would win at settlement anyway)
  • Fail to coordinate re-locks (standing bids evaporate — graceful degradation, no fund loss)

The oracle’s trust profile is identical to v1. No new key material, no new trust assumptions.

4.2 What the seller holds

The seller holds:

  • xpriv for deriving child privkeys from revealed paths (same as v1)
  • Re-lock daemon: online during auction to respond to oracle re-lock requests

The seller does NOT hold:

  • Any bidder’s privkey or refund key
  • Any oracle signing key
  • Any ability to spend non-standing bids

The seller can only spend proofs that have been early-revealed for re-lock — the standing bid’s current proofs. The seller cannot spend losing bidders’ proofs because those proofs are locked to different child pubkeys whose paths have NOT been revealed to the seller. The oracle only early-reveals paths for the standing bid.

4.3 What the bidder holds

The bidder holds:

  • Their own refund privkey (same as v1)
  • The derivation path they were granted (for audit, same as v1)

The bidder does NOT hold:

  • Any child privkey (seller’s key material)
  • Any spending key for the locked proofs before locktime

The bidder trusts:

  • The mint (to honor proofs — same as any Cashu user)
  • The oracle (to not reveal paths to the seller prematurely — same as v1)
  • NOT the seller for refund. The bidder’s refund is enforced by the mint’s locktime. If the seller goes offline, the bidder waits for locktime and reclaims. No seller cooperation needed.

4.4 Liveness requirements

Party Must be online when Consequence of going offline Fund loss?
Oracle Always (same as v1) No new paths, no re-locks. All bids refund at locktime. No
Seller’s daemon During auction (new) Standing bids evaporate. Auction degrades. No
Bidder Only to place bid (same as v1) Standing bid expires. Bidder reclaims. No

The seller’s liveness during the auction is a new requirement vs v1. In v1, the seller only needs to be online at settlement time. In the seller-relay design, the seller must also respond to re-lock requests during the auction.

However:

  • The seller is already running a marketplace. A lightweight daemon is a natural extension.
  • The consequence of seller offline is graceful degradation, not fund loss. The auction continues with lower bids.
  • The seller is economically incentivized to stay online: offline means the auction sells for less or not at all.

5. Game-Theoretic Analysis

5.1 Bidder strategies

Strategy Description Outcome Rational?
Honest bid Lock value, hope to win If outbid, reclaim within minutes. If standing, bid is maintained by seller’s re-lock daemon. Yes
Spam bid Lock value with no intent to win Funds locked for minimum_bid_duration. Same cost as v1 but shorter lockup. Oracle rate-limiting applies. Marginally (same as v1)
Bid retraction Attempt to pull standing bid Impossible. Proofs locked to seller’s child key. Bidder has no spending key. Same as v1. N/A
Refund griefing Attempt to delay or block own refund Impossible. Refund enforced by mint locktime. No counterparty can interfere. N/A
Let standing bid expire Standing bidder goes offline Bid reclaims at locktime (minutes). No fund loss. Auction continues with next bid. Self-harming (loses position)

5.2 Seller strategies

Strategy Description Outcome Rational?
Honest Run daemon, maintain standing bids, settle at auction end Maximizes sale price. Standing bid maintained. Yes
Go offline Stop daemon during auction Standing bids evaporate one by one. Auction degrades to lower bids or no winner. No fund theft. No (self-harming)
Premature claim Spend re-locked proofs before auction ends The spent proofs were for the standing bid — the bid the seller would win at settlement anyway. No extra value gained. Auction ends prematurely. Oracle can detect and flag. No (reputation damage, no extra profit)
Refuse re-lock for specific bidder Selectively ignore re-lock requests Targeted bidder’s bid evaporates. Auction continues with next-highest. No fund theft. Seller loses that bid’s value. No (self-harming)

5.3 Oracle strategies

Strategy Description Outcome Rational?
Honest Issue paths, coordinate re-locks, reveal at settlement Auction runs correctly. Same trust as v1. Yes
Refuse re-locks Stop coordinating re-locks Standing bids evaporate. Auction degrades. Same DoS risk as v1. N/A (platform-level concern)
Reveal paths early Reveal standing bid’s path before auction ends Enables seller to claim standing bid early. But seller would win this bid at settlement anyway. No extra theft. Same risk as v1. Mitigated by §5.6 audit
Fabricate paths Issue paths that don’t derive from seller’s xpub Bidder verifies derivation (§5.6) before locking. Attack detected. Same protection as v1. Blocked by §5.6

5.4 Collusion scenarios

Collusion What they could do Impact Prevented by
Seller + Oracle Prematurely claim the standing bid Seller gets the standing bid’s value early. But this is the bid they’d win at settlement anyway. No extra theft. Not needed — no incremental harm
Seller + Oracle Claim a losing bid’s proofs Oracle has NOT early-revealed the losing bid’s path. Seller can’t derive the child privkey. Oracle only reveals standing bid paths
Seller + Bidder Bidder lets standing bid expire on purpose Bidder gets own money back. No theft of other bidders’ funds. Self-harming for seller (lower price)
Oracle + Bidder Oracle refuses to re-lock competing bids Competing bids evaporate. The colluding bidder wins at lower price. Platform-level monitoring of re-lock patterns
Seller + Winning bidder Seller claims early, splits with bidder Seller gets winning bid value (same as settlement). No extra value to split. Not needed — no incremental harm

Key security property: no collusion scenario enables fund theft. The worst cases are:

  • Premature settlement (seller gets money slightly early, but same amount)
  • Selective bid suppression (DoS, same as v1)
  • These are liveness attacks, not safety attacks. Funds are always recoverable.

6. Detailed Comparison

6.1 vs v1 Path-Oracle

Property v1 (uniform locktime) Seller-Relay Re-Lock
Lock profile 1-of-1 P2PK + timelocked refund 1-of-1 P2PK + timelocked refund (unchanged)
Oracle key material None (derivation paths only) None (derivation paths only, unchanged)
Seller autonomy at settlement Claims alone after path reveal Claims alone after path reveal (unchanged)
Mint compatibility Basic NUT-11 Basic NUT-11 (unchanged)
Loser refund latency Hours minimum_bid_duration (minutes) — guaranteed
Rebidding capital waste Full old amount locked for hours Old amount locked for minimum_bid_duration
Bid retraction possible No No (unchanged)
Seller liveness during auction Not required Required (standing bid re-locks)
Anti-snipe mechanism Fixed window + min_bid_curve Built into re-lock cycle

6.2 vs Moving-Bound (per-bid locktimes)

Property Moving-Bound Seller-Relay Re-Lock
Loser refund latency Best-effort (fast with active bidding, slow with sparse bidding) Guaranteed (fast regardless of bidding activity)
Seller liveness during auction Not required Required
Lock profile Same as v1 Same as v1
Oracle complexity Per-bid locktime calculation Per-bid locktime + re-lock coordination + path early-reveal
Standing bid maintenance Locktime naturally extends with new bids Seller actively re-locks

6.3 vs SatsAndSports Coordinator (both gists)

Property Seller-Relay Re-Lock Coordinator (SIG_ALL) Coordinator (SIG_INPUTs)
Lock profile 1-of-1 P2PK (same as v1) 2-of-2 (coordinator + bidder) 2-of-2 (coordinator + bidder)
Oracle key material None Signing key per auction Signing key per auction
Seller autonomy ✓ Claims alone after path reveal ✗ Needs coordinator co-signature ✗ Needs coordinator co-signature
Mint compatibility Basic NUT-11 NUT-11 M-of-N + SIG_ALL NUT-11 M-of-N + SIG_INPUTs
Loser refund latency Minutes (guaranteed) Instant Instant
Seller liveness Required during auction Not required Not required
Bid retraction possible No No No
Coordinator blind to tokens N/A (no coordinator) No (sees full swap) Yes (signs hashes only)

7. Benefits of the Seller-Relay Approach

7.1 Preserved from v1

  • Oracle holds no Cashu key material. Even a fully compromised oracle cannot steal funds. It can only delay settlement or fail to coordinate re-locks (DoS, graceful degradation).
  • Seller claims independently at settlement. After the oracle reveals the final path, the seller derives the child privkey and claims. No coordinator signature needed.
  • Minimal mint compatibility. Standard NUT-11 P2PK with locktime and refund. No M-of-N multisig, no SIG_ALL, no SIG_INPUTs.
  • Bid retraction prevented. Proofs locked to seller’s child key. Bidder holds no spending key. Same as v1.
  • Safe failure mode. All bids refund at their locktimes. No fund trapping.
  • Bidder-side path verification (§5.6). Same protection against malicious oracle key substitution.

7.2 New benefits vs v1

  • Guaranteed fast refunds for losers. Within minimum_bid_duration of bid placement. Not best-effort — structurally guaranteed by the mint’s locktime enforcement. Independent of bidding activity, seller liveness, or any other party’s behavior.
  • Capital-efficient rebidding. Old bids expire within minimum_bid_duration. A bidder who rebids recovers their old capital quickly.
  • Supports open-ended auctions. No hard max_end_at required. The auction continues as long as the standing bid is maintained by re-locks.
  • Anti-snipe built in. Each re-lock of the standing bid extends the auction’s effective window.
  • No new entities. Same three parties: seller, oracle, bidder. No coordinator, no additional trusted third party.
  • No new trust assumptions for the bidder. The bidder’s trust model is identical to v1: trust the oracle to not reveal paths prematurely, trust the mint to honor proofs. The bidder does NOT trust the seller for refund.

7.3 Tradeoffs

  • Seller must run a daemon during the auction. This is a new liveness requirement. In v1, the seller only needs to be online at settlement. In the seller-relay design, the seller must also respond to re-lock requests during the auction. The daemon is lightweight (receive path, derive key, swap at mint) but must be reliably online.
  • Standing bidder’s proofs are re-locked by the seller. During the brief re-lock transition, the bidder’s original proofs are consumed and new proofs are created. The bidder does not directly control this transition. However: (a) the bidder’s refund key on the new proofs guarantees recovery, and (b) the re-lock is economically beneficial for the bidder (maintains their standing position).
  • Oracle complexity increases. The oracle must track re-lock state, detect approaching locktimes, issue new paths, and coordinate early reveals with the seller. This is more complex than v1’s single-path-issuance model but operates within the same ContextVM tool framework.

8. How It Fits Into the Settlement Policy Versioning Scheme

Tag value Lock profile Locktime Re-lock Liveness
cashu_p2pk_path_oracle_v1 1-of-1, uniform max_end_at + grace None Seller at settlement only
cashu_p2pk_path_oracle_v2 (moving-bound) 1-of-1, per-bid max(effective_end + grace, now + min_dur) None Seller at settlement only
cashu_p2pk_path_oracle_v3 (seller-relay) 1-of-1, per-bid now + min_dur Seller re-locks standing bid Seller during auction

All three policies coexist on relays. The auction kind (30408), bid kind (1023), settlement kind (1024), and path registry kind (30410) remain unchanged. Only the oracle’s path issuance, locktime calculation, and re-lock coordination differ between policies.


9. Re-Lock Mechanics Detail

9.1 New ContextVM tool: request_relock

The oracle calls this tool (or the equivalent coordination mechanism) to trigger a re-lock of the standing bid:

Input (oracle → seller):

interface RequestRelockInput {
    auctionEventId: string
    standingBidEventId: string
    currentPath: {
        derivationPath: string
        childPubkey: string
        locktime: number
    }
    newPath: {
        derivationPath: string
        childPubkey: string
        locktime: number
    }
    proofs: {
        mintUrl: string
        amount: number
        encodedToken: string
    }
}

Output (seller → oracle):

interface RequestRelockOutput {
    success: boolean
    newProofsAmount: number
    newLocktime: number
}

9.2 Re-lock sequence

Oracle                              Seller's Daemon                Mint
  |                                      |                          |
  |--- issue new path_B -------------->  |                          |
  |                                      |                          |
  |--- early-reveal path_A + proofs ---> |                          |
  |                                      |                          |
  |                                      |--- derive child_priv_A --|
  |                                      |                          |
  |                                      |--- swap old proofs ----->|
  |                                      |<-- new proofs -----------|
  |                                      |   (locked to child_B)    |
  |                                      |                          |
  |<-- relock confirmation --------------|                          |
  |                                      |                          |
  |--- update registry: path_A expired, path_B active
  |--- path_B NOT revealed (held until settlement)

9.3 Proof lifecycle

Bid placed → proofs locked to child_A (locktime T+5)
                |
                |--- Outbid? → refund at T+5 (bidder reclaims)
                |
                |--- Still standing at T+4? → re-lock:
                |       seller spends child_A proofs
                |       new proofs locked to child_B (locktime T+10)
                |       child_A path marked expired
                |       child_B path held secret
                |
                |--- Still standing at T+9? → re-lock again:
                |       seller spends child_B proofs
                |       new proofs locked to child_C (locktime T+15)
                |       child_B path marked expired
                |       child_C path held secret
                |
                |--- Auction settles → oracle reveals child_C path
                        seller derives child_priv_C
                        seller claims proofs

10. Open Questions

  1. How does the seller’s daemon authenticate re-lock requests from the oracle? The oracle is already authenticated via ContextVM (caller identity from NIP-25910 wrapping). The seller’s daemon could verify that re-lock requests come from the auction’s designated path_issuer.

  2. Should request_relock be a new ContextVM tool or an extension of request_path? A new tool is cleaner — it has different authorization (seller-only, not bidder), different inputs (includes existing proofs), and different semantics.

  3. What is the optimal minimum_bid_duration? Shorter values (2–3 min) give faster refunds but require more frequent re-locks (more seller daemon activity, more mint swaps). Longer values (10–15 min) are less demanding but slower. This may be a per-auction seller parameter with a platform-enforced minimum.

  4. Should there be a maximum number of re-locks per bid? Prevents seller exhaustion for very long auctions. Each re-lock is a mint swap (network call, small fee risk). A cap of, say, 100 re-locks per bid per auction limits seller daemon workload.

  5. How does the bid floor curve interact with re-lock timing? The re-lock doesn’t change the bid amount. The floor curve can still be applied at bid time and verified at settlement. Re-locks are transparent to the floor calculation.

  6. What if the mint is temporarily unavailable during a re-lock? The re-lock fails. The standing bid’s locktime continues to approach. If the mint comes back in time, retry. If not, the bid expires and the bidder reclaims. The oracle should retry with backoff and alert the seller.

  7. Can re-locks be batched? If the seller has multiple standing bids across multiple auctions, the daemon could batch re-lock swaps to reduce mint round-trips. This is an implementation optimization.


11. Conclusion

The seller-relay re-lock design achieves all three desired properties:

  1. Guaranteed fast refunds for losers — within minimum_bid_duration, enforced by the mint, independent of all other parties
  2. Oracle holds no key material — only derivation paths, identical trust profile to v1
  3. Seller claims independently at settlement — after path reveal, no coordinator signature needed

The cost is a liveness requirement for the seller during the auction. The seller must run a lightweight daemon that responds to re-lock requests from the oracle. This daemon performs simple operations: derive a key, swap proofs at the mint. The consequence of seller offline is graceful degradation (standing bids evaporate, no fund loss), not catastrophic failure.

No new entities, no coordinator keys, no multisig, no mint changes. The same three parties with the same trust boundaries as v1, extended with a coordination protocol that guarantees fast refunds.


Write a comment
No comments yet.