Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4c87a29
WIP: T3 docs update
jenpaff Apr 14, 2026
171d7d6
docs: polish T3 upgrade prep
jenpaff Apr 15, 2026
05b7e95
docs: add T3 changelog sections to protocol specs
jenpaff Apr 15, 2026
99ddbab
Merge branch 'main' into docs/t3-upgrade-prep
jenpaff Apr 15, 2026
2574648
docs: clarify T3 protocol changes
jenpaff Apr 15, 2026
85e597d
docs: fix t3 dates and snippet formatting
jenpaff Apr 15, 2026
ae18aab
docs: simplify tempo transaction t3 notes
jenpaff Apr 15, 2026
adbb18b
Merge branch 'main' into docs/t3-upgrade-prep
jenpaff Apr 16, 2026
a17f620
docs(t3): port virtual address protocol docs
jenpaff Apr 16, 2026
f3fe100
update virtual address documentation
malleshpai Apr 16, 2026
ab4c7e1
Update src/pages/protocol/transactions/AccountKeychain.mdx
jenpaff Apr 16, 2026
9dddb3e
docs: clarify factory CREATE/CREATE2 flows are still allowed
decofe Apr 16, 2026
c2f75c3
docs(tip20): replace virtual address mermaid with themed PNGs (#317)
decofe Apr 17, 2026
30d655d
Merge branch 'main' into docs/t3-upgrade-prep
jenpaff Apr 17, 2026
0479a26
fix: resolve review feedback on t3 docs
jenpaff Apr 21, 2026
68f94fa
merge: resolve conflicts with main (pick up v1.6.0 release link and u…
jenpaff Apr 21, 2026
66ac824
docs: make virtual-address indexer guidance more concise
jenpaff Apr 21, 2026
89df336
docs: replace T3 who-is-affected with link to upgrade page
jenpaff Apr 21, 2026
c50e31e
docs: expand indexer and explorer guidance for virtual-address deposits
max-digi Apr 21, 2026
09ec06a
docs: consolidate t3.mdx, revert typescript SDK changes
jenpaff Apr 21, 2026
98740c2
docs: condense AccountKeychain upcoming changes, fix startReward refe…
jenpaff Apr 21, 2026
22a2fef
Update src/pages/protocol/upgrades/t3.mdx
jenpaff Apr 21, 2026
0965eda
docs: add Account Keychain examples for Python and Go SDKs (#312)
decofe Apr 21, 2026
682ce9b
Update src/pages/protocol/transactions/AccountKeychain.mdx
legion2002 Apr 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added public/images/tip20/virtual-addresses-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/tip20/virtual-addresses-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 3 additions & 5 deletions src/pages/guide/node/network-upgrades.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,15 @@ For detailed release notes and binaries, see the [Changelog](/changelog).

| | |
|---|---|
| **Scope** | Enhanced access keys with periodic limits, call scoping, and an authorization ABI update; signature verification precompile; virtual addresses for TIP-20 deposit forwarding; and security hardening and gas correctness fixes |
| **TIPs** | [TIP-1011: Enhanced Access Key Permissions](/protocol/tips/tip-1011), [TIP-1020: Signature Verification Precompile](/protocol/tips/tip-1020), [TIP-1022: Virtual Addresses for TIP-20 Deposit Forwarding](/protocol/tips/tip-1022), TIP-1038: T3 security hardening and gas correctness fixes |
| **Scope** | Enhanced access keys with periodic limits, call scoping, and an authorization ABI update; signature verification precompile; and virtual addresses for TIP-20 deposit forwarding |
| **TIPs** | [TIP-1011: Enhanced Access Key Permissions](/protocol/tips/tip-1011), [TIP-1020: Signature Verification Precompile](/protocol/tips/tip-1020), [TIP-1022: Virtual Addresses for TIP-20 Deposit Forwarding](/protocol/tips/tip-1022) |
| **Details** | [T3 network upgrade](/protocol/upgrades/t3) |
| **Release** | [v1.6.0](https://github.com/tempoxyz/tempo/releases/tag/v1.6.0) |
| **Testnet** | Moderato: Apr 21, 2026 16:00 CEST (unix: 1776780000) |
| **Mainnet** | Presto: Apr 27, 2026 16:00 CEST (unix: 1777298400) |
| **Priority** | <Badge variant="red">Required</Badge> |

All node operators should upgrade before the Moderato activation date, even if they do not plan to use the new T3 feature set directly.

Partners that create or rotate access keys should also review the T3 upgrade page. Existing authorized access keys remain valid, but key authorization flows must move to the new TIP-1011 ABI after activation.
See the [T3 network upgrade](/protocol/upgrades/t3) page for breaking changes, migration checklist, and integration guidance.

---

Expand Down
4 changes: 4 additions & 0 deletions src/pages/guide/tempo-transaction/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,8 @@ If you are an EVM smart contract developer, see the [Foundry guide for Tempo](/s

## Properties

:::info[T3 will change these examples]
The examples below show the currently active Tempo Transaction shape. T3 changes the access-key examples and parts of the transaction envelope, and the affected lines are called out inline.
:::

<TempoTxProperties />
10 changes: 10 additions & 0 deletions src/pages/protocol/tip20-rewards/spec.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,22 @@ description: Technical specification for the TIP-20 reward distribution system u

# TIP-20 Rewards Distribution

:::info[T3 will change this spec]
The [T3 network upgrade](/protocol/upgrades/t3) will update this specification. The sections below describe the currently active behavior. See [Upcoming changes](#upcoming-changes) for the upcoming deltas.
:::

## Abstract
An opt-in, scalable, pro-rata reward distribution mechanism built into TIP-20 tokens. The system uses a "reward-per-token" accumulator pattern to distribute rewards proportionally to opted-in holders without requiring staking or per-holder iteration. Rewards are distributed instantly; time-based streaming distributions are planned for a future upgrade.

## Motivation
Many applications require pro-rata distribution of tokens to existing holders (incentive programs, deterministic inflation, staking rewards). Building this into TIP-20 allows efficient distribution without forcing users to stake tokens elsewhere or requiring distributors to loop over all holders.

## Upcoming changes

T3 updates the TIP-20 rewards spec through [TIP-1022](/protocol/tips/tip-1022) in one place:

- `setRewardRecipient(...)` will reject [TIP-1022](/protocol/tips/tip-1022) virtual addresses. Reward recipients must remain canonical accounts rather than forwarding aliases, because reward assignment is not a TIP-20 forwarding path.

## Specification
The rewards mechanism allows anyone to distribute token rewards to opted-in holders proportionally based on holdings. Users must opt in to receiving rewards and may delegate rewards to a recipient address.

Expand Down
6 changes: 6 additions & 0 deletions src/pages/protocol/tip20/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,12 @@ By using TIP-20 tokens as quote tokens, the DEX benefits from the same payment-o
icon="lucide:send"
title="Guide: Make Payments"
/>
<Card
description="Generate one deposit address per customer without sweep transactions"
to="/protocol/tip20/virtual-addresses"
icon="lucide:route"
title="Virtual Addresses"
/>
<Card
description="Create and manage your own stablecoin on Tempo"
to="/guide/issuance"
Expand Down
13 changes: 13 additions & 0 deletions src/pages/protocol/tip20/spec.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ description: Technical specification for TIP-20, the optimized token standard ex

# TIP20

:::info[T3 will change this spec]
The [T3 network upgrade](/protocol/upgrades/t3) will update this specification. The sections below describe the currently active behavior. See [Upcoming changes](#upcoming-changes) for the upcoming deltas.
:::

## Abstract
TIP20 is a suite of precompiles that provide a built-in optimized token implementation in the core protocol. It extends the ERC-20 token standard with built-in functionality like memo fields and reward distribution.

Expand All @@ -12,6 +16,15 @@ All major stablecoins today use the ERC-20 token standard. While ERC-20 provides
TIP-20 extends ERC-20, building these features into precompiled contracts that anyone can permissionlessly deploy on Tempo. This makes token operations much more efficient, allows issuers to quickly set up on Tempo, and simplifies integrations since it ensures standardized behavior across tokens.
It also enables deeper integration with token-specific Tempo features like paying gas in stablecoins and payment lanes.

## Upcoming changes

T3 updates TIP-20 behavior through [TIP-1022](/protocol/tips/tip-1022). All changes below come from TIP-1022:

- [TIP-1022](/protocol/tips/tip-1022) adds virtual-address recipient resolution for recipient-bearing TIP-20 paths: `transfer`, `transferFrom`, `transferWithMemo`, `transferFromWithMemo`, `mint`, and `mintWithMemo`.
- When a TIP-20 operation targets a registered virtual address, the effective recipient becomes the registered master wallet before recipient authorization and mint-recipient checks run.
- Forwarded virtual-address deposits appear as two-hop standard `Transfer` events in the same transaction. Indexers and explorers should collapse that pair into one logical deposit to the resolved master wallet.
- Virtual addresses are valid TIP-20 recipients on those paths, but they remain forwarding aliases rather than canonical TIP-20 holders. Non-TIP-20 tokens sent to a virtual address do not forward.

## Specification
TIP-20 tokens support standard fungible token operations such as transfers, mints, and burns. They also support transfers, mints, and burns with an attached 32-byte memo; a role-based access control system for token administrative operations; and a system for opt-in [reward distribution](/protocol/tip20-rewards/spec).

Expand Down
186 changes: 186 additions & 0 deletions src/pages/protocol/tip20/virtual-addresses.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
---
title: Virtual addresses for TIP-20 deposits
description: Understand how TIP-20 virtual addresses work, why they remove sweep transactions, and how to attribute forwarded deposits on Tempo.
---

import { Cards, Card } from 'vocs'
import { StaticMermaidDiagram } from '../../../components/StaticMermaidDiagram'

# Virtual addresses for TIP-20 deposits

Virtual addresses let you give each customer their own TIP-20 deposit address without giving each customer their own onchain wallet balance. A deposit sent to that address is forwarded by the protocol to a registered master wallet.

For exchanges, ramps, custodians, and payment processors, this changes the operational model. You still get one address per customer for attribution and reconciliation, but you no longer need sweep jobs to consolidate funds.

## Why this feature exists

Without virtual addresses, per-customer deposit addresses are operationally expensive. Each deposit address becomes a real onchain balance holder. Funds land there first, and then the operator has to sweep those funds into a central wallet.

With virtual addresses, the customer-facing address is still unique, but it behaves like a routing alias. The protocol resolves it to the registered master wallet during the TIP-20 transfer itself.

<img src="/images/tip20/virtual-addresses-light.png" alt="Without virtual addresses, each customer deposit address holds a separate onchain balance that must be swept to the master wallet. With virtual addresses, TIP-20 forwarding routes deposits directly to the master wallet." className="dark:hidden" />
<img src="/images/tip20/virtual-addresses-dark.png" alt="Without virtual addresses, each customer deposit address holds a separate onchain balance that must be swept to the master wallet. With virtual addresses, TIP-20 forwarding routes deposits directly to the master wallet." className="hidden dark:block" />

This means:

- you keep one deposit address per customer
- the master wallet receives the balance directly
- no sweep transaction is needed
- no separate TIP-20 balance is created for each deposit address
Comment thread
jenpaff marked this conversation as resolved.

Forwarding happens inside the same TIP-20 precompile call that processes the transfer — there is no second transaction or additional token movement. The only extra cost is a single storage read (SLOAD) to look up the registered master wallet in the virtual-address registry.

## The mental model

A virtual address is not a second wallet. It is a deposit alias for one canonical wallet.

The important idea is simple: the virtual address is for routing and attribution, while the master wallet is where the TIP-20 balance actually lives.

## Address format

A virtual address is still a normal 20-byte EVM address. [TIP-1022](/protocol/tips/tip-1022) gives those 20 bytes a specific layout:

```text
0x | masterId (4 bytes) | VIRTUAL_MAGIC (10 bytes) | userTag (6 bytes)
```

Example:

```text
0x2612766c fdfdfdfdfdfdfdfdfdfd 000000000001
```

Where:

| Part | Size | Purpose |
| --- | --- | --- |
| `masterId` | 4 bytes | identifies which registered master wallet should receive the funds |
| `VIRTUAL_MAGIC` | 10 bytes | marks the address as virtual so TIP-20 can recognize it |
| `userTag` | 6 bytes | operator-chosen routing or attribution value |

TIP-20 recognizes a virtual address by the fixed 10-byte middle marker. It then uses the leading `masterId` to resolve the registered wallet and leaves the trailing `userTag` available for operator-side attribution.

## What happens when someone sends funds

When a sender transfers a covered TIP-20 token to a virtual address, the TIP-20 precompile detects the virtual format, looks up the registered master, and credits that master wallet.

<StaticMermaidDiagram chart={`sequenceDiagram
participant Sender
participant TIP20 as TIP-20
participant Registry as Virtual registry
participant Master as Registered wallet

Sender->>TIP20: transfer(virtualAddress, amount)
TIP20->>Registry: resolve(masterId)
Registry-->>TIP20: master wallet
TIP20->>Master: credit balance
Note over TIP20: emits Transfer(sender → virtual, amount)
Note over TIP20: emits Transfer(virtual → master, amount)
`} />
Comment thread
jenpaff marked this conversation as resolved.

Two things matter here:

1. The balance is credited only to the master wallet.
2. The transaction still exposes the virtual address in events, so backends and indexers can attribute the deposit correctly.

That is why `balanceOf(virtualAddress)` remains `0`. The virtual address is visible in the transfer path, but it does not end up holding the token balance.

## What this changes for operators

Virtual addresses are mainly an operations feature.

For an exchange or payment processor, the normal flow becomes:

1. register one master wallet
2. derive deposit addresses offchain for each customer
3. watch TIP-20 events and map the `userTag` back to the customer record on the backend
4. credit the customer internally once the deposit is observed

This gives you the accounting benefits of per-customer addresses without managing thousands or millions of real onchain balances.

## What this changes for wallets, explorers, and indexers

A virtual address is a forwarding alias, not a balance-holding account. Treat it as such in any UI or tooling: do not show it as holding a balance. Wallets, block explorers, and operational tooling that truncate addresses should display enough of the address to distinguish both the `masterId` and the `userTag`; ideally show the full address.

For indexers, the event sequences vary by operation. The basic transfer pattern is shown above. Memo and mint paths produce additional events in the same forwarding pattern:

**transferWithMemo / transferFromWithMemo:**
```
Transfer(sender, virtualAddress, amount)
TransferWithMemo(sender, virtualAddress, amount, memo)
Transfer(virtualAddress, masterWallet, amount)
```

**mint:**
```
Transfer(0x0, virtualAddress, amount)
Mint(virtualAddress, amount)
Transfer(virtualAddress, masterWallet, amount)
```

**mintWithMemo:**
```
Transfer(0x0, virtualAddress, amount)
TransferWithMemo(0x0, virtualAddress, amount, memo)
Mint(virtualAddress, amount)
Transfer(virtualAddress, masterWallet, amount)
```

In all cases, treat the full sequence as one logical deposit to the master wallet. If you surface each `Transfer` log independently, forwarded deposits will appear twice and the effective recipient will be wrong.

For deposit attribution, extract the `userTag` (trailing 6 bytes) directly from the virtual address to map the deposit to the right customer record without additional onchain queries.

If the sender and registered master wallet are the same address, two `Transfer` events still emit but the net balance change is zero. Account for this when counting deposits or computing balances.

## What this does not do

TIP-1022 is deliberately narrow in scope.

### It only changes TIP-20 deposit paths

Virtual forwarding applies only to the TIP-20 transfer and mint paths defined by [TIP-1022](/protocol/tips/tip-1022). It is not a general EVM alias system.

### It does not change ERC-20 contracts deployed on Tempo

If a non-TIP-20 token contract receives a transfer to a virtual address, that contract treats it as a normal literal address. TIP-1022 does not help there.

### It does not make every protocol virtual-address aware

Some protocols record ownership against the literal address they are given. If they mint LP shares, receipts, or similar positions to a virtual address, those positions can become stranded unless that protocol explicitly supports resolution.

### It does not bypass TIP-403 policy checks

Policy checks run against the resolved master wallet. If the master is not allowed to receive a token, deposits to that master's virtual addresses fail too.

## Adoption at a glance

Adopting virtual addresses is straightforward conceptually:

- one-time setup: register a master wallet and mine the required salt
- ongoing operations: derive deposit addresses offchain
- reconciliation: decode the `userTag` from events and credit the right customer internally

If you want the exact transfer semantics, event shape, and validation rules, read [TIP-1022](/protocol/tips/tip-1022) alongside the [TIP-20 specification](/protocol/tip20/spec).

## Learn more

<Cards>
<Card
title="TIP-20 specification"
description="See how T3 updates recipient resolution and event semantics for TIP-20 transfers and mints."
to="/protocol/tip20/spec"
icon="lucide:file-text"
/>
<Card
title="TIP-1022 specification"
description="Read the full TIP with address derivation, forwarding semantics, and invariants."
to="/protocol/tips/tip-1022"
icon="lucide:file-text"
/>
<Card
title="T3 network upgrade"
description="See when virtual addresses activate and what else ships in T3."
to="/protocol/upgrades/t3"
icon="lucide:rocket"
/>
</Cards>
11 changes: 11 additions & 0 deletions src/pages/protocol/tip403/spec.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ description: Technical specification for TIP-403, the policy registry system ena

# Overview

:::info[T3 will change this spec]
The [T3 network upgrade](/protocol/upgrades/t3) will update this specification. The sections below describe the currently active behavior. See [Upcoming changes](#upcoming-changes) for the upcoming deltas.
:::

## Abstract

TIP-403 provides a policy registry system that allows TIP-20 tokens to inherit access control and compliance policies. The registry supports two types of policies (whitelist and blacklist) and includes special built-in policies for common use cases. Policies can be shared across multiple tokens, enabling consistent compliance enforcement.
Expand All @@ -14,6 +18,13 @@ Token issuers often need to implement compliance policies such as KYC/AML requir

TIP-403 addresses this by providing a centralized registry that tokens can reference for authorization decisions. This enables consistent policy enforcement across multiple tokens and reduces implementation complexity for token issuers.

## Upcoming changes

T3 updates TIP-403 interactions with token recipients through [TIP-1022](/protocol/tips/tip-1022) as follows:

- Policy-configuration functions that accept literal member addresses will reject [TIP-1022](/protocol/tips/tip-1022) virtual addresses.
- TIP-20 policy checks for virtual-address transfers and mints will run against the resolved master wallet, not the forwarding alias, so policy membership must be configured on the master address.

---

# Specification
Expand Down
Loading
Loading