In the Hydra Auction architecture, commands/requests flow from people (Seller, Bidder, Delegate) to systems (Frontend/CLI, Cardano node, delegate server, Hydra node) as follows:
flowchart TB
subgraph Auction App
seller([Seller])
bidder([Bidder])
frontend(Frontend CLI)
end
subgraph Hydra-based Auction Hosting
delegate([Delegate])
delegateServer(Delegate server)
hydraNode(Hydra node)
end
subgraph Cardano
cardanoNode(Cardano node)
end
admin([Admin])
admin -- start/stop -----> cardanoNode
seller -- request --> frontend
bidder -- request --> frontend
frontend -- request --> cardanoNode
frontend -- request --> delegateServer
delegateServer -- request --> hydraNode
delegate -- start/stop ---> delegateServer
delegate -- start/stop ---> hydraNode
hydraNode -- request --> cardanoNode
In the rest of this document, we will describe each of these systems and the request types that people can submit to those systems.
- All auction users are from a predefined list of actors
(with fixed keys laying in
data/credentials
). This is only to simplify demonstration, no real limitation for that in scripts exists. - Hardcoded auction lot asset class is used.
- All Hydra nodes know each others' IPs before starting a node (this is a current limitation of Hydra).
- Multiple delegates cannot share a single Hydra node, due to the Hydra API allowing any actions from any client. So we have one Hydra node to one Delegate server correspondence for now.
- An auction can only be hosted on a single Hydra Head
and a Hydra Head can only host one auction.
- Later, when Hydra will support incremental commits and decommits (see Hydra spec for details), same Hydra Head and set of delegates can be reused for multiple Auctions.
- Anyone can place auction into Hydra Head.
- At the same time any Auction has its Hydra Head Id recorded on-chain and cannot be placed on any other Hydra Head.
- Should Delegate server validate transactions before posting them to L2 or only Hydra Ledger and Frontend should do that.
A typical workflow for an auction should look as follows:
- The delegates ensure that all daemon services are started (Delegate servers, Hydra nodes).
- Delegates initialize the Hydra Head.
- The seller announces the auction.
- (Bidding start time is reached)
- The seller starts the bidding phase.
- A delegate moves the standing bid to L2.
- The delegates open the Hydra Head.
- Bidders may submit new bids on L2.
- One of the delegates or bidders closes the Hydra Head on L1. The delegates' Hydra nodes continuously monitor L1 for this closing transaction, ready to submit contesting transactions if necessary.
- The seller or one of the bidders or delegates fans out the standing bid to L1.
- (Bidding end time is reached)
- The winning bidder may buy the auction lot.
- (Voucher expiry time is reached)
- If the auction lot has not been bought by the winning bidder, then the seller reclaims the auction lot and may claim the winning bidder’s bidder deposit.
- One of the delegates distributes the auction fees to the delegates.
- (Cleanup time is reached)
- The seller spends the standing bid utxo and burns the voucher token.
The Cardano node is responsible for broadcasting transactions to the Cardano network.
In the real world, this would correspond to the node, provided by a light-wallet backend. Alternatively, for full decentralization, a user could in principle choose to run their own Cardano node, without a trusted intermediary.
For testing purposes, a local Cardano node cluster (with one node)
can be started using docker-compose
.
start. Start a Cardano node, as a single-node development network (devnet) or as a node on a known Cardano network (mainnet or testnet). Command parameters:
|
stop. Stop the Cardano node. |
The Hydra node is responsible for broadcasting L2 transactions to the Hydra Head and participating in the Hydra Head consensus protocol (including L1 Hydra Head transactions).
The Hydra node API should be only accessible to the delegate server. It should not be directly accessible to sellers or bidders.
The delegate server may send the following commands to the Hydra node:
Init
, Commit
, NewTx
, GetUTxO
, Close
, Fanout
.
Hydra API reference: https://hydra.family/head-protocol/api-reference
The delegate server is responsible for responding to requests from the Frontend CLI, constructing queries or transactions as necessary to submit to the delegate’s Hydra node.
Each delegate should have its own delegate server and Hydra node running.
start. Start a delegate server and an associated Hydra Node. Command parameters:
|
stop. Stop the delegate server and its associated Hydra node. |
The frontend CLI is a program that can be run by sellers and bidders. It provides an interactive prompt for them to submit their actions to interact with the auction.
start. Start a frontend CLI session. Command parameters:
|
stop. Quit the frontend CLI session. |
The AuctionTerms
for the Auction ID are cached in the auction state directory.
prepare. Distribute ADA from the faucet to all the potential users in the auction (Alice, Bob, etc.) and provide a freshly minted NFT to the recipient, so that the NFT can be put up for auction. This action is intended for testing purposes on local devnets. It has no effect on mainnet or public testnets. Request parameters:
|
showUtxos. Show the utxos owned by the current user. showAllUtxos. Show the utxos of all users (Alice, Bob, etc.). Request parameters: none. |
announceAuction. Used by sellers. Construct From this moment timing of stages begins. Request parameters:
|
createBidDeposit. Used by bidders to place deposits for auctions, before the bidding start time. Request parameters:
This request will return an error if the deposit amount is smaller than
the Approved bidders at bidding start time will be selected from bidders that created sufficient deposits. |
startBiddingL2. Used by sellers. Performed after BiddingStart and before BiddingEnd. Execute a sequence of actions to allow bidding to start on L2. Request parameters:
This endpoint is equivalent to calling startBiddingL1 and then calling moveStandingBidToL2. |
startBiddingL1. Used by sellers. Performed after BiddingStart and before BiddingEnd. If the request submitter is the seller
corresponding to the Request parameters:
The list of approved bidders is automatically determined here via an L1 off-chain query that selects all bidders who created sufficient deposits for the auction. |
moveStandingBidToL2. Used by sellers. Commit the standing bid to the Hydra Head and coordinate the opening of the Hydra Head. Request parameters:
This endpoint performs the following actions:
|
newBidL1. Submit a new bid as an L1 transaction to the Cardano node. Performed after BiddingStart and before BiddingEnd. This request is needed for the fallback scenario when the standing bid is not on L2 because either it was never moved there or the Hydra Head closed prematurely. Normally, all bids should be submitted to L2. Request parameters:
|
newBidL2. Send a request to a given delegate server (chosen by the bidder) to submit a new bid as an L2 transaction to the Hydra Head. Performed after BiddingStart and before BiddingEnd. Request parameters:
Response:
Cache this post-dated transaction for the bidder. |
bidderBuys. Used by the winning bidder. Performed after BiddingEnd and before VoucherExpiry. Submits a transaction that:
Request parameters:
|
sellerReclaims. Used by the seller. Performed after VoucherExpiry. Submits a transaction that:
Request parameters:
|
refundDeposit. Used by losing bidders. Performed after BiddingEnd. Submits a transaction that:
Request parameters:
|
closeHeadByBidder. Submit the cached post-dated L1 closing transaction to the Cardano node. This request is needed for the fallback scenario when the delegates fail to close the Hydra Head in time for the contestation period to end by the bidding end time. In that scenario, a bidder can use this request to force the Hydra Head to close, preventing the Hydra Head from staying open significantly past the bidding end time. No request parameters are required. |
fanoutByBidder. Fan out the standing bid utxo from the Hydra Head, so that it can be used in L1 transactions. This request is needed in case the delegates' hydra nodes fail to fan out the standing bid after the Hydra Head closes. Normally, that should happen automatically. No request parameters are required. |
cleanupStandingBid. Used by the seller. Performed after an auction's cleanup time. Spend the standing bid utxo with the Request parameters:
|
How Delegate server API works:
- Delegate server may have multiple clients which it does not authenticate, because all permissions are already enforced on-chain.
- Delegate server works in async event-driven way, the same as Hydra Node. Clients could push requests and receive Delegate server responses, in async way. We name them Requests/Responses, not Inputs/Outputs like Hydra. That is because Delegate may have inputs other than Frontend requests. Delegate server do broadcast all Hydra events which could be interesting for its clients.
Things which should be done automatically:
- Delegate server should be started when Hydra node already running. After start it asks for the initialization of the Hydra Head.
- When one of the delegates makes a commit (via Hydra node) with the standing bid UTxO, all of the other delegates should make empty commits. They should be able to do this by monitoring the commit messages on L2.
- The Hydra Head is opened by Hydra node automatically as soon as all Hydra nodes commit.
- If the Hydra Head isn't opened before the bidding end time, it should be aborted by Delegate server.
- Delegate server closes the Hydra Head at the bidding end time. Otherwise, bidders would be able to submit new bids on L2 past the bidding end time.
- Delegate server submits fee distribution transaction, if after voucher expiry fee escrow is present.
Fanout
should be triggered when the contestation period ends.
Frontend Requests: commitStandingBid. Used by Request parameters:
The Note: Implementation for this API request is currently blocked because Hydra nodes do not support creating transactions to commit utxos from script addresses to a Hydra Head. The implementation details of this request depend on how this feature will be implemented in Hydra. |
newBid. Construct and submit a Request parameters:
This request is sent by the Frontend CLI when it receives
a |