> ## Documentation Index
> Fetch the complete documentation index at: https://companyname-a7d5b98e-v2-pagination.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Gasless transactions

export const Aside = ({type = "note", title = "", icon = "", iconType = "regular", children}) => {
  const asideVariants = ["note", "tip", "caution", "danger"];
  const asideComponents = {
    note: {
      outerStyle: "border-sky-500/20 bg-sky-50/50 dark:border-sky-500/30 dark:bg-sky-500/10",
      innerStyle: "text-sky-900 dark:text-sky-200",
      calloutType: "note",
      icon: <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-sky-500" aria-label="Note">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M7 1.3C10.14 1.3 12.7 3.86 12.7 7C12.7 10.14 10.14 12.7 7 12.7C5.48908 12.6974 4.0408 12.096 2.97241 11.0276C1.90403 9.9592 1.30264 8.51092 1.3 7C1.3 3.86 3.86 1.3 7 1.3ZM7 0C3.14 0 0 3.14 0 7C0 10.86 3.14 14 7 14C10.86 14 14 10.86 14 7C14 3.14 10.86 0 7 0ZM8 3H6V8H8V3ZM8 9H6V11H8V9Z"></path>
        </svg>
    },
    tip: {
      outerStyle: "border-emerald-500/20 bg-emerald-50/50 dark:border-emerald-500/30 dark:bg-emerald-500/10",
      innerStyle: "text-emerald-900 dark:text-emerald-200",
      calloutType: "tip",
      icon: <svg width="11" height="14" viewBox="0 0 11 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="text-emerald-600 dark:text-emerald-400/80 w-3.5 h-auto" aria-label="Tip">
          <path d="M3.12794 12.4232C3.12794 12.5954 3.1776 12.7634 3.27244 12.907L3.74114 13.6095C3.88471 13.8248 4.21067 14 4.46964 14H6.15606C6.41415 14 6.74017 13.825 6.88373 13.6095L7.3508 12.9073C7.43114 12.7859 7.49705 12.569 7.49705 12.4232L7.50055 11.3513H3.12521L3.12794 12.4232ZM5.31288 0C2.52414 0.00875889 0.5 2.26889 0.5 4.78826C0.5 6.00188 0.949566 7.10829 1.69119 7.95492C2.14321 8.47011 2.84901 9.54727 3.11919 10.4557C3.12005 10.4625 3.12175 10.4698 3.12261 10.4771H7.50342C7.50427 10.4698 7.50598 10.463 7.50684 10.4557C7.77688 9.54727 8.48281 8.47011 8.93484 7.95492C9.67728 7.13181 10.1258 6.02703 10.1258 4.78826C10.1258 2.15486 7.9709 0.000106649 5.31288 0ZM7.94902 7.11267C7.52078 7.60079 6.99082 8.37878 6.6077 9.18794H4.02051C3.63739 8.37878 3.10743 7.60079 2.67947 7.11294C2.11997 6.47551 1.8126 5.63599 1.8126 4.78826C1.8126 3.09829 3.12794 1.31944 5.28827 1.3126C7.2435 1.3126 8.81315 2.88226 8.81315 4.78826C8.81315 5.63599 8.50688 6.47551 7.94902 7.11267ZM4.87534 2.18767C3.66939 2.18767 2.68767 3.16939 2.68767 4.37534C2.68767 4.61719 2.88336 4.81288 3.12521 4.81288C3.36705 4.81288 3.56274 4.61599 3.56274 4.37534C3.56274 3.6515 4.1515 3.06274 4.87534 3.06274C5.11719 3.06274 5.31288 2.86727 5.31288 2.62548C5.31288 2.38369 5.11599 2.18767 4.87534 2.18767Z"></path>
        </svg>
    },
    caution: {
      outerStyle: "border-amber-500/20 bg-amber-50/50 dark:border-amber-500/30 dark:bg-amber-500/10",
      innerStyle: "text-amber-900 dark:text-amber-200",
      calloutType: "warning",
      icon: <svg className="flex-none w-5 h-5 text-amber-400 dark:text-amber-300/80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-label="Warning">
          <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
        </svg>
    },
    danger: {
      outerStyle: "border-red-500/20 bg-red-50/50 dark:border-red-500/30 dark:bg-red-500/10",
      innerStyle: "text-red-900 dark:text-red-200",
      calloutType: "danger",
      icon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" className="text-red-600 dark:text-red-400/80 w-4 h-4" aria-label="Danger">
          <path d="M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zm41.6-48c-4.3 7.4-4.3 16.6 0 24l88.3 152.9c4.3 7.4 12.2 12 20.8 12l176.6 0c8.6 0 16.5-4.6 20.8-12L453.4 268c4.3-7.4 4.3-16.6 0-24L365.1 91.1c-4.3-7.4-12.2-12-20.8-12l-176.6 0c-8.6 0-16.5 4.6-20.8 12L58.6 244zM256 128c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"></path>
        </svg>
    }
  };
  let variant = type;
  let gotInvalidVariant = false;
  if (!asideVariants.includes(type)) {
    gotInvalidVariant = true;
    variant = "danger";
  }
  const iconVariants = ["regular", "solid", "light", "thin", "sharp-solid", "duotone", "brands"];
  if (!iconVariants.includes(iconType)) {
    iconType = "regular";
  }
  return <>
      <div className={`callout my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border ${asideComponents[variant].outerStyle}`} data-callout-type={asideComponents[variant].calloutType}>
        <div className="mt-0.5 w-4" data-component-part="callout-icon">
          {}
          {icon === "" ? asideComponents[variant].icon : <Icon icon={icon} iconType={iconType} size={14} />}
        </div>
        <div className={`text-sm prose min-w-0 w-full ${asideComponents[variant].innerStyle}`} data-component-part="callout-content">
          {gotInvalidVariant ? <p>
              <span className="font-bold">
                Invalid <code>type</code> passed!
              </span>
              <br />
              <span className="font-bold">Received: </span>
              {type}
              <br />
              <span className="font-bold">Expected one of: </span>
              {asideVariants.join(", ")}
            </p> : <>
              {title && <p className="font-bold">{title}</p>}
              {children}
            </>}
        </div>
      </div>
    </>;
};

