Skip to main content
Version: 0.4.1

Send XTZ

The Send screen lets you transfer XTZ to any Tezos (tz1 / tz2 / tz3 / KT1) or EVM (0x…) address. The wallet auto-detects the destination runtime and picks the cheapest valid routing path under the hood.

Steps

  1. Click Send XTZ on the Home screen
  2. Stage 1 — Form: enter the destination address and amount
  3. Stage 2 — Review: confirm destination, amount, and the routing path
  4. Stage 3 — Sent: view the transaction hash and return home

Accepted address formats

The destination field accepts any of:

FormatExampleRouting
tz1…tz1VSUr8wwNhLAzempoch5d6hLRiTh8CjcjbSame-runtime · Michelson (native)
tz2…tz2TSvNTh2epDMhZHrw73nV9piBX7kLZ9K9mSame-runtime · Michelson (native)
tz3…tz3Nk25mfsfsceBdHXDqHDP6KpUNAbGxksZXSame-runtime · Michelson (native)
KT1…KT18oDJJKXMKhfE1bSuAPGp92pYcwVDiqsPwSame-runtime · Michelson (native, default unit)
0x…0x1234…abcdCross-runtime · L1 → L2 via NAC gateway

The Send page surfaces this in real time via a RoutingCard below the recipient input — the pill colour and caption update as you type.

Amount validation

  • Must be a positive decimal number (e.g. 1, 0.5, 1.23456)
  • Cannot exceed your current XTZ balance
  • Minimum: no enforced minimum (network will reject dust if needed)

How the transaction is sent

The popup sends a SEND_TX { to, amount: hexWei, asset } envelope to the service worker. The service worker branches on detectRuntime(to):

Same-runtime: native Michelson runtime transfer

For any tz1 / tz2 / tz3 / KT1 recipient, the wallet emits a plain Michelson runtime transfer with no contract call:

signer.sendNativeTransfer(to, mutezAmount);
// → toolkit.contract.transfer({ to, amount: mutezAmount, mutez: true })

No NAC gateway, no synthetic EVM hash, no block scanning. The hash returned to the popup is the Michelson op hash (o…, Base58Check, ~51 chars), browsable on tzkt.

Cross-runtime: NAC gateway

For a 0x… recipient, the kernel needs to materialise the value on the EVM runtime. The wallet falls back to the existing relayer path:

  1. provider.request('eth_sendTransaction', [{ to, value: hexWei, data: '0x' }])
  2. GatewayBuilder detects empty calldata → default entrypoint
  3. LocalSignerClient.sendContractCall('default', { string: destination }, mutezAmount) submits a transaction to the NAC gateway (KT18oDJJKXMKhfE1bSuAPGp92pYcwVDiqsPw)
  4. The L1 opHash is converted to a synthetic 32-byte EVM-style hash; the relayer then resolves it to the real kernel-synthesized EVM tx hash by scanning blocks

Amount conversion

The XTZ decimal input is converted to hex wei in the popup, then back to mutez wherever appropriate:

wei   = amount × 10^18      (popup → SW)
mutez = wei / 10^12 (SW → Taquito)

Both sendNativeTransfer and sendContractCall consume mutez. The cross-runtime path keeps wei inside the eth_sendTransaction envelope until the gateway builder converts it.

Stage 3 — Transaction hash

The hash shown on success depends on the routing path:

PathHash formatExplorer
Same-runtime nativeo… Base58 (~51 chars)tzkt
Cross-runtime via gateway0x… 32-byte hexBlockscout (resolved real EVM hash)

The popup truncates either form correctly. A clickable link to the right explorer is on the roadmap for a follow-up patch — for now copy the hash and open it in tzkt or Blockscout depending on the path.

Why two paths?

Forwarding a tz1 → tz1 transfer through the NAC gateway would mean: tz1 → KT1 NAC → mutez forwarded to recipient. Same destination, same amount, but with an extra contract call and a CRAC round-trip the kernel doesn't need. Skipping the gateway saves the fees and the latency.

The cross-runtime case (tz1 → 0x) is the only path that genuinely needs the gateway, because the recipient identity lives on the EVM runtime.

XTZ on a 0x alias is forwarded back to the tz1

Under the Tezos X account model, EVM aliases cannot hold native XTZ. The kernel's AliasForwarder automatically reroutes any XTZ sent to a 0x alias back to its tz1 of origin. This means a tz1 → 0x XTZ transfer ends up crediting the recipient's tz1, not the alias. It's still a useful path when the sender only knows the recipient's EVM address — but the value lands on the Tezos side. ERC-20 tokens (USDC, …) are unaffected ; they live on the alias normally.