Werogram/Документация/CustomFragment gift withdrawal
RUWEROGRAM DOCS

CustomFragment gift withdrawal

CustomFragment replaces the old local-only completion page behind payments.getStarGiftWithdrawalUrl with a self-hosted TON mainnet mint flow. The RPC's existing SRP/2FA check remains the gate: its returned withdrawal URL is a short-lived bearer capability. Username minting is not implemented.

Contracts

The upstream TON reference implementation requested for new collections is vendored at contracts/nft-v1.1. It is the ton-blockchain/acton-contracts nft-v1.1 package (including its wrappers, scripts, and tests), with only a local Acton manifest pinned to 1.1.0 so it can be built reproducibly alongside gramsrv.

cd contracts/nft-v1.1
acton build NftCollection
acton test tests

That reference collection deliberately accepts deployment messages only from its admin address. The already deployed InvGram Gifts collection remains the signed-mint compatibility collection for existing withdrawal URLs; it is not replaced in place (TON contract addresses and storage layouts are immutable). A new upstream collection can be deployed for a future relayer flow after its admin wallet and collection address are configured.

The contracts in contracts/customfragment are an idiomatic typed Tolk rewrite of the minting subset of Telegram's GPL-3.0 TeleMint contracts. They use a new storage layout and deterministic item address scheme, so they are not address- compatible with the original FunC contracts.

cd contracts/customfragment
acton build
acton test --coverage --coverage-format text
acton wrapper CustomFragmentCollection
acton wrapper CustomFragmentItem

Deploy CustomFragmentItem, then deploy CustomFragmentCollection with:

  • subwalletId: the configured uint32 (default 1196573005, ASCII GRAM);
  • publicKey: the Ed25519 public key printed by telesrv on startup;
  • itemCode: the compiled CustomFragment item code;
  • collection metadata and royalty cells for the deployment.

Deployment is intentionally an operator action: telesrv will never deploy a mainnet contract or generate/replace the mint authority key automatically. The included deploy-mainnet Acton script deploys the collection from the global customfragment-deployer wallet and takes the authority seed only from CUSTOM_FRAGMENT_SIGNING_SEED.

Server configuration

Set the TELESRV_CUSTOM_FRAGMENT_* variables documented in .env.example and enable the public Web listener. The collection address must be a TON basechain mainnet address. Keep the signing key outside the repository with restrictive filesystem permissions.

Set TELESRV_CUSTOM_FRAGMENT_PUBLIC_BASE_URL to a dedicated HTTPS host served by the same Web listener. It must differ from the native client's internal link host; otherwise Android may parse /gift-withdrawal/{token} as a username link instead of opening the browser.

The browser sends a wallet-bound, five-minute authorization to TON Connect. The server does not accept the wallet callback as proof. It derives the expected NFT address with get_nft_address_by_index, reads get_nft_data through proof- checking mainnet lite servers, and atomically marks the gift exported only when the index, collection and owner all match.

The claim path uses the same fail-closed compare-and-swap rule: the database owner observed when a TON Proof challenge is issued must still be the owner when the single-use challenge is committed. A concurrent ownership sync or second claim therefore returns a conflict instead of overwriting a newer projection.

Public routes:

  • /custom-fragment — service and collection information;
  • /gift-withdrawal/{token} — private mint page returned by the TL method;
  • /custom-fragment/tonconnect-manifest.json — TON Connect manifest;
  • /custom-fragment/collection.json — TEP-64 metadata for InvGram Gifts;
  • /custom-fragment/metadata/gift/{slug}.json — TEP-64 metadata;
  • /custom-fragment/media/gift/{slug}.png — rendered gift poster with its backdrop, tiled pattern, and model rest frame;
  • /custom-fragment/media/gift/{slug}.lottie.json — the selected model's raw Lottie JSON, cached in memory and suitable for client-side animation.

The public Web listener also exposes /botfather and /stickers as local Telegram-style mini apps. They use only relative /api/miniapps/* requests; creation is delegated to the existing bot/files services and requires signed Telegram initData. A newly generated bot token is returned once over the server response and is not retained by the page.

The media routes and all metadata URLs use TELESRV_CUSTOM_FRAGMENT_PUBLIC_BASE_URL, so CustomFragment can live on a dedicated HTTPS host while the main server keeps its normal public URL.