Gasless transactions execute wallet operations when the wallet owner does not hold Toncoin to pay [network fees](/foundations/fees). A relayer service and its on-chain contract submit transactions on behalf of users and attach Toncoin to cover gas costs.

<Aside type="note">
  The wallet contract must support owner-signed internal messages — implementations that only accept external messages cannot participate in gasless flows.
</Aside>

## How it works

### Core mechanism

On TON, every smart contract processes two message types:

* External messages: arrive from outside the blockchain. When a wallet contract receives an external message, it pays gas from its own Toncoin balance.
* Internal messages: arrive from other contracts. Gas is paid from Toncoin attached to the message.

Gasless transactions use internal messages: the relayer's contract sends an internal message with attached Toncoin to the wallet contract. The wallet executes actions without spending its own balance.

### Architecture

Regular transfers:

```mermaid theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
flowchart LR
  U1["User (off-chain)"] -->|External msg| W1["Wallet (pays for fees)"] --> A1([Actions])
```

Gasless transfers:

```mermaid theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
flowchart LR
  U2["User (off-chain)"] -->|External msg with payload| R["Relayer (pays for fees)"] -->|Internal msg| W2[Wallet] --> A2([Actions])
```

Three components enable gasless transactions:

1. Wallet contract with authenticated internal message support
2. Relayer service that validates and submits transactions
3. Signature scheme that proves user authorization

### Transaction flow

#### Step 1: User creates signed payload

The user's wallet application:

* Constructs an action list (transfers, contract calls)
* Adds replay protection (sequence number, expiration timestamp)
* Signs with the wallet's private key
* Sends signed payload to relayer via an API

#### Step 2: Relayer validates

The relayer verifies off-chain:

