Seller-Relay Re-Locks: Guaranteed Fast Refunds Without Oracle Key Custody (Deep Dive)
- Seller-Relay Re-Locks: Guaranteed Fast Refunds Without Oracle Key Custody
- 1. The Problem
- 2. Why Previous Approaches Fall Short
- 3. The Seller-Relay Re-Lock Mechanism
- 4. Key Material and Trust Analysis
- 5. Game-Theoretic Analysis
- 6. Detailed Comparison
- 7. Benefits of the Seller-Relay Approach
- 8. How It Fits Into the Settlement Policy Versioning Scheme
- 9. Re-Lock Mechanics Detail
- 10. Open Questions
- 11. Conclusion
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:
- Losing bidders wait for the full locktime (
max_end_at + settlement_grace, typically 1–3 hours) to reclaim their ecash. - 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)
- Bidder requests path from oracle (via
request_pathContextVM tool). - Oracle issues
path_A,child_pubkey_A,locktime = now + minimum_bid_duration(e.g., 5 minutes). - Bidder verifies
HDKey(xpub).derive(path_A).publicKey == child_pubkey_A(§5.6, same as v1). - Bidder locks proofs 1-of-1 to
child_pubkey_Awithlocktime = now + 5 minand refund to bidder’s refund key. - 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):
- Oracle issues a new path.
path_B,child_pubkey_B,locktime = now + minimum_bid_duration. - Oracle early-reveals
path_Ato the seller. The seller can now derivechild_privkey_A. - Seller’s daemon performs the re-lock swap:
- Derives
child_privkey_Afrom 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_Bwith the new locktime.
- Derives
- Oracle records the re-lock. The registry entry for this bid advances from
path_Atopath_B.path_Ais markedexpired_relocked. - 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)
- After the auction’s effective end (defined by the last re-lock or bid time), the seller requests settlement via
request_settlement. - Oracle reveals the final derivation path for the winning bid.
- Seller derives the child privkey from the final path.
- 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_durationof 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_Bwithlocktime_B. - The oracle never reveals
path_Bto 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_durationof 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_atrequired. 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
-
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. -
Should
request_relockbe a new ContextVM tool or an extension ofrequest_path? A new tool is cleaner — it has different authorization (seller-only, not bidder), different inputs (includes existing proofs), and different semantics. -
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. -
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.
-
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.
-
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.
-
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:
- Guaranteed fast refunds for losers — within
minimum_bid_duration, enforced by the mint, independent of all other parties - Oracle holds no key material — only derivation paths, identical trust profile to v1
- 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