Compare commits
	
		
			4 Commits
		
	
	
		
			cb5132f2c1
			...
			b7a24b48fd
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b7a24b48fd | |||
| 70b5659dc8 | |||
| 5d5c91399f | |||
| 03689add7e | 
@ -108,6 +108,14 @@
 | 
				
			|||||||
    color: var(--color);
 | 
					    color: var(--color);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .text-success {
 | 
				
			||||||
 | 
					    color: var(--fg-success);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .text-error {
 | 
				
			||||||
 | 
					    color: var(--fg-error);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .hitbox {
 | 
					  .hitbox {
 | 
				
			||||||
    padding: 15px;
 | 
					    padding: 15px;
 | 
				
			||||||
    margin: -15px;
 | 
					    margin: -15px;
 | 
				
			||||||
@ -124,7 +132,8 @@
 | 
				
			|||||||
    color: var(--fg-success);
 | 
					    color: var(--fg-success);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .neon.success:hover, .neon.success.active {
 | 
					  .neon.success:hover,
 | 
				
			||||||
 | 
					  .neon.success.active {
 | 
				
			||||||
    background-color: var(--fg-success);
 | 
					    background-color: var(--fg-success);
 | 
				
			||||||
    color: var(--white);
 | 
					    color: var(--white);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -134,7 +143,8 @@
 | 
				
			|||||||
    color: var(--fg-error);
 | 
					    color: var(--fg-error);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .neon.error:hover, .neon.error.active {
 | 
					  .neon.error:hover,
 | 
				
			||||||
 | 
					  .neon.error.active {
 | 
				
			||||||
    background-color: var(--fg-error);
 | 
					    background-color: var(--fg-error);
 | 
				
			||||||
    color: var(--white);
 | 
					    color: var(--white);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,7 @@ package handler
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"database/sql"
 | 
						"database/sql"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"git.ekzyis.com/ekzyis/delphi.market/lib/lmsr"
 | 
				
			||||||
	"git.ekzyis.com/ekzyis/delphi.market/server/router/context"
 | 
						"git.ekzyis.com/ekzyis/delphi.market/server/router/context"
 | 
				
			||||||
	"git.ekzyis.com/ekzyis/delphi.market/server/router/pages"
 | 
						"git.ekzyis.com/ekzyis/delphi.market/server/router/pages"
 | 
				
			||||||
	"git.ekzyis.com/ekzyis/delphi.market/types"
 | 
						"git.ekzyis.com/ekzyis/delphi.market/types"
 | 
				
			||||||
@ -15,16 +16,29 @@ func HandleIndex(sc context.Context) echo.HandlerFunc {
 | 
				
			|||||||
			db      = sc.Db
 | 
								db      = sc.Db
 | 
				
			||||||
			ctx     = c.Request().Context()
 | 
								ctx     = c.Request().Context()
 | 
				
			||||||
			rows    *sql.Rows
 | 
								rows    *sql.Rows
 | 
				
			||||||
			err     error
 | 
					 | 
				
			||||||
			markets []types.Market
 | 
								markets []types.Market
 | 
				
			||||||
 | 
								err     error
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if rows, err = db.QueryContext(ctx, ""+
 | 
							if rows, err = db.QueryContext(ctx, ""+
 | 
				
			||||||
 | 
								"WITH lmsr AS ("+
 | 
				
			||||||
 | 
								"  SELECT "+
 | 
				
			||||||
 | 
								"    o.market_id, "+
 | 
				
			||||||
 | 
								"    COALESCE(SUM(o.quantity) FILTER(WHERE o.outcome = 0), 0) AS q1, "+
 | 
				
			||||||
 | 
								"    COALESCE(SUM(o.quantity) FILTER(WHERE o.outcome = 1), 0) AS q2, "+
 | 
				
			||||||
 | 
								"    COALESCE(SUM(i.msats_received), 0) / 1000 AS volume "+
 | 
				
			||||||
 | 
								"  FROM orders o "+
 | 
				
			||||||
 | 
								"  JOIN invoices i ON o.invoice_id = i.id "+
 | 
				
			||||||
 | 
								"  WHERE i.confirmed_at IS NOT NULL "+
 | 
				
			||||||
 | 
								"  GROUP BY o.market_id"+
 | 
				
			||||||
 | 
								")"+
 | 
				
			||||||
			"SELECT m.id, m.question, m.description, m.created_at, m.end_date, "+
 | 
								"SELECT m.id, m.question, m.description, m.created_at, m.end_date, "+
 | 
				
			||||||
 | 
								"m.lmsr_b, l.q1, l.q2, l.volume, "+
 | 
				
			||||||
			"u.id, u.name, u.created_at, u.ln_pubkey, u.nostr_pubkey, u.msats "+
 | 
								"u.id, u.name, u.created_at, u.ln_pubkey, u.nostr_pubkey, u.msats "+
 | 
				
			||||||
			"FROM markets m "+
 | 
								"FROM markets m "+
 | 
				
			||||||
			"JOIN users u ON m.user_id = u.id "+
 | 
								"JOIN users u ON m.user_id = u.id "+
 | 
				
			||||||
			"JOIN invoices i ON m.invoice_id = i.id "+
 | 
								"JOIN invoices i ON m.invoice_id = i.id "+
 | 
				
			||||||
 | 
								"JOIN lmsr l ON m.id = l.market_id "+
 | 
				
			||||||
			"WHERE i.confirmed_at IS NOT NULL"); err != nil {
 | 
								"WHERE i.confirmed_at IS NOT NULL"); err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -32,12 +46,16 @@ func HandleIndex(sc context.Context) echo.HandlerFunc {
 | 
				
			|||||||
		for rows.Next() {
 | 
							for rows.Next() {
 | 
				
			||||||
			var m types.Market
 | 
								var m types.Market
 | 
				
			||||||
			var u types.User
 | 
								var u types.User
 | 
				
			||||||
 | 
								var l types.LMSR
 | 
				
			||||||
			if err = rows.Scan(
 | 
								if err = rows.Scan(
 | 
				
			||||||
				&m.Id, &m.Question, &m.Description, &m.CreatedAt, &m.EndDate,
 | 
									&m.Id, &m.Question, &m.Description, &m.CreatedAt, &m.EndDate,
 | 
				
			||||||
 | 
									&l.B, &l.Q1, &l.Q2, &m.Volume,
 | 
				
			||||||
				&u.Id, &u.Name, &u.CreatedAt, &u.LnPubkey, &u.NostrPubkey, &u.Msats); err != nil {
 | 
									&u.Id, &u.Name, &u.CreatedAt, &u.LnPubkey, &u.NostrPubkey, &u.Msats); err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			m.User = u
 | 
								m.User = u
 | 
				
			||||||
 | 
								m.Pyes = lmsr.Quote(l.B, l.Q2, l.Q1, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			markets = append(markets, m)
 | 
								markets = append(markets, m)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -101,27 +101,51 @@ func HandleMarket(sc context.Context) echo.HandlerFunc {
 | 
				
			|||||||
		var (
 | 
							var (
 | 
				
			||||||
			db  = sc.Db
 | 
								db  = sc.Db
 | 
				
			||||||
			ctx = c.Request().Context()
 | 
								ctx = c.Request().Context()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// session user
 | 
				
			||||||
			u = types.User{}
 | 
								u = types.User{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// market id
 | 
				
			||||||
			id = c.Param("id")
 | 
								id = c.Param("id")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// quantity of shares user entered into form
 | 
				
			||||||
			quantity = c.QueryParam("q")
 | 
								quantity = c.QueryParam("q")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// quantity as number
 | 
				
			||||||
			q int64
 | 
								q int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// current market
 | 
				
			||||||
			m = types.Market{}
 | 
								m = types.Market{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// market founder
 | 
				
			||||||
			mU = types.User{}
 | 
								mU = types.User{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// market LMSR data
 | 
				
			||||||
			l = types.LMSR{}
 | 
								l = types.LMSR{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// total price for current quantity of shares in sats
 | 
				
			||||||
			total float64
 | 
								total float64
 | 
				
			||||||
			quote0   = types.MarketQuote{}
 | 
					
 | 
				
			||||||
			quote1   = types.MarketQuote{}
 | 
								// market quotes
 | 
				
			||||||
			uQ0      int
 | 
								quoteNo  = types.MarketQuote{}
 | 
				
			||||||
			uQ1      int
 | 
								quoteYes = types.MarketQuote{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// how many shares the user already holds
 | 
				
			||||||
 | 
								uQuantityNo  int
 | 
				
			||||||
 | 
								uQuantityYes int
 | 
				
			||||||
			rows         *sql.Rows
 | 
								rows         *sql.Rows
 | 
				
			||||||
			p0       []types.MarketPoint
 | 
					
 | 
				
			||||||
			p1       []types.MarketPoint
 | 
								// chart data
 | 
				
			||||||
 | 
								lineNo  []types.Point
 | 
				
			||||||
 | 
								lineYes []types.Point
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			err error
 | 
								err error
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if c.Get("session") != nil {
 | 
							if c.Get("session") != nil {
 | 
				
			||||||
			u = c.Get("session").(types.User)
 | 
								u = c.Get("session").(types.User)
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
 | 
								// unauthenticated user
 | 
				
			||||||
			u.Id = -1
 | 
								u.Id = -1
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -149,6 +173,7 @@ func HandleMarket(sc context.Context) echo.HandlerFunc {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if err = db.QueryRowContext(ctx, ""+
 | 
							if err = db.QueryRowContext(ctx, ""+
 | 
				
			||||||
			"SELECT "+
 | 
								"SELECT "+
 | 
				
			||||||
 | 
								"COALESCE(SUM(i.msats_received), 0) / 1000 AS volume, "+
 | 
				
			||||||
			"COALESCE(SUM(o.quantity) FILTER(WHERE o.outcome = 0), 0) AS q1, "+
 | 
								"COALESCE(SUM(o.quantity) FILTER(WHERE o.outcome = 0), 0) AS q1, "+
 | 
				
			||||||
			"COALESCE(SUM(o.quantity) FILTER(WHERE o.outcome = 1), 0) AS q2, "+
 | 
								"COALESCE(SUM(o.quantity) FILTER(WHERE o.outcome = 1), 0) AS q2, "+
 | 
				
			||||||
			"COALESCE(SUM(o.quantity) FILTER(WHERE o.outcome = 0 AND o.user_id = $2), 0) AS uq1, "+
 | 
								"COALESCE(SUM(o.quantity) FILTER(WHERE o.outcome = 0 AND o.user_id = $2), 0) AS uq1, "+
 | 
				
			||||||
@ -167,14 +192,16 @@ func HandleMarket(sc context.Context) echo.HandlerFunc {
 | 
				
			|||||||
			// but this isn't sybil resistant.
 | 
								// but this isn't sybil resistant.
 | 
				
			||||||
			//
 | 
								//
 | 
				
			||||||
			// For now, we will ignore pending orders.
 | 
								// For now, we will ignore pending orders.
 | 
				
			||||||
			"WHERE o.market_id = $1 AND i.confirmed_at IS NOT NULL", id, u.Id).Scan(
 | 
								"WHERE o.market_id = $1 AND i.confirmed_at IS NOT NULL", id, u.Id).
 | 
				
			||||||
			&l.Q1, &l.Q2, &uQ0, &uQ1); err != nil {
 | 
								Scan(&m.Volume, &l.Q1, &l.Q2, &uQuantityNo, &uQuantityYes); err != nil {
 | 
				
			||||||
			if err == sql.ErrNoRows {
 | 
								if err == sql.ErrNoRows {
 | 
				
			||||||
				return echo.NewHTTPError(http.StatusNotFound)
 | 
									return echo.NewHTTPError(http.StatusNotFound)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							m.Pyes = lmsr.Quote(l.B, l.Q2, l.Q1, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if rows, err = db.QueryContext(ctx, ""+
 | 
							if rows, err = db.QueryContext(ctx, ""+
 | 
				
			||||||
			"SELECT created_at, quote(b, q0, q1, 1) AS p0, quote(b, q1, q0, 1) AS p1 "+
 | 
								"SELECT created_at, quote(b, q0, q1, 1) AS p0, quote(b, q1, q0, 1) AS p1 "+
 | 
				
			||||||
			"FROM ( "+
 | 
								"FROM ( "+
 | 
				
			||||||
@ -203,12 +230,12 @@ func HandleMarket(sc context.Context) echo.HandlerFunc {
 | 
				
			|||||||
			if err = rows.Scan(&createdAt, &_p0, &_p1); err != nil {
 | 
								if err = rows.Scan(&createdAt, &_p0, &_p1); err != nil {
 | 
				
			||||||
				return err
 | 
									return err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			p0 = append(p0, types.MarketPoint{X: createdAt, Y: _p0})
 | 
								lineNo = append(lineNo, types.Point{X: createdAt, Y: _p0})
 | 
				
			||||||
			p1 = append(p1, types.MarketPoint{X: createdAt, Y: _p1})
 | 
								lineYes = append(lineYes, types.Point{X: createdAt, Y: _p1})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		total = lmsr.Quote(l.B, l.Q1, l.Q2, int(q))
 | 
							total = lmsr.Quote(l.B, l.Q1, l.Q2, int(q))
 | 
				
			||||||
		quote0 = types.MarketQuote{
 | 
							quoteNo = types.MarketQuote{
 | 
				
			||||||
			Outcome:    0,
 | 
								Outcome:    0,
 | 
				
			||||||
			AvgPrice:   total / float64(q),
 | 
								AvgPrice:   total / float64(q),
 | 
				
			||||||
			TotalPrice: total,
 | 
								TotalPrice: total,
 | 
				
			||||||
@ -216,7 +243,7 @@ func HandleMarket(sc context.Context) echo.HandlerFunc {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		total = lmsr.Quote(l.B, l.Q2, l.Q1, int(q))
 | 
							total = lmsr.Quote(l.B, l.Q2, l.Q1, int(q))
 | 
				
			||||||
		quote1 = types.MarketQuote{
 | 
							quoteYes = types.MarketQuote{
 | 
				
			||||||
			Outcome:    1,
 | 
								Outcome:    1,
 | 
				
			||||||
			AvgPrice:   total / float64(q),
 | 
								AvgPrice:   total / float64(q),
 | 
				
			||||||
			TotalPrice: total,
 | 
								TotalPrice: total,
 | 
				
			||||||
@ -225,9 +252,9 @@ func HandleMarket(sc context.Context) echo.HandlerFunc {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return pages.Market(
 | 
							return pages.Market(
 | 
				
			||||||
			m,
 | 
								m,
 | 
				
			||||||
			p0, p1,
 | 
								lineNo, lineYes,
 | 
				
			||||||
			quote0, quote1,
 | 
								quoteNo, quoteYes,
 | 
				
			||||||
			uQ0, uQ1).Render(context.RenderContext(sc, c), c.Response().Writer)
 | 
								uQuantityNo, uQuantityYes).Render(context.RenderContext(sc, c), c.Response().Writer)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -239,24 +266,48 @@ func HandleOrder(sc context.Context) echo.HandlerFunc {
 | 
				
			|||||||
			tx  *sql.Tx
 | 
								tx  *sql.Tx
 | 
				
			||||||
			ctx = c.Request().Context()
 | 
								ctx = c.Request().Context()
 | 
				
			||||||
			u   = c.Get("session").(types.User)
 | 
								u   = c.Get("session").(types.User)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// market id
 | 
				
			||||||
			id = c.Param("id")
 | 
								id = c.Param("id")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// how many shares user wants to buy
 | 
				
			||||||
			quantity = c.FormValue("q")
 | 
								quantity = c.FormValue("q")
 | 
				
			||||||
			outcome        = c.FormValue("o")
 | 
								// quantity as number
 | 
				
			||||||
			q int64
 | 
								q int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// on which outcome user wants to bet
 | 
				
			||||||
 | 
								outcome = c.FormValue("o")
 | 
				
			||||||
 | 
								// outcome as id
 | 
				
			||||||
			o int64
 | 
								o int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// selected market
 | 
				
			||||||
			m = types.Market{}
 | 
								m = types.Market{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// market founder
 | 
				
			||||||
			mU = types.User{}
 | 
								mU = types.User{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// market LMSR data
 | 
				
			||||||
			l = types.LMSR{}
 | 
								l = types.LMSR{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// total price as returned by LMSR for given quantity
 | 
				
			||||||
			totalF float64
 | 
								totalF float64
 | 
				
			||||||
 | 
								// total rounded to msats
 | 
				
			||||||
			total int
 | 
								total int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// invoice data
 | 
				
			||||||
			hash           lntypes.Hash
 | 
								hash           lntypes.Hash
 | 
				
			||||||
			paymentRequest string
 | 
								paymentRequest string
 | 
				
			||||||
			expiry         = int64(60)
 | 
								expiry         = int64(60)
 | 
				
			||||||
			expiresAt      = time.Now().Add(time.Second * time.Duration(expiry))
 | 
								expiresAt      = time.Now().Add(time.Second * time.Duration(expiry))
 | 
				
			||||||
			invoiceId      int
 | 
								invoiceId      int
 | 
				
			||||||
			invDescription string
 | 
								invDescription string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// id of created order
 | 
				
			||||||
			orderId int
 | 
								orderId int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// QR component during render
 | 
				
			||||||
			qr templ.Component
 | 
								qr templ.Component
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			err error
 | 
								err error
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -36,8 +36,8 @@ templ Index(markets []types.Market) {
 | 
				
			|||||||
									<a href={ templ.SafeURL(fmt.Sprintf("/market/%d", m.Id)) }>{ m.Question }</a>
 | 
														<a href={ templ.SafeURL(fmt.Sprintf("/market/%d", m.Id)) }>{ m.Question }</a>
 | 
				
			||||||
									<div class="text-small text-muted">{ m.User.Name } / { humanize.Time(m.CreatedAt) } / { humanize.Time(m.EndDate) }</div>
 | 
														<div class="text-small text-muted">{ m.User.Name } / { humanize.Time(m.CreatedAt) } / { humanize.Time(m.EndDate) }</div>
 | 
				
			||||||
								</span>
 | 
													</span>
 | 
				
			||||||
								<span class="px-3 border-b border-muted pb-3 mt-3 flex"><div class="self-center">51%</div></span>
 | 
													<span class={ fmt.Sprintf("%s %s", "px-3 border-b border-muted pb-3 mt-3 flex", colorize(m.Pyes)) }><div class="self-center">{ fmt.Sprintf("%.2f%%", m.Pyes * 100) }</div></span>
 | 
				
			||||||
								<span class="pe-3 border-b border-muted pb-3 mt-3 flex"><div class="self-center">0</div></span>
 | 
													<span class="pe-3 border-b border-muted pb-3 mt-3 flex"><div class="self-center">{ fmt.Sprintf("%s", humanizeRound(m.Volume)) }</div></span>
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
@ -92,6 +92,25 @@ func minDate() string {
 | 
				
			|||||||
	return time.Now().Add(24 * time.Hour).Format("2006-01-02")
 | 
						return time.Now().Add(24 * time.Hour).Format("2006-01-02")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func humanizeRound(f float64) string {
 | 
				
			||||||
 | 
						if f > 1_000_000 {
 | 
				
			||||||
 | 
							return fmt.Sprintf("%.2fm", f/1_000_000)
 | 
				
			||||||
 | 
						} else if f > 1_000 {
 | 
				
			||||||
 | 
							return fmt.Sprintf("%.2fk", f/1_000)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return fmt.Sprintf("%.2f", f)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func colorize(f float64) string {
 | 
				
			||||||
 | 
						if f > 0.5 {
 | 
				
			||||||
 | 
							return "text-success"
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return "text-error"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func tabStyle(path string, tab string) string {
 | 
					func tabStyle(path string, tab string) string {
 | 
				
			||||||
	class := "!no-underline"
 | 
						class := "!no-underline"
 | 
				
			||||||
	if path == tab {
 | 
						if path == tab {
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: Add countdown? Use or at least show somewhere precise timestamps?
 | 
					// TODO: Add countdown? Use or at least show somewhere precise timestamps?
 | 
				
			||||||
templ Market(m types.Market, p0 []types.MarketPoint, p1 []types.MarketPoint, q0 types.MarketQuote, q1 types.MarketQuote, uQ0 int, uQ1 int) {
 | 
					templ Market(m types.Market, p0 []types.Point, p1 []types.Point, quoteNo types.MarketQuote, quoteYes types.MarketQuote, uQuantityNo int, uQuantityYes int) {
 | 
				
			||||||
	<html>
 | 
						<html>
 | 
				
			||||||
		@components.Head()
 | 
							@components.Head()
 | 
				
			||||||
		<body
 | 
							<body
 | 
				
			||||||
@ -54,10 +54,10 @@ templ Market(m types.Market, p0 []types.MarketPoint, p1 []types.MarketPoint, q0
 | 
				
			|||||||
						</button>
 | 
											</button>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
					<div class="mx-auto my-5" x-show="outcome === 1">
 | 
										<div class="mx-auto my-5" x-show="outcome === 1">
 | 
				
			||||||
						@components.MarketForm(m, 1, q1, uQ1)
 | 
											@components.MarketForm(m, 1, quoteYes, uQuantityYes)
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
					<div class="mx-auto my-5" x-show="outcome === 0">
 | 
										<div class="mx-auto my-5" x-show="outcome === 0">
 | 
				
			||||||
						@components.MarketForm(m, 0, q0, uQ0)
 | 
											@components.MarketForm(m, 0, quoteNo, uQuantityNo)
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
 | 
				
			|||||||
@ -36,6 +36,9 @@ type Market struct {
 | 
				
			|||||||
	Description string
 | 
						Description string
 | 
				
			||||||
	CreatedAt   time.Time
 | 
						CreatedAt   time.Time
 | 
				
			||||||
	EndDate     time.Time
 | 
						EndDate     time.Time
 | 
				
			||||||
 | 
						Pyes        float64
 | 
				
			||||||
 | 
						// market volume in sats
 | 
				
			||||||
 | 
						Volume float64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type LMSR struct {
 | 
					type LMSR struct {
 | 
				
			||||||
@ -51,7 +54,7 @@ type MarketQuote struct {
 | 
				
			|||||||
	Reward     float64
 | 
						Reward     float64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type MarketPoint struct {
 | 
					type Point struct {
 | 
				
			||||||
	X time.Time
 | 
						X time.Time
 | 
				
			||||||
	Y float64
 | 
						Y float64
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user