* Signature is authentic (confirmed with the wallet's public key)
* Sequence number matches the current wallet state
* Expiration timestamp is valid
* Payment terms are met (if applicable)

#### Step 3: Relayer submits internal message

The relayer's contract sends an internal message to the user's wallet:

* Attaches sufficient Toncoin for gas
* Includes the user's signed payload as the message body
* Spends the relayer's Toncoin, not the user's

#### Step 4: Wallet executes

The wallet contract:

* Verifies signature on-chain
* Checks replay protection
* Executes signed actions using attached Toncoin
* Increments sequence number

The blockchain sees a standard internal message. Authentication happens inside the wallet contract.

## Payment models

Relayers use different models to recover gas costs:

* Jetton payment: the user includes a jetton transfer to the relayer in the signed action list. The relayer receives jettons after transaction execution.
* Prepaid credits: the user purchases credits off-chain. The relayer deducts credits per transaction. No on-chain payment.
* Sponsorship: the relayer covers costs without payment. Common for onboarding, promotions, or subsidized dApp actions. Requires abuse prevention (rate limits, address restrictions).

## Security

### Cryptographic protection

The user's signature covers all actions and replay protection data. The wallet contract verifies the signature on-chain before execution.

Guarantees:

* Relayer cannot modify actions, recipients, or amounts
* Relayer cannot forge transactions
* Relayer cannot replay old transactions (sequence numbers prevent this)
* Relayer cannot use expired signatures (expiration timestamps prevent this)

Any modification invalidates the signature and causes rejection.

### Relayer trust requirements

The relayer controls transaction submission but cannot compromise funds:

The relayer can:

* Refuse to submit transactions (censorship)
* Delay submission (timing attacks)
* Observe transaction content before submission (privacy loss)

The relayer cannot:

* Modify signed actions
* Steal funds
* Create unauthorized transactions

Users depend on relayer availability and honesty for submission, but funds remain cryptographically protected.

### MEV and front-running

The relayer sees transaction content before blockchain submission, which enables value extraction:

* Sandwich attacks: for DEX trades, the relayer can submit its own transactions before and after the user's transaction to profit from price impact.
* Transaction reordering: the relayer can delay or reorder transactions to maximize profit, particularly in DeFi scenarios where order matters.

Mitigation:

* Use short expiration windows (60-300 seconds)
* Choose relayers with reputation systems
* For high-value operations, use direct external messages when Toncoin is available
* Monitor for suspicious delays or failures

### Operational risks

* Insufficient gas: if the relayer attaches too little Toncoin, execution fails. The wallet's sequence number does not increment, so the user can retry with the same signed payload.
* Network congestion: gas costs spike during high load. Relayers may refuse service or increase fees temporarily.
* Jetton payment risks: jetton contracts may have restrictions, insufficient balance, or bugs. Relayers should emulate transactions off-chain before spending Toncoin.
* Prepaid credit risks: users trust the relayer to honor off-chain credit balances. No on-chain recourse if the relayer refuses service.
* Sponsorship abuse: without rate limits and address restrictions, attackers can drain relayer resources through spam.

### Relayer compromise

If a relayer's infrastructure is breached:

The attacker gains:

* Visibility into pending transactions
* User IP addresses and metadata
* Ability to censor transactions

The attacker does not gain:

* Ability to forge signatures
* Ability to steal funds
* Ability to modify signed actions

Users can switch to alternative relayers or use external messages once Toncoin is available.

## Example: jetton payment

Alice wants to send 100 USDT to Bob but has zero Toncoin. The relayer charges 0.5 USDT.

Alice's wallet:

1. Creates actions: send 100 USDT to Bob, send 0.5 USDT to the relayer
2. Adds a sequence number (e.g., 42) and expiration (e.g., 5 minutes)
3. Signs with the private key
4. Sends signed payload to relayer API

Relayer:

1. Verifies signature against Alice's public key
2. Checks that the sequence number is 42 (matches wallet state)
3. Checks that the expiration is valid
4. Sends internal message to Alice's wallet with 0.1 Toncoin attached

Alice's wallet contract:

1. Receives the internal message
2. Verifies signature
3. Checks that the sequence number is 42 and the expiration is valid
4. Executes both USDT transfers using attached 0.1 Toncoin for gas
5. Increments sequence number to 43

Result:

* Alice: 0 Toncoin (unchanged), -100.5 USDT
* Bob: +100 USDT
* Relayer: -0.1 Toncoin, +0.5 USDT

The relayer accumulates USDT fees and exchanges them for Toncoin periodically.

## Limitations

Not a protocol feature: gasless transactions are an application-layer pattern. The blockchain does not enforce or guarantee relayer behavior.

Wallet requirement: the wallet contract must support authenticated internal messages. Not all wallet implementations provide this. In practice, only Wallet v5 reference contracts currently implement owner-signed internal messages.

No standardization: relayer APIs, fee structures, and supported assets vary. Each integration requires custom implementation.

[TON Connect](/ecosystem/ton-connect/overview) incompatibility: currently, TON Connect does not support gasless. The `sendTransaction` method does not return signed payloads to dApps — it submits transactions directly. Gasless requires obtaining signed payloads and forwarding them to relayers off-chain.

<Aside type="note">
  dApps that need gasless must implement custom signing flows outside TON Connect. Users sign payloads directly via a browser extension or a native app and send them to relayers via an API.
</Aside>

Centralization: users depend on relayer uptime, policies, and willingness to serve requests. Relayers can censor addresses or refuse service.

## Implementation

### Wallet contract requirements

* Accept authenticated internal messages signed by the wallet owner
* Enforce replay protection (sequence numbers, expiration timestamps) for both external and internal messages
* Use distinct operation codes for external and internal entry points to prevent cross-channel replay attacks

### Relayer requirements

* Validate signatures and replay protection off-chain before spending Toncoin
* Attach sufficient Toncoin to cover gas for wallet execution and outgoing actions
* Implement rate limiting and abuse prevention
* For jetton payments, emulate transactions to verify successful execution
* Forward the signed payload verbatim in the internal message body without modifying fields covered by the signature

### Example: wallet v5

The [wallet v5](/standard/wallets/v5) standard supports gasless via the `internal_signed` message format:

* Separate opcodes for external and internal messages prevent replay attacks
* The contract enforces signature verification, sequence numbers, and expiration checks for owner-signed internal messages
* A relayer forwards the signed payload verbatim as the internal message body and attaches Toncoin for gas
