-
Notifications
You must be signed in to change notification settings - Fork 0
WIP: Paid contests & awards #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jus1d
wants to merge
56
commits into
dev
Choose a base branch
from
feat/wallets
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
56 commits
Select commit
Hold shift + click to select a range
868825f
chore: Split business logic into service layer
jus1d 6a3cd5d
chore: replace int32 to int
jus1d 89aa391
chore: cleanup
jus1d a317e9a
chore: use params struct to services
jus1d 69fa08f
chore: remove select * from sql queries
jus1d 6a3eea7
chore: add migrations back, add ton package
jus1d f0cbec8
chore: Implement types for contests with prizes
jus1d d6d17d0
chore: Introduce tx manager
jus1d d2151a3
chore: add problem repo to txrepo
jus1d 0dbe2d6
chore: improve fixes after review
jus1d 1d151c4
chore: ton transfer: add comment optional
jus1d 1645577
fix: incorrect participants count
jus1d b791a0f
chore: add creator_id and title filters for contest querying
jus1d 832e29e
chore: add leaderboard view
jus1d de6ebeb
chore: factor out charcode calculation from repo layer
jus1d e4d7f18
chore: add some views
jus1d be0ba77
chore: cleanup views, prizes
jus1d 33a5bce
migrations: split creating view out of tables
jus1d 9016c27
chore: Add submission_details view
jus1d f8d891a
chore: add `award_type` to contest responses
jus1d 330fff4
chore: add enum difficulty
jus1d 7c132a0
chore: check txs to pay the entry
jus1d fe87802
chore: add tx hash, and entry price for the contest
jus1d b3b768d
chore: add entry price to create contest params
jus1d dc16613
chore: add `is_admitted` field to entry response
jus1d 47d9b14
chore: add address to contest detailed response
jus1d efe166d
chore: cleanup omit empties
jus1d bf08f48
chore: forbid to view contest problem if entry is not paid
jus1d cd96f85
chore: add awards distributions
jus1d 89299dd
chore: rename migration files
jus1d 243703a
chore: Introduce payments table
jus1d 66a60ba
chore: drop indecies
jus1d 283c4f8
chore: Improve migrations, add indecies, make views materialized
jus1d bb6bc91
chore: Save wallet adresses as testnet, if config setted as testnet
jus1d 2866e5b
chore: remove materialized views
jus1d 5055f26
chore: remove GET /entry
jus1d 3507533
chore: Improve contest response structure
jus1d 376e4bd
chore: check for entry paid on get contest
jus1d e895509
chore: rename leaderboard to scores
jus1d 27cacfb
chore: ignore .diff files
jus1d de382b3
fix: proper ignore .diff files
jus1d db1ff41
chore: add address to account/user response
jus1d 9c8f0ad
chore: Introduce tonproof logic. again
jus1d 4edd6bc
chore: replace liteapi with tonutils
jus1d 9084169
chore: move implementation of abi.Executor to ton.Client
jus1d a4de79b
chore: hide tonconnect.Server inside of ton.Client
jus1d e746327
chore: Move tonproof logic into service
jus1d 498b5c8
chore: add caching balance
jus1d 9e7bb60
chore: remove logging from auth mw
jus1d 2b846ca
chore: Implement mnemonic encryption
jus1d 0a68ad6
test: cover ./pkg/ with tests
jus1d f5e231d
migrations: sucked into one master migration
jus1d c7b277e
chore: Add request_id to every error response
jus1d 2a0722c
fix: correctly return is_admitted after payment
jus1d d670b3d
chore: Improve validation, error handling, and consistency across con…
jus1d d36a5cb
deps: Update `crypto` to 0.45.0
jus1d File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,3 +10,7 @@ build | |
| # Ignore TODO | ||
| TODO | ||
| buffer | ||
|
|
||
| migrations/data.up.sql | ||
|
|
||
| *.diff | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| package distributor | ||
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
| "fmt" | ||
| "log/slog" | ||
| "math/big" | ||
|
|
||
| "github.com/jackc/pgx/v5" | ||
| "github.com/voidcontests/api/internal/lib/crypto" | ||
| "github.com/voidcontests/api/internal/storage/models" | ||
| "github.com/voidcontests/api/internal/storage/repository" | ||
| "github.com/voidcontests/api/pkg/ton" | ||
| "github.com/xssnick/tonutils-go/address" | ||
| "github.com/xssnick/tonutils-go/tlb" | ||
| ) | ||
|
|
||
| func New(r *repository.Repository, tc *ton.Client, cipher crypto.Cipher) func(ctx context.Context) error { | ||
| return func(ctx context.Context) error { | ||
| contests, err := r.Contest.GetWithUndistributedAwards(ctx) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| for _, c := range contests { | ||
| err := distributeAwardForContest(ctx, r, tc, cipher, c) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
| } | ||
|
|
||
| func distributeAwardForContest(ctx context.Context, r *repository.Repository, tc *ton.Client, cipher crypto.Cipher, c models.Contest) error { | ||
| w, err := r.Contest.GetWallet(ctx, *c.WalletID) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| decryptedMnemonic, err := cipher.Decrypt(w.MnemonicEncrypted) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to decrypt mnemonic: %w", err) | ||
| } | ||
|
|
||
| wallet, err := tc.WalletWithSeed(decryptedMnemonic) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| winnerID, err := r.Contest.GetWinnerID(ctx, c.ID) | ||
| if errors.Is(err, pgx.ErrNoRows) { | ||
| slog.Info("no users that submitted at least one ok solution", slog.Int("contest_id", c.ID)) | ||
| return nil | ||
| } | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| winner, err := r.User.GetByID(ctx, winnerID) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if winner.Address == "" { | ||
| return fmt.Errorf("user has no wallet") | ||
| } | ||
|
|
||
| recepient, err := address.ParseAddr(winner.Address) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| nanos, err := tc.GetBalance(ctx, wallet.Address()) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // keep 2% for paying gas | ||
| factor := 1 - 0.02 | ||
| amount := tlb.FromNanoTON(big.NewInt(int64(float64(nanos) * factor))) | ||
| tx, err := wallet.TransferTo(ctx, recepient, amount, fmt.Sprintf("contests.fckn.engineer: Prize for winning contest #%d", c.ID)) | ||
|
||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| slog.Info("award distributed", slog.Int("contest_id", c.ID), slog.String("tx", tx)) | ||
|
|
||
| paymentID, err := r.Payment.Create(ctx, tx, tc.GetAddress(wallet.Address()), tc.GetAddress(recepient), amount.Nano().Uint64(), false) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| err = r.Contest.SetDistributionPaymentID(ctx, c.ID, paymentID) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable name "recepient" is misspelled. It should be "recipient" (note the 'i' before 'e').