Case · P2P exchange and crypto infrastructure · 2026
P2P exchange, where users exchange USDT, TON and Jetton tokens for rubles directly with each other, and the platform holds the crypto part in its own custody, compares assets with liabilities every half hour and does not release withdrawal until ledger converges to a penny.
A P2P exchange is always a trust between two people who will never meet, plus a crypto part that can neither be lost nor doubled. The user enters USDT on TRC-20, TON or Jetton, puts an ad, agrees with the counter in the chat and expects that after confirmation of payment, the platform will release the crypt - without error per penny and without a second write-off when repeated.
At the same time, the exchange itself does not store money in one wallet “just in case”: TON and Jetton come and go through a separate custodial microservice GRAM, and the site must trust its events exactly as much as it can verify them – signature, idempotence and regular reconciliation of residues.
The seller publishes the order at its rate - fixed or floating from the exchange; the buyer responds, and a transaction is created for the pair with a price fixed at the time of response.
Market · Online coursesThe crypto part of the seller is frozen on the balance sheet immediately so that it cannot be taken into another transaction. The parties agree in chat in real time, attach a check of payment.
Deal · WebSocket via ReverbAn unpaid transaction is automatically canceled by timeout, unconfirmed after payment escalates, and background jobs monitor this regardless of whether the browser is open to the parties.
CancelUnpaidDeal / CancelUnconfirmedDeal / AutoRejectDealIf the parties do not agree, anyone can open a dispute for one of the predefined reasons - the transaction is frozen until the decision of the administrator, who sees the correspondence and the check in its entirety.
AdminDisputeController Causes from the directoryConfirmation of payment removes the freeze and transfers the crypto part to the buyer with a single atomic operation – an intermediate state in which money “nowhere” does not exist.
BalanceService · TransactionalUSDT on TRON, TON and Jetton tokens do not enter the platform in the same way. TRON transfers have their own logic of energy rental and address monitoring, and TON and Jetton do not touch the blockchain directly from the main site at all – this is the responsibility of the GRAM microservice, which the site calls through a signed HMAC-API.
Own TRON wallet on mnemonic keys, monitoring incoming transfers and renting energy for outgoing TRC-20 transfer, so as not to pay a full fee to TRX for each output.
Deposits come with confirmed events from GRAM in crypto_depositsIt is separate from the legacy USDT balance. The minimum amount and network (testnet/mainnet) are checked at the reception, not after the fact.
Only allowlisted tokens, separate endpoint reception and immutable jetton_ledger_entries. Withdrawal reserves the amount and commission immediately, and deducts - only after confirmation from GRAM.
Idempotency-Key and external_idRepeated call returns the same result credited=falseIt doesn't create a second operation.gram:custody:audit Every minute 30 compares managed TON-wallets GRAM with the amount of obligations to users and holds the admission to 0.1 TON on network commissions - the discrepancy over the tolerance goes to the administrator at allert.The user simply exchanges the crypt for rubles with another person in the chat – and under the hood, each penny goes through the freeze, the idempotent ledger and the planned reconciliation of assets, so that neither a double deposit nor a suspended transaction go unnoticed.
Laravel 12 · MySQL · Redis · Laravel Reverb · Vue 3 · Inertia.js · TRC-20 · TON · Jetton · GRAM