Skip to content

Commit 5d316f0

Browse files
finishe reamed
1 parent 4e9d0a2 commit 5d316f0

18 files changed

+428
-67
lines changed

lazer/cardano/hermes/README.md

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,71 @@ Contact: luduena.nicolas.victorio@gmail.com
1111

1212
Hermes market is a proof of concept integration of Pyth oracle information with Cardano's bleeding edge L2 [Hydra](https://hydra.family/head-protocol) that allows for real time bets on BTC price. Therefore truly giving an edge over a simple 5 minute market with up to 2 minute block finality in the L1 on the worst cases. Even on mainnet with high congestion scenarios, block confirmation is not guaranteed after several days.
1313

14-
## Original Repository
14+
## Motivation
1515

16-
The origial repository for this project can be found here: https://github.com/nicolasLuduena/pythathon
16+
Cardano is a powerful and very secure blockchain, but slow for the fast transactions: Cardano's consensus algorithm, while efficient, still requires massive global replication of state changes, potentially increasing transaction settlement times during peak hours. For our use case, we require real-time transaction settlement times.
17+
18+
For solving this issue, we rely on Hydra L2 to provide the speed and scalability we need for this project. Hydra L2 is a layer 2 solution that is built on top of Cardano and provides a low-latency, high-throughput, and secure way to process transactions.
19+
20+
For the Oracle service, we use Pyth, a service provider of real-time price feeds for various kinds of assets. For this PoC, we built a 5-minute prediction market for BTC/USD trading pair.
21+
22+
## Architecture
23+
24+
### Onchain
25+
26+
We designed an Aiken smart contract for managing the markets lifecycle and the bets placed on them through the orders script.
27+
28+
There are several operations that can be performed on the market script:
29+
- Create a new market: every 5 minutes, a new market UTxOis created associated with a fresh order script.
30+
- Place Buy or Sell order: a user can place a buy or sell order for receiving the appropriate position tokens.
31+
- Record the final price of the market: the oracle service will record the final price in the market UTxO.
32+
- Claim winnings: a winning user can claim the winnings by providing the position tokens.
33+
- Claim losses: user provide their losing tokens for being burned.
34+
- Close the market: the market is closed by burning the Market UTxO control token.
35+
- Process an orders match: grab complementary orders from opposite directions, and distribute the tokens appropriately.
36+
37+
You can find the diagrams for all these transactions [here](./doc/transactions.pdf)
38+
39+
### Infrastructure
40+
41+
Two Hydra nodes required for running one Hydra Head in offline mode. We declare the initial UTxO set for the Hydra chain, inject the appropriate scripts and assets for working with the Pyth oracle service.
42+
43+
### Server & Offchain
44+
45+
The server encompasses the prediction market business logic for interacting with the onchain scripts, and with the offchain services that interact with the Pyth oracle service and builds the Market script transactions. Also, we have a Hydra service that connects seamlessly with the Hydra nodes for sending and receiving transactions, and looking up for useful blockchain information.
46+
47+
### Client
48+
49+
The client is a simple React application to visualize the current prediction market state, with real-time updates coming from the server being shown in a nice real-time udpated chart, with buy and sell orders being shown as well. It also allows to place buy and sell orders, and to claim winnings or losses.
50+
51+
### Limitations
52+
53+
A key limitation for this PoC is that we use Hydra in offline mode, which means that the Hydra nodes are not connected to a Cardano Node, but we just declar a initial UTxO set for the Hydra chain. For using Pyth within Hydra in this offline mode setup, we "inject" the Pyth-related onchain entities (withdraw validator and Pyth State asset) in the initial UTxO set.
54+
55+
But for a production deployment in a public testnet or mainnet, the part of injecting the Pyth-related onchain entities on the Hydra initial UTxO set presents a real challenge. We would need to spend the UTxO containing the Pyth State asset for being commited to the Hydra chain. Naturally, the Pyth contract will not allow this to happen.
56+
57+
So for this idea to work in a public testnet or mainnet, either an update of the Pyth contract is needed, or an update of the Hydra protocol is needed for supporting L1 UTxOs as reference inputs (no spending allowed) inside the Hydra Head. This would be sufficient since the UTxO holding the Pyth State asset is only needed as reference inputs in the Oracle operations.
58+
59+
## Tech Stack
60+
61+
- App: Vite + React + TailwindCSS
62+
- Server: Node.js + WebSocket
63+
- Infrastructure: Docker compose, Hydra
64+
- Onchain: Aiken, [Pyth Lazer Aiken lib](https://github.com/pyth-network/pyth-lazer-cardano)
65+
- Offchain: Lucid Evolution
66+
67+
## Setup & Run
68+
69+
1. Run the infrastructure: see [infra/README.md](./infra/README.md)
70+
2. Run the server
71+
```bash
72+
cd server
73+
pnpm install
74+
pnpm api
75+
```
76+
3. Run the UI
77+
```bash
78+
cd ui
79+
pnpm install
80+
pnpm dev
81+
```
52.1 KB
Binary file not shown.

lazer/cardano/hermes/doc/transactions.typ

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@
296296
address: "order book address",
297297
value: (
298298
"Order Control token": "1",
299-
"BUY/SELL": `M`,
299+
"UP/DOWN": `M`,
300300
),
301301
datum: (
302302
owner: `pkh`,
@@ -329,7 +329,7 @@
329329
datum: (
330330
owner: `pkh`,
331331
direction: "Up|Down",
332-
operation: `Sell|Down`,
332+
operation: `Sell|Buy`,
333333
price: `P`,
334334
),
335335
redeemer: ("CompleteFill"),
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#! /bin/bash
2+
# Build + sign the Hydra offline-head seed tx for Preprod (--testnet-magic 1).
3+
# Tx layout follows infra/hydra-bootstrap/entrypoint.sh: cardano-cli latest transaction build-raw, then sign, then cat.
4+
# Run from repo host with Docker (entrypoint runs cardano-cli inside its image; we invoke the same CLI via docker run).
5+
#
6+
# No --tx-out-reference-script-file: cardano-cli’s reference-script CBOR does not match Hydra 1.3’s ledger check
7+
# (ConwayUtxowFailure MalformedReferenceScripts). The Pyth UTxO carries inline datum + tokens only; attach Plutus
8+
# in L2 txs explicitly (e.g. Lucid attach.WithdrawalValidator / attach.Script) instead of readFrom scriptRef.
9+
10+
set -euo pipefail
11+
12+
BOOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13+
INFRA="$(cd "${BOOT}/.." && pwd)"
14+
15+
CARDANO_IMAGE="${CARDANO_IMAGE:-ghcr.io/intersectmbo/cardano-node:10.1.4}"
16+
17+
cardano_cli() {
18+
docker run --rm --user "$(id -u):$(id -g)" --entrypoint cardano-cli \
19+
-v "${INFRA}:/work" -w /work/hydra-bootstrap \
20+
"${CARDANO_IMAGE}" "$@"
21+
}
22+
23+
# Preprod (not the devnet 42 from entrypoint.sh)
24+
testnet_magic="${TESTNET_MAGIC:-1}"
25+
26+
# Define the UTxO details and amounts (initial-utxo-set.json fiction #0)
27+
tx_in1="0000000000000000000000000000000000000000000000000000000000000000#0"
28+
tx_in_lovelace=100000000041175
29+
fee=41175
30+
# Remaining lovelace to the Pyth script output after fee
31+
out_lovelace=$((tx_in_lovelace - fee))
32+
33+
policy_id="d799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6"
34+
asset_name_hex="50797468205374617465"
35+
# Must match submit-seed-tx.sh PYTH_OUTPUT_ADDR
36+
pyth_script_address="${PYTH_OUTPUT_ADDR:-addr_test1wrm3tr5zpw9k2nefjtsz66wfzn6flnphr5kd6ak9ufrl3wcqqfyn8}"
37+
38+
tx_out="${pyth_script_address}+${out_lovelace}+1 ${policy_id}.${asset_name_hex}"
39+
40+
signing_key="${SEED_SIGNING_KEY:-${INFRA}/credentials/hydra-funds.sk}"
41+
if [[ "${signing_key}" != "${INFRA}"/* ]]; then
42+
echo "Signing key must be under ${INFRA}" >&2
43+
exit 1
44+
fi
45+
signing_key_container="/work/${signing_key#"${INFRA}"/}"
46+
47+
# Inline datum CBOR (hex) — same as seed-output-datum.hex
48+
datum_hex="$(tr -d ' \n\t' < "${SEED_DATUM_HEX_FILE:-${BOOT}/seed-output-datum.hex}")"
49+
if command -v xxd >/dev/null 2>&1; then
50+
printf '%s' "${datum_hex}" | xxd -r -p > "${BOOT}/seed-output-datum.cbor"
51+
else
52+
python3 -c "import sys,binascii; sys.stdout.buffer.write(binascii.unhexlify(sys.argv[1]))" "${datum_hex}" > "${BOOT}/seed-output-datum.cbor"
53+
fi
54+
55+
tx_raw="/work/hydra-bootstrap/seed.body.json"
56+
tx_signed="/work/hydra-bootstrap/seed.witnessed.json"
57+
58+
# Build the raw transaction (cf. entrypoint.sh — build-raw, then fee, then out-file)
59+
echo "Building raw transaction..."
60+
cardano_cli latest transaction build-raw \
61+
--tx-in "${tx_in1}" \
62+
--tx-out "${tx_out}" \
63+
--tx-out-inline-datum-cbor-file seed-output-datum.cbor \
64+
--protocol-params-file /work/protocol-parameters.json \
65+
--fee "${fee}" \
66+
--out-file "${tx_raw}"
67+
68+
# Sign the transaction (Preprod testnet-magic)
69+
echo "Signing transaction (Preprod testnet-magic ${testnet_magic})..."
70+
cardano_cli latest transaction sign \
71+
--tx-body-file "${tx_raw}" \
72+
--signing-key-file "${signing_key_container}" \
73+
--testnet-magic "${testnet_magic}" \
74+
--out-file "${tx_signed}"
75+
76+
cp "${BOOT}/seed.witnessed.json" "${INFRA}/seed-spend.signed.json"
77+
cp "${BOOT}/seed.body.json" "${BOOT}/seed-spend.raw"
78+
79+
echo "Wrote ${INFRA}/seed-spend.signed.json and ${BOOT}/seed-spend.raw"
80+
cat "${INFRA}/seed-spend.signed.json"
70 Bytes
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
d8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb241822ffbf582080efc1f480c5615af3fb673d42287e993da9fbc3506b6e41dfa32950820c2e6cd8799fd8799fd87980d87a80ffd8799fd87a9f1b000001a2f5f38d08ffd87a80ffffffa0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"type": "Tx ConwayEra",
2+
"type": "Unwitnessed Tx ConwayEra",
33
"description": "Ledger Cddl Format",
4-
"cborHex": "84a300d90102818258200000000000000000000000000000000000000000000000000000000000000000000181a400581d70f7158e820b8b654f2992e02d69c914f49fcc371d2cdd76c5e247f8bb01821b00005af3107a4000a1581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6a14a5079746820537461746501028201d818586ad8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb2400ffa0a0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff03d818590abe8203590ab9590ab60101003229800aba4aba2aba1aba0aab9faab9eaab9dab9a9bae002488888888966002646465300130063754003370e90014dc3a4001300a0039805001244444b30013370e9003002c4c8c966002600c601a6ea800e2b3001300e3754007159800980298069baa301130120028a518b20188b201e8b2018375a602000260186ea801a264b300130010068cc004c040c034dd5003cdd6001488c8cc00400400c88cc00c004c0080092223300100222598008014660024602c602e602e0032301630170019ba54800244b3001300b30133754005132323259800980d80144c8c9660026020003159800980c9baa00280345901a456600260220031323259800980f80140222c80e0dd6980e800980c9baa0028acc004c0340062b3001301937540050068b20348b202e405c80b8c05cdd5000980d001c59018192cc004c05c0062b3001337129002180b000c5a2601e602c00280aa2c80c0dd5180c800980c800980a1baa0028b202448888cc8966002601e602e6ea800a2646464646644b300130220038992cc004c058c078dd5000c4c8c8c8ca60026eb4c0980066eb8c0980126eb4c09800e6eb8c0980092222598009815802c4cc060dd59815007112cc00400a26603401844b30010028acc004c08cc0a8dd500f44cc88cc89660026644b30013371e6eb8c0d0c0d4c0d4c0d4c0c4dd500d800c528c4c8cc004004dd5981018191baa01c2259800800c528456600264b30013371e6eb8c0d000401226600e606600200b14a08190c0d80062946266004004606e0028189034205e3001302f375404a6eb8c0c8c0bcdd501144c9289919800800811112cc00400629344c8cc89263259800cc004dd7181018199baa0019bae302130333754003375c606c60666ea800572a8acc004c8c966002605a60686ea800629422605a60686ea8c0e0c0d4dd5000a06632598009816981a1baa0018a60103d87a8000898109981bcc004cc020c0e0c0d4dd50009803981a9baa02ba6103d87a8000a60103d879800040cc97ae040cc64660020026eacc088c0d4dd500f912cc004006298103d87a80008992cc004cdc78021bae3036001898119981c981b800a5eb82266006006607600481a8c0e40050371bae30203033375400310018b20628b2062325980099b8f48900375c606c606e003130360018b2062323235980099b8f375c606e00291104b9011a82008919191919191919911981f98149981f98200039981f9ba90013303f30400024bd701981f9820182080125eb80d6600266e252000001892cc004cdc48011b8d00189981f1ba93300a0020013303e3753300100299b81371a0020050015c612f5c11640e91640e46eb8c0f8c0fc008dd7181f0021bad303d001323303c375066f29281bae303d0013303c303d303e0014bd702cc004cdc4a40086e340062660766ea4cc01d20040013303b375330014801266e00dc6800a40070015c612f5c11640dc6eb8c0ecc0f0004d6600294624b30013371290201b8d00189981d1ba93300648100004cc0e8dd4cc005204099b80371a002901fc0057184bd704590364590351bae303a303b001300100259800a51892cc004cdc4a4100026e340062660706ea4cc0112080010013303837533001482000666e00dc6800a40ff0015c612f5c11640d11640cd1640c86eb8c0dcc0e00056600266e252008371a00513303537526600290040011981a9ba99800a4011337006e3400920078012e3097ae08b20623718900019801801981b0011bae303400140c91640b444b300130040018a518acc004c01000a29422b3001980099baf9800981918179baa002981918179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920024bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d87b8000a50a5140b51980099baf9800980e18179baa002980e18179baa001919192cc004c0a8c0c4dd5181a981b00144006264b3001302b001899ba548008cc0d4dd419b80375a606c60666ea800920014bd704566002605400310028801206240c460626ea8005030181a00098181baa001400c98103d8798000a50a5140b514a0816902d205a2303130323032303230323032303230320012323232332259800981400145284566002604a0051980099baf30343031375400298103d87b8000a50a5140bd13233225980098158014528c566002605800513322598009817181a9baa30233036375400d13371000400313371200400281a0dd6981b981a1baa00359800981618199baa30213034375400f1001899b80001480090324528206440c860626ea8004dd6981a98191baa004303430313754002817902f18171baa001303230330033031302e3754002606000260586ea8004888c8cc89660026050005159800981418181baa0018a60103d87a80008a6103d879800040bd15980098128014566002604a60606ea80062980103d87a80008a6103d87b800040bd13322598009815000c530103d87b80008acc004c0ac006264b30013371000600314c0103d87980008acc004cdc4000801c530103d87b80008a6103d87a800040c88190dd6981b18199baa0038a6103d879800040c48188dd6981a18189baa00330303754002817902f18171baa001300200330010038b2052899191980b18160010980198188021bae302c001302e00240b11323233014302b00213003302f004375c6052002605800481522c8140604c002604a0026048002603e6ea80062c80e8c08401a2c80f8dd7180f8009bab301f002301f001301e001301d0013018375400516405864b3001300e301637540031301a3017375400316405464660020026eb0c010c05cdd5006912cc004006298103d87a80008992cc006600266ebc00530103d87a8000a50a51405d1001899801801980e801202e325980099912cc00400a294226530013259800980a180e1baa00189bad301d302037566040603a6ea8006290002036301f0019baf301f30200019bab003488966002003159800980100344cc01400d20008a5040751325980099baf301f0014c010140008acc004cc018010dd6981018119bab3020001898019ba630240028a5040791598009980300224001130030078a50407880f0c0880050200ca60020033756601260386ea8c024c070dd5002488cc080008cc080dd3000a5eb810011112cc00400a26600298103d87a80004bd6f7b63044ca60026eb8c0780066eacc07c00660460069112cc004cdc8a441000038acc004cdc7a441000038998029807198121ba60024bd70000c4cc015300103d87a8000006408119800803c006446600e0046604c66ec0dd48029ba6004001401c8100604200480fa2942294229410201ba63301b337606ea4058dd31980d99bb0301c3019375498118d8799f4a507974682053746174654850797468204f7073ff004c010101004bd6f7b63025eb7bdb1808928c566002602260306ea8c070c064dd5180e180c9baa300630193754003132598009807180c9baa001898031980e180e980d1baa0014bd704590181803980c9baa30063019375400316405d14c103d87a8000405c603600280c88966002601e602e6ea800a2646464b3001301f002899803180f00189980300080245901c180e800980e800980c1baa0028b202c44c8c008c05c00cdd7180a801202645900b1b874801100a0c024c028004c024004c010dd5005452689b2b20042611e581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e600010219a0d7a0f5f6"
4+
"cborHex": "84a300d90102818258200000000000000000000000000000000000000000000000000000000000000000000181a300581d70f7158e820b8b654f2992e02d69c914f49fcc371d2cdd76c5e247f8bb01821b00005af3107a4000a1581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6a14a5079746820537461746501028201d81858b0d8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb241822ffbf582080efc1f480c5615af3fb673d42287e993da9fbc3506b6e41dfa32950820c2e6cd8799fd8799fd87980d87a80ffd8799fd87a9f1b000001a2f5f38d08ffd87a80ffffffa0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff0219a0d7a0f5f6"
55
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type": "Unwitnessed Tx ConwayEra",
3+
"description": "Ledger Cddl Format",
4+
"cborHex": "84a300d90102818258200000000000000000000000000000000000000000000000000000000000000000000181a300581d70f7158e820b8b654f2992e02d69c914f49fcc371d2cdd76c5e247f8bb01821b00005af3107a4000a1581cd799d287105dea9377cdf9ea8502a83d2b9eb2d2050a8aea800a21e6a14a5079746820537461746501028201d81858b0d8799fd8799f581c363d819f282a6cf2a6c2cb6bbc68213538355ca64e4b64620e14949a015820a36234ef3749a2c94136b6345bceff450791ef1ebc99e918f16f8075a441bb241822ffbf582080efc1f480c5615af3fb673d42287e993da9fbc3506b6e41dfa32950820c2e6cd8799fd8799fd87980d87a80ffd8799fd87a9f1b000001a2f5f38d08ffd87a80ffffffa0581c68a8972304546f254cbf625996c3a9e2ac860f77a9fcd4ee9f73907bff0219a0d7a0f5f6"
5+
}

0 commit comments

Comments
 (0)