anti-gambling-trader-tw
Free open-source investment anti-fraud, trading statistics and automated trading program tools: default PaperBroker, provides 14 broker/exchange options; trade record analysis runs locally.
AI translation
PriTok automates bond corporate actions on Solana: record date, calculation, one-click payout to every holder, a receipt for each payment.
Translation pending
FinanceTypeScript · RustGitHub @ssadkovOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Bond registry and payouts on Solana — corporate actions for tokenized bonds (devnet prototype)
Taken from the repository README
Loading the full README.
Read the full README ↗Bond registry and payouts on Solana. Pritok is Russian for "inflow": coupons and principal flowing to bondholders on schedule. The name also reads as PRIncipal + TOKens.
PRITOK services a tokenized bond after placement — the job of a registrar and a paying agent. It knows who held the bond on each record date, calculates what every holder is owed, and lets the platform operator execute each corporate action for all holders with one command: pay onchain or route to a bank, retire the bonds at maturity. It shows publicly when an issuer has not paid. Every entitlement and every payment can be checked in the Solana explorer.
Built for the Superteam Kazakhstan × KASE side track Corporate Actions on Blockchain. Independent prototype, not affiliated with KASE.
| Video | https://youtu.be/LSAAGoHZc4w — two-minute pitch |
| Live demo | https://pritok-sol.vercel.app/demo — Solana devnet, role screens with one-click demo signing (project page) |
| Program | 9LMSMqD3xMBaNdfRb4bKDT3MBTX8ry1Na84rMSJ787aY on devnet |
| Full lifecycle on devnet | FCNB…C6ry — coupons, 20% amortization, a default and its cure, wallet and bank payouts, redemption with burn |
| Operator-run lifecycle | H9xK…mdja — every coupon and the redemption executed by the operator, bonds burned by the program |
| Tests | 21 passing: 7 unit, 14 integration on LiteSVM |
?lang=kk|en|ru to a link). In about 10 seconds the bond is created, three investors are admitted, and the issue is placed among them 30% / 20% / 50% (by default 1 000 bonds of 100 000 ₸ at 16%). Time is accelerated: one half-year lasts four minutes, so the whole two-year issue plays out in about 17 minutes.How it works replays a 9-step tour of the screen. A ? next to a term explains it in plain language.
| Requirement | How PRITOK does it | Where to see it |
|---|---|---|
| Test tokenized instrument with holder registry | Token-2022 bond mint, one holder record per wallet per bond, admission by the operator | Registry at date, operator console |
| Coupon payment: holders on the record date | Record-date balances frozen onchain at every balance change (see record dates) | Holder register as of |
| Coupon: calculate each investor's entitlement | units at record date × coupon per bond, per holder | Calculation panel of any event |
| Coupon: execute onchain or show a settlement flow | Both. The operator executes the payout for all holders with one command (pay_holder), or a holder claims; to the wallet in stablecoin, or to a paying agent with bank confirmation | Operator console, event card stages |
| Redemption: identify holders, principal due | Transfers close at the maturity record date; principal on the current face after amortization | Maturity event |
| Redemption: settle and retire tokens | redeem_for (operator) or redeem (holder) burns the bonds and pays principal + last coupon atomically | Operator console, "N redeemed and burned", journal |
| One additional corporate action | Partial redemption (amortization), plus secondary DvP trade with accrued interest and default & cure | Issuer screen, sale form |
| Verifiable onchain record | Receipt account per payout, every operation decoded in the journal with an explorer link | Journal, "to wallet ↗" receipt links |
| Clear line between implemented and simulated | Table below | — |
flowchart LR
subgraph Solana devnet
P[pritok program]
B[(Bond account<br/>terms + event schedule)]
H[(Holder account<br/>per wallet per bond)]
C[(Claim receipt<br/>per payout)]
M[Token-2022 bond mint<br/>accounts always frozen]
V[Payment vault<br/>tKZT, owned by the bond]
P --- B & H & C
P -- thaw / move / freeze / burn --> M
P -- pays out --> V
end
W[Next.js web app<br/>registry, roles, portfolio] -- reads accounts + decoded history --> P
W -- demo signing, devnet only --> P
| Component | Role |
|---|---|
programs/pritok | Anchor program: 18 instructions, all corporate-action logic and money movement |
| Token-2022 bond mint | DefaultAccountState = Frozen; mint and freeze authority is the bond PDA |
| tKZT | Test tenge (classic SPL token, 2 decimals) used for placement, payouts and trades |
web/ | Next.js: public registry, operator console, issuer and investor screens, all-issues list, portfolio. Reads accounts and decodes the program's transaction history server-side |
client/ | TypeScript client shared with the web app, and a scripted end-to-end devnet scenario |
| Account | Seeds | Holds |
|---|---|---|
Config | ["config"] | platform operator (registrar and paying agent), pause flag, allowed payment tokens |
Bond | ["bond", issuer, bond_id] | terms, current face factor, issued_units, supply, reserved obligations, up to 8 events sorted by record date |
| Bond mint | ["mint", bond] | Token-2022 mint, 0 decimals |
| Payment vault | ATA of the bond PDA | funded, not yet claimed obligations |
Holder | ["holder", bond, wallet] | admission flag, balance, record-date balances |
Claim | ["claim", bond, action_id, wallet] | one payout: units, amount, wallet / bank requested / bank confirmed, payment-reference hash |
| Who | Instructions |
|---|---|
| Operator | init_config, allow_holder, revoke_holder, set_paused, pay_holder, redeem_for, claim_to_bank (for a holder), confirm_bank_payment |
| Issuer | create_bond (from the issuer's form), fund_action, declare_partial_redemption |
| Holder | subscribe, transfer_bond, trade_dvp (with the counterparty), claim, claim_to_bank, redeem |
| Anyone | close_subscription, mark_default |
A Solana program cannot iterate over token holders, and an offchain snapshot is not verifiable. PRITOK records balances lazily instead.
action_id and a position in that order.Example from the demo: Aigerim holds 300, Bolat 200, the fund 500. Aigerim sends 10 to Bolat before coupon 1's record date, and Bolat sends 10 to the fund after it. Coupon 1 is paid on 290 / 210 / 500; coupon 2 on 290 / 200 / 510.
Rules that keep this correct, each covered by a test:
issued_units); later burns do not shrink what is owed.AccountFrozen.redeem_for, against a principal payment. Issues created before 2026-10-10 lack the extension; their holders redeem by themselves.| Event | Per bond | Required from the issuer |
|---|---|---|
| Coupon | face × factor × coupon_rate / 2; the factor is the one in force for the whole coupon period | per bond × issued_units |
| Partial redemption | face × redeemed share | funded in full when declared |
| Maturity | face × current factor | per bond × issued_units |
| Accrued interest (trade) | next coupon × elapsed share of the period; zero between the record and payment dates | paid by the buyer |
Amounts are rounded down per holder; any dust stays in the vault. The issuer never withdraws from the vault.
| Convention | Kazakhstan practice | PRITOK |
|---|---|---|
| Record date | Art. 31(2) of the Law "On the Securities Market": holders are fixed as of the start of the last day of the period the payment is for; older issues may keep a longer window set in their terms | record_offset_secs is set per issue: one day for a real issue, longer where the prospectus says so. The demo stretches it to 30 seconds out of a 240-second "half-year", so a transfer after the record date can be shown |
| Coupon amount | Day-count basis 30/360 is standard on KASE | A semi-annual coupon is face × rate / 2, which is what 30/360 gives for a full regular period |
| Accrued interest | 30/360 | Linear in actual time within the coupon period. Close to 30/360, but not identical around month ends. A 30/360 calendar for real-dated issues is on the roadmap |
| Rounding | Tiyn | Amounts are held in tiyn (2 decimals) and rounded down per holder |
pay_holder for every holder of record, several per transaction: the vault pays each holder's own token account and creates the receipt. At maturity redeem_for pays principal and the last coupon and burns the bonds. The money can only go to the holder's own account.TradeSettled event.The vault invariant vault balance ≥ funded and unclaimed obligations is checked after every money movement.
| Role | Can | Cannot |
|---|---|---|
| Issuer | create the bond, fund events, declare partial redemptions | change terms or the schedule alone, touch the registry, withdraw from the vault |
| Platform operator (registrar and paying agent) | execute payouts and redemptions to holders' own accounts, route a holder's payout to the bank, admit and revoke holders, pause subscriptions and transfers, confirm bank payouts | issue bonds, change terms, send investors' money anywhere but their own account or the paying agent |
| Holder | subscribe, transfer, trade, claim to the wallet or the bank, redeem | change anything about the bond |
| Anyone | mark an underfunded event as defaulted, read everything | — |
Revocation and pause never cancel a payout that already exists: a revoked or paused holder still receives recorded coupons and principal.
| Implemented onchain | Simulated |
|---|---|
| Bond token, holder registry, admission and revocation, pause | KYC: the registrar simply admits an address |
| Record dates, entitlements, coupons, partial redemption, maturity with burn | tKZT instead of a real tenge stablecoin; the payment token is a parameter, so KZTE or another stablecoin replaces it without code changes |
| Default, public issuer debt and cure | Accelerated time: a "half-year" is minutes |
| Bank payout up to the paying agent, confirmation with a payment-reference hash | The bank transfer itself: the confirmation is the paying agent's statement |
| DvP trade with program-computed accrued interest | Price discovery: the parties agree the clean price; there is no order book |
| — | Demo signing: the web server signs with devnet demo keys; in production each party signs on its own device or through a broker or custodian |
Operator console: every corporate action of the issue with its stage. Coupon 1 executed for all three holders, coupon 2 funded and ready to execute with one command, later events waiting for the issuer.
| Issuer's form: face value, coupon, term and size, with the coupon per bond and what the issuer raises and pays back | Investor portfolio: result, payouts due now, next payout, calendar, holdings, history |
cargo test -p pritok). Integration tests run the compiled program on LiteSVM with a controllable clock:
AccountFrozen;docs/REVIEW-BRIEF.md and docs/PLAN.md). The first round replaced a transfer hook with always-frozen accounts after finding bypasses via owner burn and SetAuthority. The second fixed amortization timing, fixed issued_units, restricted payment mints and added the vault reserve.Anchor 0.32.1, Agave 3.1.12, Rust 1.89.
anchor build
cargo test -p pritok
On Windows, scripts/wsl-test.sh builds and tests in the WSL filesystem, which is much faster than /mnt/c.
Web app:
cd web && npm install
cp .env.example .env.local # RPC_URL: a dedicated devnet RPC; DEMO_SIGNING=1 for the role buttons
npm run dev # http://localhost:3100
With DEMO_SIGNING=1 the server signs with devnet demo keys: locally from client/.keys, on a host such as Vercel from DEMO_KEYS (JSON of secret-key byte arrays; Root Directory web). Anyone with the link can press the buttons, so use it on devnet only. The public devnet RPC rate-limits the registry reads; use a dedicated endpoint such as Helius.
Scripted scenarios:
cd client && npm install
npm run scenario # full lifecycle, about 11 minutes
MODE=setup npm run scenario # create and place a bond, continue from the UI
../scripts/drive-sandbox.sh <bond> # drive a setup bond to maturity through the web API
programs/pritok/ Anchor program and LiteSVM tests
client/ TypeScript client and the devnet scenario
web/ Next.js app: registry, role screens, issues list, portfolio
docs/PLAN.md plan, design decisions and status (Russian)
docs/REVIEW-BRIEF.md brief used for the independent design review
scripts/ WSL build and test, sandbox driver
PRITOK — реестр держателей и платёжный агент для токенизированных облигаций на Solana.
Демо: https://pritok-sol.vercel.app. Нажмите «Новый демо-выпуск» и следуйте подсказке «Сейчас».