dkforest

A forum and chat platform (onion)
git clone https://git.dasho.dev/n0tr1v/dkforest.git
Log | Files | Refs | LICENSE

commit 10cc47581042c30b4a8481b816d4bd65e650928b
parent 93f8ccc9c22e57cd558bddb9c0edb1a969bf0854
Author: n0tr1v <n0tr1v@protonmail.com>
Date:   Wed, 13 Dec 2023 03:14:08 -0500

poker xmr stagenet test

Diffstat:
Acmd/dkf/migrations/148.sql | 26++++++++++++++++++++++++++
Mdoc/notes.md | 8++++++++
Mpkg/actions/actions.go | 55++++++++++++++++++++++++++++++++++++++++---------------
Apkg/database/tablePokerXmrTransactions.go | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpkg/database/tableUsers.go | 26++++++++++++++++++++++++++
Mpkg/template/fn.go | 6++++++
Mpkg/template/tmp.go | 2++
Mpkg/web/handlers/data.go | 7+++++--
Mpkg/web/handlers/handlers.go | 18++++++++++++++++++
Mpkg/web/public/views/pages/poker.gohtml | 26++++++++++++++++++++++++++
10 files changed, 209 insertions(+), 17 deletions(-)

diff --git a/cmd/dkf/migrations/148.sql b/cmd/dkf/migrations/148.sql @@ -0,0 +1,26 @@ +-- +migrate Up +ALTER TABLE users ADD COLUMN poker_xmr_sub_address VARCHAR(255) NOT NULL DEFAULT ''; +CREATE INDEX users_poker_xmr_sub_address_idx ON users (poker_xmr_sub_address); + +CREATE TABLE IF NOT EXISTS poker_xmr_transactions ( + id INTEGER NOT NULL PRIMARY KEY, + tx_id VARCHAR(255) NOT NULL, + user_id INTEGER NOT NULL, + address VARCHAR(255) NOT NULL, + amount INTEGER NOT NULL, + height INTEGER NOT NULL, + confirmations INTEGER NOT NULL, + is_in TINYINT(1) NOT NULL DEFAULT 0, + processed TINYINT(1) NOT NULL DEFAULT 0, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT poker_xmr_transactions_user_id_fk + FOREIGN KEY (user_id) + REFERENCES users (id) + ON DELETE NO ACTION + ON UPDATE CASCADE); +CREATE INDEX poker_xmr_transactions_user_id_idx ON poker_xmr_transactions (user_id); +CREATE INDEX poker_xmr_transactions_is_in_idx ON poker_xmr_transactions (is_in); +CREATE INDEX poker_xmr_transactions_tx_id_idx ON poker_xmr_transactions (tx_id); + +-- +migrate Down diff --git a/doc/notes.md b/doc/notes.md @@ -86,3 +86,10 @@ select username, registration_duration from users order by id desc limit 10; ``` ./monero-wallet-rpc --wallet-file /Users/n0tr1v/Monero/wallets/dkf_stage/dkf_stage.keys --daemon-address 3.10.182.182:38081 --stagenet --rpc-bind-port 6061 --password '...' --disable-rpc-login ``` + +``` +wget https://downloads.getmonero.org/cli/linux64 +tar -xf linux64 +./monero-x86_64-linux-gnu-v0.18.3.1/monero-wallet-cli --stagenet --daemon-address 3.10.182.182:38081 +./monero-x86_64-linux-gnu-v0.18.3.1/monero-wallet-rpc --stagenet --daemon-address 3.10.182.182:38081 --wallet-file /home/dkf/dkf-poker-stagenet.keys --rpc-bind-port 6061 --password '...' +``` +\ No newline at end of file diff --git a/pkg/actions/actions.go b/pkg/actions/actions.go @@ -227,24 +227,49 @@ func xmrWatch(db *database.DkfDB) { continue } for _, transfer := range transfers.In { - invoice, err := db.GetXmrInvoiceByAddress(transfer.Address) - if err != nil { - logrus.Error(err, transfer.TxID) + if user, err := db.GetUserByPokerXmrSubAddress(transfer.Address); err == nil { + pokerTransfer, err := db.GetOrCreatePokerXmrTransaction(user.ID, transfer) + if err != nil { + logrus.Error(err) + continue + } + if pokerTransfer.Processed { + continue + } + pokerTransfer.Confirmations = int64(transfer.Confirmations) + pokerTransfer.DoSave(db) + if transfer.Confirmations < 10 { + logrus.Error("payment processing") + continue + } + tx := db.Begin() + pokerTransfer.Processed = true + user.ChipsTest += int(pokerTransfer.Amount) / 100_000_000 + pokerTransfer.DoSave(tx) + user.DoSave(tx) + tx.Commit() continue - } - origConfirmations := invoice.Confirmations - invoice.Confirmations = int64(transfer.Confirmations) - amount := int64(transfer.Amount) - invoice.AmountReceived = &amount - invoice.DoSave(db) - if origConfirmations >= 10 { - continue - } else if transfer.Confirmations < 10 { - logrus.Error("payment processing") + } else { continue + //invoice, err := db.GetXmrInvoiceByAddress(transfer.Address) + //if err != nil { + // logrus.Error(err, transfer.TxID) + // continue + //} + //origConfirmations := invoice.Confirmations + //invoice.Confirmations = int64(transfer.Confirmations) + //amount := int64(transfer.Amount) + //invoice.AmountReceived = &amount + //invoice.DoSave(db) + //if origConfirmations >= 10 { + // continue + //} else if transfer.Confirmations < 10 { + // logrus.Error("payment processing") + // continue + //} + //logrus.Error("payment done") + //// TODO: execute something } - logrus.Error("payment done") - // TODO: execute something } } } diff --git a/pkg/database/tablePokerXmrTransactions.go b/pkg/database/tablePokerXmrTransactions.go @@ -0,0 +1,52 @@ +package database + +import ( + "github.com/monero-ecosystem/go-monero-rpc-client/wallet" + "github.com/sirupsen/logrus" + "time" +) + +type PokerXmrTransaction struct { + ID int64 + TxID string + UserID UserID + Address string + Amount int64 + Confirmations int64 + Height int64 + IsIn bool + Processed bool + CreatedAt time.Time + UpdatedAt time.Time +} + +func (d *DkfDB) GetUserPokerXmrTransactions(userID UserID) (out []PokerXmrTransaction, err error) { + err = d.db.Order("id DESC").Find(&out, "user_id = ?", userID).Error + return +} + +func (d *DkfDB) GetOrCreatePokerXmrTransaction(userID UserID, transfer *wallet.Transfer) (out PokerXmrTransaction, err error) { + if err = d.db.First(&out, "tx_id = ?", transfer.TxID).Error; err != nil { + out = PokerXmrTransaction{ + TxID: transfer.TxID, + UserID: userID, + Address: transfer.Address, + Height: int64(transfer.Height), + Amount: int64(transfer.Amount), + Confirmations: int64(transfer.Confirmations), + IsIn: true, + } + err = d.db.Create(&out).Error + } + return +} + +func (t *PokerXmrTransaction) Save(db *DkfDB) error { + return db.db.Save(t).Error +} + +func (t *PokerXmrTransaction) DoSave(db *DkfDB) { + if err := t.Save(db); err != nil { + logrus.Error(err) + } +} diff --git a/pkg/database/tableUsers.go b/pkg/database/tableUsers.go @@ -3,6 +3,10 @@ package database import ( "dkforest/pkg/config" "errors" + "fmt" + "github.com/boombuler/barcode" + "github.com/boombuler/barcode/qr" + "image" "strings" "time" @@ -123,6 +127,7 @@ type User struct { SyntaxHighlightCode string ConfirmExternalLinks bool ChessSoundsEnabled bool + PokerXmrSubAddress string HighlightOwnMessages bool `gorm:"-"` } @@ -333,6 +338,11 @@ func (d *DkfDB) GetUserByID(userID UserID) (out User, err error) { return } +func (d *DkfDB) GetUserByPokerXmrSubAddress(pokerXmrSubAddress string) (out User, err error) { + err = d.db.First(&out, "poker_xmr_sub_address = ?", pokerXmrSubAddress).Error + return +} + // GetUserByUsername ... func (d *DkfDB) GetUserByUsername(username Username) (out User, err error) { err = d.db.First(&out, "username = ? COLLATE NOCASE", username).Error @@ -657,3 +667,19 @@ func (u *User) IncrChips(chips int, isTest bool) { u.ChipsTest += chips } } + +func (u *User) GetURL() string { + return fmt.Sprintf("monero:%s", u.PokerXmrSubAddress) +} + +func (u *User) GetImage() (image.Image, error) { + b, err := qr.Encode(u.GetURL(), qr.L, qr.Auto) + if err != nil { + return nil, err + } + b, err = barcode.Scale(b, 150, 150) + if err != nil { + return nil, err + } + return b, nil +} diff --git a/pkg/template/fn.go b/pkg/template/fn.go @@ -113,6 +113,12 @@ func divide100(val int64) float64 { func divide1000(val int64) float64 { return float64(val) / 1000 } +func divide100M(val int64) float64 { + return float64(val) / 100_000_000 +} +func divide1T(val int64) float64 { + return float64(val) / 1_000_000_000_000 +} func int64bytes(val int64) string { return humanize.Bytes(uint64(val)) diff --git a/pkg/template/tmp.go b/pkg/template/tmp.go @@ -41,6 +41,8 @@ func GetRenderer(e *echo.Echo) *Templates { tmplBuilder.AddFn("dot", utils.Dot) tmplBuilder.AddFn("divide100", divide100) tmplBuilder.AddFn("divide1000", divide1000) + tmplBuilder.AddFn("divide100M", divide100M) + tmplBuilder.AddFn("divide1T", divide1T) tmplBuilder.AddFn("toString", toString) tmplBuilder.AddFn("toI64", toI64) tmplBuilder.AddFn("formatFloat", formatFloat) diff --git a/pkg/web/handlers/data.go b/pkg/web/handlers/data.go @@ -929,8 +929,11 @@ type chessData struct { } type pokerData struct { - Balance int64 - Tables []database.PokerTable + Balance int64 + PokerXmrSubAddress string + Img string + Tables []database.PokerTable + Transactions []database.PokerXmrTransaction } type powHelperData struct { diff --git a/pkg/web/handlers/handlers.go b/pkg/web/handlers/handlers.go @@ -14,6 +14,7 @@ import ( "fmt" humanize "github.com/dustin/go-humanize" "github.com/labstack/echo" + wallet1 "github.com/monero-ecosystem/go-monero-rpc-client/wallet" "github.com/pquerna/otp" "github.com/pquerna/otp/totp" "github.com/sirupsen/logrus" @@ -755,8 +756,25 @@ func BHCHandler(c echo.Context) error { func PokerHomeHandler(c echo.Context) error { db := c.Get("database").(*database.DkfDB) authUser := c.Get("authUser").(*database.User) + getImgStr := func(img image.Image) string { + buf := bytes.NewBuffer([]byte("")) + _ = png.Encode(buf, img) + return base64.StdEncoding.EncodeToString(buf.Bytes()) + } + if authUser.PokerXmrSubAddress == "" { + if resp, err := config.Xmr().CreateAddress(&wallet1.RequestCreateAddress{}); err == nil { + authUser.PokerXmrSubAddress = resp.Address + authUser.DoSave(db) + } + } var data pokerData + data.Transactions, _ = db.GetUserPokerXmrTransactions(authUser.ID) + data.PokerXmrSubAddress = authUser.PokerXmrSubAddress data.Balance = int64(authUser.ChipsTest) data.Tables, _ = db.GetPokerTables() + if authUser.PokerXmrSubAddress != "" { + b, _ := authUser.GetImage() + data.Img = getImgStr(b) + } return c.Render(http.StatusOK, "poker", data) } diff --git a/pkg/web/public/views/pages/poker.gohtml b/pkg/web/public/views/pages/poker.gohtml @@ -3,6 +3,12 @@ {{ define "content" }} <div class="container"> <div class="mb-3"> + Xmr address: {{ if .Data.PokerXmrSubAddress }}{{ .Data.PokerXmrSubAddress }}{{ else }}none{{ end }}<br /> + {{ if .Data.PokerXmrSubAddress }} + <img src="data:image/png;base64,{{ .Data.Img }}" class="img-thumbnail" alt="" /> + {{ end }} + </div> + <div class="mb-3"> Balance: {{ .Data.Balance }} chips </div> <h3>Tables</h3> @@ -20,5 +26,25 @@ <tr><td colspan="2"><em>No table to show</em></td></tr> {{ end }} </table> + + <h3>Transactions</h3> + <table class="table table-novpadding table-sm table-hover table-striped"> + <tr> + <th>Amount XMR</th> + <th>Confirmations</th> + <th>Processed</th> + <th>Created at</th> + </tr> + {{ range .Data.Transactions }} + <tr> + <td>{{ .Amount | divide1T }}</td> + <td>{{ .Confirmations }}</td> + <td>{{ .Processed | fmtBool }}</td> + <td>{{ .CreatedAt.Format "Jan 02, 2006 15:04:05" }}</td> + </tr> + {{ else }} + <tr><td colspan="4"><em>No transactions to show</em></td></tr> + {{ end }} + </table> </div> {{ end }} \ No newline at end of file