From ca1b47b0fc68a7c5c6d97f7d576078014016a296 Mon Sep 17 00:00:00 2001 From: kaladin <335095@niuitmo.ru> Date: Wed, 12 Nov 2025 17:15:28 +0300 Subject: [PATCH 1/5] add processing draft --- payments/jettons.mdx | 139 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 2 deletions(-) diff --git a/payments/jettons.mdx b/payments/jettons.mdx index 97a171405..8227e6623 100644 --- a/payments/jettons.mdx +++ b/payments/jettons.mdx @@ -3,6 +3,141 @@ title: "Jettons payments processing" sidebarTitle: "Jettons" --- -import { Stub } from '/snippets/stub.jsx'; +import { Aside } from "/snippets/aside.jsx"; - +Processing jetton payments requires understanding TON's sharded token architecture. Unlike single-contract token systems, each jetton type consists of a master contract and individual wallet contracts for each holder. + + + + + +## Key concepts + +Before implementing jetton payment processing, understand these core concepts: + +**Jetton architecture**: Each jetton type has one master contract that stores metadata and total supply. Each address holding the jetton has a separate jetton wallet contract at a deterministic address derived from the master contract and owner address. + +**Transfer flow**: Jetton transfers involve multiple messages. A user sends a `transfer` message to their jetton wallet, which sends an `internal_transfer` to the recipient's jetton wallet, which then sends a `transfer_notification` to the recipient's address if `forward_ton_amount > 0`. + + + +**Security model**: Always validate that jetton wallets belong to the expected master contract. Anyone can deploy fake jetton wallet contracts with arbitrary balances. + +This article covers processing jetton deposits using transfer notifications. All approaches require maintaining a whitelist of trusted jetton master contracts. + +For architectural patterns and deposit methods comparison, see [Toncoin processing](/payments/toncoin). + +## Processing deposits + +### Setup + +To process jetton deposits, you need: + +- **Whitelist of trusted jetton masters**: List of jetton master contract addresses you accept +- **Deposit wallet address**: Your service's wallet (e.g., wallet v4 or v5) + +### Initial configuration + +1. For each whitelisted jetton master, derive the jetton wallet address for your deposit wallet using the master contract's `get_wallet_address()` method +2. Store the mapping of `jetton master` → `jetton wallet` → `deposit wallet` in your database +3. Begin monitoring transactions to the deposit wallet address + +### Processing incoming transactions + +When a transaction arrives at your deposit wallet: + +1. Check that `tx.in_msg.source` matches a known jetton wallet for this deposit wallet +2. Verify the master → jetton wallet relationship: + - Call `get_wallet_address(deposit-wallet)` on the master contract + - Confirm the returned address matches the sender +3. Verify there are no outgoing messages (`tx.out_msgs.length === 0`) +4. Parse the message body: + - Check the opcode (first 32 bits of `tx.in_msg.body`) equals `0x7362d09c` (transfer_notification) + - Extract `query_id`, `amount`, `sender`, and `forward_payload` [according to TL-B](/standard/tokens/jettons/api) +5. Verify the amount matches your expected value + +### Crediting user accounts + +After validation, extract deposit information: + +- **For invoice-based deposits**: Parse the invoice ID from `forward_payload`, match it against your database, and credit the corresponding user account +- **For address-based deposits**: Match the `deposit-wallet` address against your database and credit the user account + + + +## Security considerations + +### Master-wallet verification + +Never trust jetton wallet addresses without verification. Always perform these checks: + +1. Get the jetton master address from your whitelist +2. Call `jetton_master.get_wallet_address(owner_address)` +3. Verify the returned address matches the jetton wallet that sent the notification + +### Transfer notification validation + +When processing deposits via `transfer_notification`: + +- Verify the opcode is exactly `0x7362d09c` +- Check the sender address is an expected jetton wallet +- Extract `amount` in base units (not decimal) +- Validate the `sender` field against expected user addresses +- Parse `forward_payload` carefully—it may be malformed +- Check for bounce indicators (single outgoing message back to sender) + +### Fake jetton detection + +Attackers can deploy jettons with identical names, symbols, and images: + +- Always verify the jetton master address against your whitelist +- Never trust metadata (name, symbol, image) for authentication +- Display the master contract address in admin interfaces +- Implement a manual approval workflow for adding new jettons + +## Common attack patterns + +### Fake jetton wallets + +**Attack**: Attacker deploys a contract claiming to be a jetton wallet with an inflated balance. + +**Mitigation**: Verify the master-wallet relationship by calling `get_wallet_address()` on the master contract. + + +### Invoice ID reuse + +**Attack**: User attempts to reuse a settled invoice identifier. + +**Mitigation**: Mark invoices as used after the first successful deposit. + + +### Master contract spoofing + +**Attack**: Deploying a fake master contract that validates the attacker's fake jetton wallets. + +**Mitigation**: Maintain a strict whitelist of trusted master contracts and verify all jetton wallets against it. + +## Implementation checklist + +Before enabling jetton processing in production: + +### Testing + +- [ ] Deploy and test on testnet with real user scenarios +- [ ] Verify master-wallet relationships for all whitelisted jettons +- [ ] Test with fake jetton wallets to confirm rejection +- [ ] Validate transfer notification parsing with various payload formats +- [ ] Test bounce detection and handling +- [ ] Test invoice ID collision and reuse scenarios +- [ ] Test full flow: deposit → credit → withdrawal → confirmation From d2a2e2c5523f19fc1af6888436a97d63eca647b5 Mon Sep 17 00:00:00 2001 From: kaladin <335095@niuitmo.ru> Date: Wed, 12 Nov 2025 17:53:37 +0300 Subject: [PATCH 2/5] fix link --- payments/jettons.mdx | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/payments/jettons.mdx b/payments/jettons.mdx index 8227e6623..3a83cf20c 100644 --- a/payments/jettons.mdx +++ b/payments/jettons.mdx @@ -35,6 +35,13 @@ For architectural patterns and deposit methods comparison, see [Toncoin processi ## Processing deposits + + ### Setup To process jetton deposits, you need: @@ -69,13 +76,14 @@ After validation, extract deposit information: - **For invoice-based deposits**: Parse the invoice ID from `forward_payload`, match it against your database, and credit the corresponding user account - **For address-based deposits**: Match the `deposit-wallet` address against your database and credit the user account - -