diff --git a/public/images/tip20/virtual-addresses-dark.png b/public/images/tip20/virtual-addresses-dark.png
new file mode 100644
index 00000000..e07754c3
Binary files /dev/null and b/public/images/tip20/virtual-addresses-dark.png differ
diff --git a/public/images/tip20/virtual-addresses-light.png b/public/images/tip20/virtual-addresses-light.png
new file mode 100644
index 00000000..dbf3f21b
Binary files /dev/null and b/public/images/tip20/virtual-addresses-light.png differ
diff --git a/src/pages/guide/node/network-upgrades.mdx b/src/pages/guide/node/network-upgrades.mdx
index 72d8b7e8..eaa1c6d8 100644
--- a/src/pages/guide/node/network-upgrades.mdx
+++ b/src/pages/guide/node/network-upgrades.mdx
@@ -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** | Required |
-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.
---
diff --git a/src/pages/guide/tempo-transaction/index.mdx b/src/pages/guide/tempo-transaction/index.mdx
index 383b3ecf..20796385 100644
--- a/src/pages/guide/tempo-transaction/index.mdx
+++ b/src/pages/guide/tempo-transaction/index.mdx
@@ -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.
+:::
+
diff --git a/src/pages/protocol/tip20-rewards/spec.mdx b/src/pages/protocol/tip20-rewards/spec.mdx
index 6380b93d..47cb4b63 100644
--- a/src/pages/protocol/tip20-rewards/spec.mdx
+++ b/src/pages/protocol/tip20-rewards/spec.mdx
@@ -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.
diff --git a/src/pages/protocol/tip20/overview.mdx b/src/pages/protocol/tip20/overview.mdx
index ddea9646..f4a0a151 100644
--- a/src/pages/protocol/tip20/overview.mdx
+++ b/src/pages/protocol/tip20/overview.mdx
@@ -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"
/>
+
+
+
+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
+
+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.
+
+>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)
+`} />
+
+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
+
+
+
+
+
+
diff --git a/src/pages/protocol/tip403/spec.mdx b/src/pages/protocol/tip403/spec.mdx
index d60e5b8b..b5df3c6c 100644
--- a/src/pages/protocol/tip403/spec.mdx
+++ b/src/pages/protocol/tip403/spec.mdx
@@ -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.
@@ -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
diff --git a/src/pages/protocol/transactions/AccountKeychain.mdx b/src/pages/protocol/transactions/AccountKeychain.mdx
index 71f0438b..c89f5a32 100644
--- a/src/pages/protocol/transactions/AccountKeychain.mdx
+++ b/src/pages/protocol/transactions/AccountKeychain.mdx
@@ -6,14 +6,28 @@ description: Technical specification for the Account Keychain precompile managin
**Address:** `0xAAAAAAAA00000000000000000000000000000000`
+:::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.
+:::
+
## Overview
-The Account Keychain precompile manages authorized Access Keys for accounts, enabling Root Keys (e.g., passkeys) to provision scoped "secondary" Access Keys with expiry timestamps and per-TIP20 token spending limits.
+The Account Keychain precompile manages authorized Access Keys for accounts, enabling Root Keys (e.g., passkeys) to provision scoped "secondary" Access Keys with expiry timestamps and per-TIP20 token spending limits.
## Motivation
The Tempo Transaction type unlocks a number of new signature schemes, including WebAuthn (Passkeys). However, for an Account using a Passkey as its Root Key, the sender will subsequently be prompted with passkey prompts for every signature request. This can be a poor user experience for highly interactive or multi-step flows. Additionally, users would also see "Sign In" copy in prompts for signing transactions which is confusing. This proposal introduces the concept of the Root Key being able to provision a (scoped) Access Key that can be used for subsequent transactions, without the need for repetitive end-user prompting.
+## Upcoming changes
+
+T3 updates this spec through [TIP-1011](/protocol/tips/tip-1011):
+
+- `TokenLimit` gains an optional `period` for recurring spending limits
+- `authorizeKey(...)` moves to a new ABI with `allowAnyCalls` and `CallScope[]` for call scoping
+- New functions: `setAllowedCalls(...)`, `removeAllowedCalls(...)`, `getAllowedCalls(...)`
+- `getRemainingLimit(...)` returns both `remaining` and `periodEnd`
+- Access-key-signed transactions can no longer create contracts in any configuration. Calling the `CREATE` opcode onchain still works
+
## Concepts
### Access Keys
@@ -23,7 +37,7 @@ Access Keys are secondary signing keys authorized by an account's Root Key. They
- **Expiry**: Unix timestamp when the key becomes invalid (0 = never expires, non-zero values must be > current timestamp)
- **Spending Limits**: Per-TIP20 token limits that deplete as tokens are spent
- Limits deplete as tokens are spent and can be updated by the Root Key via `updateSpendingLimit()`
- - Spending limits only apply to TIP20 `transfer()`, `transferWithMemo()`, `approve()`, and `startReward()` calls
+ - Spending limits only apply to TIP20 `transfer()`, `transferWithMemo()`, and `approve()` calls
- Spending limits only apply when `msg.sender == tx.origin` (direct EOA calls, not contract calls)
- Native value transfers and `transferFrom()` are NOT limited
- **Privilege Restrictions**: Cannot authorize new keys or modify their own limits
@@ -35,7 +49,7 @@ The protocol enforces a strict hierarchy at validation time:
1. **Root Key**: The account's main key (derived from the account address)
- Can call all precompile functions
- Has no spending limits
-
+
2. **Access Keys**: Secondary authorized keys
- Cannot call mutable precompile functions (only view functions are allowed)
- Subject to per-TIP20 token spending limits
diff --git a/src/pages/protocol/transactions/index.mdx b/src/pages/protocol/transactions/index.mdx
index a218f46b..c6012fbb 100644
--- a/src/pages/protocol/transactions/index.mdx
+++ b/src/pages/protocol/transactions/index.mdx
@@ -67,6 +67,10 @@ 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.
+:::
+
diff --git a/src/pages/protocol/transactions/spec-tempo-transaction.mdx b/src/pages/protocol/transactions/spec-tempo-transaction.mdx
index 1645e480..1d6e3476 100644
--- a/src/pages/protocol/transactions/spec-tempo-transaction.mdx
+++ b/src/pages/protocol/transactions/spec-tempo-transaction.mdx
@@ -4,6 +4,10 @@ description: Technical specification for the Tempo transaction type (EIP-2718) w
# Tempo Transaction
+:::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
This spec introduces native protocol support for the following features, using a new Tempo transaction type:
@@ -20,6 +24,18 @@ Current accounts are limited to secp256k1 signatures and sequential nonces, crea
Users cannot leverage modern authentication methods like passkeys, applications face throughput limitations due to sequential nonces.
+## Upcoming changes
+
+T3 updates the Tempo Transaction spec through [TIP-1011](/protocol/tips/tip-1011) in the following ways:
+
+- `KeyAuthorization` expands with the [TIP-1011](/protocol/tips/tip-1011) fields `allowed_calls` and periodic `TokenLimit.period`, adding call scoping and recurring spending limits to access keys.
+- The signed post-T3 key-authorization payload remains `SignedKeyAuthorization { authorization, signature }`, but `authorization` now uses the expanded `KeyAuthorization` shape and new RLP encoding.
+- Low-level integrators that manually encode `key_authorization` must branch pre-T3 vs post-T3. The post-T3 digest and signed payload include `allowed_calls?` in addition to `expiry?` and `limits?`.
+- Access-key validation gains two new execution checks: call scopes must pass before execution begins, and access-key-signed transactions may no longer perform contract creation anywhere in the batch.
+- The Account Keychain precompile ABI changes in lockstep with T3 to support periodic limits, call-scoped authorizations, and new scope-management functions.
+- Intrinsic gas for `key_authorization` changes to account for periodic-limit state and call-scope storage. See [TIP-1011](/protocol/tips/tip-1011#intrinsic-gas-for-key-authorization) for the post-T3 slot-counting rules.
+
+
## Specification
### Transaction Type
@@ -688,16 +704,17 @@ The protocol tracks and enforces spending limits for TIP20 token transfers:
```typescript
// Define key parameters
const keyAuth = {
+ chain_id: 1,
key_type: SignatureType.P256, // 1
key_id: keyId, // address derived from public key
expiry: timestamp + 86400, // 24 hours from now (or 0 for never)
limits: [
- { token: USDG_ADDRESS, amount: 1000000000 }, // 1000 USDG (6 decimals)
- { token: DAI_ADDRESS, amount: 500000000000000000000 } // 500 DAI (18 decimals)
+ { token: USDG_ADDRESS, limit: 1000000000 }, // 1000 USDG (6 decimals)
+ { token: DAI_ADDRESS, limit: 500000000000000000000 } // 500 DAI (18 decimals)
]
};
- // Compute digest: keccak256(rlp([key_type, key_id, expiry, limits]))
+ // Compute digest: keccak256(rlp([chain_id, key_type, key_id, expiry, limits]))
const authDigest = computeAuthorizationDigest(keyAuth);
```
@@ -718,10 +735,7 @@ The protocol tracks and enforces spending limits for TIP20 token transfers:
max_fee_per_gas: 1000000000,
max_priority_fee_per_gas: 1000000000,
key_authorization: {
- key_type: keyAuth.key_type,
- expiry: keyAuth.expiry,
- limits: keyAuth.limits,
- key_id: keyAuth.key_id,
+ authorization: keyAuth,
signature: rootSignature // Root Key's signature on authDigest
},
// ... other fields
diff --git a/src/pages/protocol/upgrades/t3.mdx b/src/pages/protocol/upgrades/t3.mdx
index 61a5f817..e16d8e6e 100644
--- a/src/pages/protocol/upgrades/t3.mdx
+++ b/src/pages/protocol/upgrades/t3.mdx
@@ -1,12 +1,10 @@
---
title: T3 Network Upgrade
-description: Details and timeline for the T3 network upgrade, including enhanced access keys, signature verification, virtual addresses, and security hardening and gas correctness fixes.
+description: Details and timeline for the T3 network upgrade, including enhanced access keys, signature verification, and virtual addresses.
---
# T3 Network Upgrade
-This page summarizes the features, partner impact, and breaking changes included in the T3 network upgrade.
-
:::info[T3 is not live yet]
The features described on this page are scheduled for T3 and are not active on Moderato or Presto yet. They only become live once the T3 activation timestamps are reached.
:::
@@ -20,47 +18,49 @@ The features described on this page are scheduled for T3 and are not active on M
Partners should upgrade nodes to the T3-compatible release before the Moderato activation timestamp.
-## Overview
+Overview
-T3 is Tempo's next network upgrade. It introduces the following changes:
-- Enhanced access key permissions with periodic spending limits, call scoping, and a protocol-level ban on access-key contract creation ([TIP-1011](/protocol/tips/tip-1011))
-- A signature verification precompile for secp256k1, P256, and WebAuthn signatures ([TIP-1020](/protocol/tips/tip-1020))
-- Virtual addresses for TIP-20 deposit forwarding ([TIP-1022](/protocol/tips/tip-1022))
+| TIP | What it does | Who should review |
+|-----|-------------|-------------------|
+| [TIP-1011](/protocol/tips/tip-1011) | Periodic spending limits, call scoping, and a ban on access-key contract creation | Wallets, account SDKs, apps using connected apps or subscriptions |
+| [TIP-1020](/protocol/tips/tip-1020) | Signature verification precompile for secp256k1, P256, and WebAuthn | Smart contract teams, account integrators, wallet SDKs |
+| [TIP-1022](/protocol/tips/tip-1022) | [Virtual addresses](/protocol/tip20/virtual-addresses) for TIP-20 deposit forwarding | Exchanges, ramps, custodians, payment processors, explorers, indexers |
-**Action required for integrators:** Partners that create or update access keys should upgrade to a T3-compatible SDK release before activation.
+## Breaking changes
-## Partner impact
+### Access-key authorization ABI
-| Area | Who should review | Summary |
-|------|-------------------|---------|
-| Access keys | Wallets, account SDKs, and apps using connected apps or subscriptions | Existing authorized access keys remain valid for delegated transaction flows. T3 adds optional periodic limits and call scoping, bans contract creation from access-key transactions, and changes the authorization ABI used to create or rotate keys. |
-| Signature verification precompile | Smart contract teams, account integrators, and wallet SDKs | Contracts can verify secp256k1, P256, and WebAuthn signatures through one precompile instead of custom verifier contracts. |
-| Virtual addresses | Exchanges, ramps, custodians, payment processors, explorers, and indexers | Partners can generate per-user TIP-20 deposit addresses that forward to a registered master wallet. Explorers and indexers should display and attribute forwarded deposits correctly. |
+Integrations that directly call `AccountKeychain.authorizeKey(...)` or manually encode `key_authorization` must migrate to the TIP-1011 format after activation. Legacy calls fail with `LegacyAuthorizeKeySelectorChanged(newSelector: 0x980a6025)`.
-## Breaking changes
+- **Before activation:** use the legacy ABI. The TIP-1011 format is not yet valid onchain.
+- **After activation:** use the TIP-1011 format. The legacy ABI stops working.
-Partners that create or update access keys should upgrade to a T3-compatible SDK release before activation.
+If you support both pre-T3 and post-T3 networks, branch on network version or activation timestamp.
-For most integrators, no action is needed beyond upgrading to T3-compatible tooling. Existing authorized access keys keep working, and Tempo Transactions that use `key_authorization` keep working.
+### Access-key contract creation
-### Breaking change for access-key integrations
+Post-T3, access-key-signed transactions can no longer create contracts in any configuration — including direct CREATE, factory CREATE, and internal CREATE2. Move those flows to a root key path.
-The only integrations that need code changes are ones that call `AccountKeychain.authorizeKey(...)` directly onchain. Before T3, those flows used the legacy authorization ABI. After T3, they must use the TIP-1011 authorization format with the updated `authorizeKey(...)` arguments. Legacy calls fail with `LegacyAuthorizeKeySelectorChanged`, sometimes surfaced as `LegacyAuthorizeKeySelectorChanged(newSelector: 0x980a6025)`.
+### Migration checklist
-**Before activation:** Integrations must continue using the legacy `AccountKeychain.authorizeKey(...)` ABI. The TIP-1011 authorization format is not yet valid onchain.
+- Upgrade to a T3-compatible SDK release listed below
+- Regenerate contract bindings or replace handcrafted encoders for `authorizeKey(...)`
+- Move any access-key contract-creation flows to a root key path
+- Test key creation, key rotation, and recovery flows on Moderato after T3 activates
-**After activation:** Integrations must use the TIP-1011 authorization format.
+Most integrators only need to upgrade tooling. Existing authorized access keys keep working.
-T3 also adds one new execution restriction: access-key-signed transactions can no longer create contracts. If your product used access keys for deployments, factory calls, or module-install flows that create contracts, those transactions must move to a Root Key path.
+## Supporting new features
-If you support both pre-T3 and post-T3 networks at the same time, branch on network version or activation timestamp. The old authorization ABI only works before T3. The new authorization ABI only works after T3.
+### Virtual addresses for explorers and indexers
-### Migration checklist
+Each virtual-address deposit emits two `Transfer` events in one transaction: `Transfer(sender, virtualAddress, amount)` then `Transfer(virtualAddress, masterWallet, amount)`. Collapse these into one logical deposit to the master wallet. The virtual address is for attribution only — `balanceOf(virtualAddress)` is always zero.
-- upgrade to a T3-compatible SDK mentioned below
-- regenerate contract bindings or replace handcrafted encoders for `authorizeKey(...)`
-- move any access-key contract-creation flows to a Root Key path
-- test key creation, key rotation, and recovery flows on Moderato after T3 activates
+See [Virtual addresses for TIP-20 deposits](/protocol/tip20/virtual-addresses) for the full routing model and event sequences.
+
+### Signature verification precompile
+
+[TIP-1020](/protocol/tips/tip-1020) is additive — existing verifier setups keep working. Teams that want a standard onchain verification surface can adopt the precompile instead of maintaining custom verifier contracts. See the [Signature Verification with Foundry](/sdk/foundry/signature-verifier) guide.
## Compatible SDK releases
@@ -74,21 +74,11 @@ Tempo's broader tooling ecosystem is available in [Developer tools](/quickstart/
| [Python](https://github.com/tempoxyz/pytempo) | [`0.5.0`](https://github.com/tempoxyz/pytempo/releases/tag/pytempo%400.5.0) |
| [Foundry](https://github.com/foundry-rs/foundry) | [`nightly`](https://github.com/foundry-rs/foundry/releases/tag/nightly) |
-## Related docs
-Guides about TIPs coming soon.
-
-## Feature TIPs
-
-### TIP-1011: Enhanced Access Key Permissions
-
-[TIP-1011](/protocol/tips/tip-1011) adds periodic spending limits and call scoping to access keys, including restrictions on which contracts a key can call and, for common token flows, which recipient it can target. This gives wallets, account SDKs, and apps a safer way to offer delegated permissions for recurring billing, subscription renewals, payroll, connected-app approvals, or agent budgets without asking the user to approve every transaction manually. For existing partners, previously authorized access keys continue to work after activation, but any flow that creates, rotates, or re-authorizes a key must move to the new TIP-1011 ABI, and access-key transactions can no longer be used for contract creation.
-
-### TIP-1020: Signature Verification Precompile
-
-[TIP-1020](/protocol/tips/tip-1020) adds a single precompile for verifying secp256k1, P256, and WebAuthn signatures onchain. This gives smart contract teams, wallet builders, and account integrators a standard verification surface for passkey wallets, multisigs, governance approvals, subscription authorization, and other signature-driven flows without deploying and maintaining custom verifier contracts for each signature type. This change is additive for existing partners: nothing breaks if you keep your current verifier setup, but teams that want simpler integrations or forward-compatible support for Tempo signature types can adopt the precompile. Keychain signatures still need `AccountKeychain` for key resolution, so this precompile covers the underlying signature schemes rather than the full keychain authorization flow.
-
-The Foundry project template for Tempo includes a working example that uses the `SignatureVerifier` precompile to verify P256 signatures inside a smart contract. See the [Signature Verification with Foundry](/sdk/foundry/signature-verifier) guide to get started.
-
-### TIP-1022: Virtual Addresses for TIP-20 Deposit Forwarding
+:::note[Current SDK caveat]
+The Accounts SDK and `wallet_authorizeAccessKey` docs still describe the legacy pre-T3 access-key shape. Until their T3 support lands, use the protocol specs and the T3-compatible SDK releases above for the post-T3 `authorizeKey(...)` ABI.
+:::
-[TIP-1022](/protocol/tips/tip-1022) lets partners issue per-user deposit addresses that forward TIP-20 deposits to a registered master wallet at the protocol level. This is useful for exchanges, ramps, custodians, and payment processors that want one deposit address per customer for reconciliation, attribution, or account crediting, but do not want to maintain sweep jobs or fund separate onchain wallets for every user. For existing partners, nothing changes unless you adopt virtual addresses, but any explorer, indexer, or backend system that surfaces TIP-20 deposit activity should handle forwarded deposits correctly. Teams that adopt virtual addresses should treat those forwarded deposits as deposits to the registered master wallet. Forwarding applies only to TIP-20 transfer paths.
+## Related docs
+- [Virtual addresses for TIP-20 deposits](/protocol/tip20/virtual-addresses)
+- [TIP-1022](/protocol/tips/tip-1022)
+- Coordinating meta TIP: [tempoxyz/tempo#3273](https://github.com/tempoxyz/tempo/pull/3273)
diff --git a/src/pages/quickstart/integrate-tempo.mdx b/src/pages/quickstart/integrate-tempo.mdx
index 9db9ca8b..4cba2811 100644
--- a/src/pages/quickstart/integrate-tempo.mdx
+++ b/src/pages/quickstart/integrate-tempo.mdx
@@ -5,7 +5,6 @@ interactive: true
import * as Demo from '../../components/guides/Demo.tsx'
import { ConnectWallet } from '../../components/ConnectWallet.tsx'
-import TempoTxProperties from '../../snippets/tempo-tx-properties.mdx'
import { Cards, Card } from 'vocs'
# Integrate Tempo
diff --git a/src/pages/quickstart/predeployed-contracts.mdx b/src/pages/quickstart/predeployed-contracts.mdx
index f16094ea..15a2e34b 100644
--- a/src/pages/quickstart/predeployed-contracts.mdx
+++ b/src/pages/quickstart/predeployed-contracts.mdx
@@ -14,6 +14,8 @@ Core protocol contracts that power Tempo's features.
| [**Fee Manager**](/protocol/fees/spec-fee-amm#2-feemanager-contract) | [`0xfeec000000000000000000000000000000000000`](https://explore.tempo.xyz/address/0xfeec000000000000000000000000000000000000) | Handle fee payments and conversions |
| [**Stablecoin DEX**](/protocol/exchange) | [`0xdec0000000000000000000000000000000000000`](https://explore.tempo.xyz/address/0xdec0000000000000000000000000000000000000) | Enshrined DEX for stablecoin swaps |
| [**TIP-403 Registry**](/protocol/tip403/spec) | [`0x403c000000000000000000000000000000000000`](https://explore.tempo.xyz/address/0x403c000000000000000000000000000000000000) | Transfer policy registry |
+| [**Signature Verifier**](/protocol/tips/tip-1020) | [`0x5165300000000000000000000000000000000000`](https://explore.tempo.xyz/address/0x5165300000000000000000000000000000000000) | Verify secp256k1, P256, and WebAuthn signatures onchain |
+| [**Address Registry**](/protocol/tips/tip-1022) | [`0xFDC0000000000000000000000000000000000000`](https://explore.tempo.xyz/address/0xFDC0000000000000000000000000000000000000) | Resolve virtual TIP-20 deposit addresses to registered master wallets |
| [**pathUSD**](/protocol/exchange/quote-tokens#pathusd) | [`0x20c0000000000000000000000000000000000000`](https://explore.tempo.xyz/address/0x20c0000000000000000000000000000000000000) | First stablecoin deployed |
## Standard Utilities
diff --git a/src/pages/sdk/foundry/index.mdx b/src/pages/sdk/foundry/index.mdx
index c4cf1308..6737e8ad 100644
--- a/src/pages/sdk/foundry/index.mdx
+++ b/src/pages/sdk/foundry/index.mdx
@@ -129,7 +129,7 @@ forge script script/Mail.s.sol
```bash
# Set environment variables
-export TEMPO_RPC_URL=https://rpc.tempo.xyz
+export TEMPO_RPC_URL=https://rpc.moderato.tempo.xyz
export VERIFIER_URL=https://contracts.tempo.xyz
# Optional: create a new keypair and request some testnet tokens from the faucet.
@@ -156,15 +156,6 @@ forge create src/Mail.sol:Mail \
--verify \
--constructor-args 0x20c0000000000000000000000000000000000001
-# Deploy using an access key (delegated signing)
-forge create src/Mail.sol:Mail \
- --tempo.access-key $ACCESS_KEY_PRIVATE_KEY \
- --tempo.root-account $ROOT_ADDRESS \
- --rpc-url $TEMPO_RPC_URL \
- --broadcast \
- --verify \
- --constructor-args 0x20c0000000000000000000000000000000000001
-
# Set a salt for deterministic contract address derivation
# The salt is passed to TIP20_FACTORY.createToken() which uses it with the sender
# address to compute a deterministic deployment address via getTokenAddress(sender, salt)
@@ -196,6 +187,8 @@ forge script script/Deploy.s.sol \
--private-key $PRIVATE_KEY
```
+Use a root key for `forge create`. Post-T3, access keys can sign calls but not deployments.
+
For more verification options including verifying existing contracts and API verification, see [Contract Verification](/quickstart/verify-contracts).
:::warning[Batch Transaction Rules]
@@ -285,8 +278,8 @@ cast send 'increment()' \
# Send with access key (delegated signing):
# First authorize the key via Account Keychain precompile
cast send 0xAAAAAAAA00000000000000000000000000000000 \
- 'authorizeKey(address,uint8,uint64,bool,(address,uint256)[])' \
- $ACCESS_KEY_ADDR 0 1893456000 false "[]" \
+ 'authorizeKey(address,uint8,uint64,bool,(address,uint256,uint64)[],bool,(address,(bytes4,address[])[])[])' \
+ $ACCESS_KEY_ADDR 0 1893456000 false "[]" true "[]" \
--rpc-url $TEMPO_RPC_URL \
--private-key $ROOT_PRIVATE_KEY
# Then send using the access key
@@ -296,6 +289,10 @@ cast send 'increment()' \
--tempo.root-account $ROOT_ADDRESS
```
+Post-T3, direct `authorizeKey(...)` calls must use the enhanced TIP-1011 ABI shown above. If you need periodic limits or call scopes, fill those arrays instead of passing `[]`.
+
+Post-T3, access-key transactions also cannot create contracts, so use a root key for deployments or other flows that perform `CREATE`.
+
### Local Development with Anvil
Anvil supports Tempo mode for local testing and forking Tempo networks:
diff --git a/src/pages/sdk/go/index.mdx b/src/pages/sdk/go/index.mdx
index c98fdf77..0d64006a 100644
--- a/src/pages/sdk/go/index.mdx
+++ b/src/pages/sdk/go/index.mdx
@@ -285,6 +285,128 @@ for _, resp := range responses {
}
```
+## Account Keychain
+
+The `keychain` package provides typed helpers for Tempo's [Account Keychain precompile](/protocol/transactions/AccountKeychain), enabling access key management and signing directly from Go.
+
+:::info
+Enhanced access key features — periodic spending limits and call scoping — require the [T3 network upgrade](/protocol/upgrades/t3).
+:::
+
+```go [keychain_manage.go]
+package main
+
+import (
+ "context"
+ "math/big"
+ "time"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/tempoxyz/tempo-go/pkg/client"
+ "github.com/tempoxyz/tempo-go/pkg/keychain"
+ "github.com/tempoxyz/tempo-go/pkg/signer"
+ "github.com/tempoxyz/tempo-go/pkg/transaction"
+)
+
+func main() {
+ c := client.New("https://rpc.tempo.xyz")
+ s, _ := signer.NewSigner("0xYOUR_PRIVATE_KEY")
+
+ ctx := context.Background()
+ nonce, _ := c.GetTransactionCount(ctx, s.Address().Hex())
+
+ accessKeyAddr := common.HexToAddress("")
+
+ // Authorize a new access key (secp256k1, no expiry):
+ restrictions := keychain.NewKeyRestrictions(0)
+ call, _ := keychain.AuthorizeKey(accessKeyAddr, keychain.SignatureTypeSecp256k1, restrictions)
+
+ tx := transaction.NewBuilder(big.NewInt(4217)).
+ SetNonce(nonce).
+ SetGas(200000).
+ SetMaxFeePerGas(big.NewInt(20000000000)).
+ SetMaxPriorityFeePerGas(big.NewInt(1000000000)).
+ AddCall(call.To, big.NewInt(0), call.Data).
+ Build()
+
+ // Authorize with a spending limit:
+ token := common.HexToAddress("")
+ restrictions = keychain.NewKeyRestrictions(0).
+ WithLimits([]keychain.TokenLimit{{Token: token, Amount: big.NewInt(1_000_000)}})
+ call, _ = keychain.AuthorizeKey(accessKeyAddr, keychain.SignatureTypeSecp256k1, restrictions)
+
+ // Authorize with call scopes (restrict to specific contracts/functions):
+ scope := keychain.NewCallScopeBuilder(token).
+ Transfer(nil).
+ Approve(nil).
+ Build()
+ restrictions = keychain.NewKeyRestrictions(0).
+ WithAllowedCalls([]keychain.CallScope{scope})
+ call, _ = keychain.AuthorizeKey(accessKeyAddr, keychain.SignatureTypeSecp256k1, restrictions)
+
+ // Full example: 24h expiry + spending limit + call scope:
+ expiry := uint64(time.Now().Add(24 * time.Hour).Unix())
+ restrictions = keychain.NewKeyRestrictions(expiry).
+ WithLimits([]keychain.TokenLimit{{Token: token, Amount: big.NewInt(1_000_000)}}).
+ WithAllowedCalls([]keychain.CallScope{
+ keychain.NewCallScopeBuilder(token).Transfer(nil).Build(),
+ })
+ call, _ = keychain.AuthorizeKey(accessKeyAddr, keychain.SignatureTypeSecp256k1, restrictions)
+
+ // Revoke an access key (permanent, cannot be re-authorized):
+ call, _ = keychain.RevokeKey(accessKeyAddr)
+
+ // Update spending limit for a key-token pair:
+ call, _ = keychain.UpdateSpendingLimit(accessKeyAddr, token, big.NewInt(2_000_000))
+
+ // Replace all call scopes for a key:
+ call, _ = keychain.SetAllowedCalls(accessKeyAddr, []keychain.CallScope{
+ keychain.NewCallScopeBuilder(token).Transfer(nil).Build(),
+ })
+
+ // Remove a target contract from allowed call list:
+ call, _ = keychain.RemoveAllowedCalls(accessKeyAddr, token)
+
+ _ = ctx
+ _ = tx
+ _ = call
+}
+```
+
+### Signing with an Access Key
+
+Use `keychain.SignWithAccessKey` to sign a transaction as an access key holder:
+
+```go [access_key_sign.go]
+accessKeySigner, _ := signer.NewSigner("")
+rootAccount := common.HexToAddress("")
+
+tx := transaction.NewBuilder(big.NewInt(4217)).
+ SetNonce(nonce).
+ SetGas(100000).
+ SetMaxFeePerGas(big.NewInt(20000000000)).
+ SetMaxPriorityFeePerGas(big.NewInt(1000000000)).
+ AddCall(recipient, big.NewInt(0), data).
+ Build()
+
+keychain.SignWithAccessKey(tx, accessKeySigner, rootAccount) // [!code hl]
+serialized, _ := transaction.Serialize(tx, nil)
+hash, _ := c.SendRawTransaction(ctx, serialized)
+```
+
+### Query Remaining Spending Limit
+
+```go [query_limit.go]
+calldata := keychain.EncodeGetRemainingLimitCalldata(
+ common.HexToAddress(""),
+ common.HexToAddress(""),
+ common.HexToAddress(""),
+)
+result, _ := c.Call(ctx, keychain.GetKeychainAddress().Hex(), calldata)
+remaining := keychain.ParseRemainingLimitResult(result)
+fmt.Printf("Remaining: %s\n", remaining.String())
+```
+
## Packages
| Package | Description |
@@ -292,6 +414,7 @@ for _, resp := range responses {
| `transaction` | TempoTransaction encoding, signing, and validation |
| `client` | RPC client for interacting with Tempo nodes |
| `signer` | Key management and signature generation |
+| `keychain` | Account Keychain precompile: access key management and signing |
## Next Steps
diff --git a/src/pages/sdk/python/index.mdx b/src/pages/sdk/python/index.mdx
index 67a359f2..e961883c 100644
--- a/src/pages/sdk/python/index.mdx
+++ b/src/pages/sdk/python/index.mdx
@@ -214,6 +214,142 @@ tx = TempoTransaction.create(
)
```
+## Account Keychain
+
+The `AccountKeychain` class provides typed helpers for Tempo's [Account Keychain precompile](/protocol/transactions/AccountKeychain), enabling access key management directly from Python.
+
+:::info
+Enhanced access key features — periodic spending limits and call scoping — require the [T3 network upgrade](/protocol/upgrades/t3).
+:::
+
+```python [keychain.py]
+from pytempo import (
+ TempoTransaction, Call,
+ KeyRestrictions, SignatureType, TokenLimit, CallScope,
+)
+from pytempo.contracts import AccountKeychain, ALPHA_USD
+from web3 import Web3
+
+w3 = Web3(Web3.HTTPProvider("https://rpc.tempo.xyz"))
+
+# Authorize a new access key (secp256k1, no expiry):
+call = AccountKeychain.authorize_key(
+ key_id="",
+ signature_type=SignatureType.SECP256K1,
+ restrictions=KeyRestrictions(expiry=0),
+)
+tx = TempoTransaction.create(
+ chain_id=w3.eth.chain_id,
+ gas_limit=200_000,
+ max_fee_per_gas=w3.eth.gas_price * 2,
+ max_priority_fee_per_gas=w3.eth.gas_price,
+ nonce=w3.eth.get_transaction_count(account.address),
+ calls=(call,),
+)
+
+# Authorize with a spending limit:
+call = AccountKeychain.authorize_key(
+ key_id="",
+ signature_type=SignatureType.SECP256K1,
+ restrictions=KeyRestrictions(
+ expiry=0,
+ limits=[TokenLimit(token=ALPHA_USD, limit=1_000_000)],
+ ),
+)
+
+# Authorize with call scopes (restrict to specific contracts/functions):
+call = AccountKeychain.authorize_key(
+ key_id="",
+ signature_type=SignatureType.SECP256K1,
+ restrictions=KeyRestrictions(
+ expiry=0,
+ allowed_calls=[
+ CallScope.transfer(target=ALPHA_USD),
+ CallScope.approve(target=ALPHA_USD),
+ ],
+ ),
+)
+
+# Full example: 24h expiry + spending limit + call scope:
+import time
+expiry = int(time.time()) + 86400
+call = AccountKeychain.authorize_key(
+ key_id="",
+ signature_type=SignatureType.SECP256K1,
+ restrictions=KeyRestrictions(
+ expiry=expiry,
+ limits=[TokenLimit(token=ALPHA_USD, limit=1_000_000)],
+ allowed_calls=[CallScope.transfer(target=ALPHA_USD)],
+ ),
+)
+
+# Revoke an access key (permanent, cannot be re-authorized):
+call = AccountKeychain.revoke_key(key_id="")
+
+# Update spending limit for a key-token pair:
+call = AccountKeychain.update_spending_limit(
+ key_id="",
+ token=str(ALPHA_USD),
+ new_limit=2_000_000,
+)
+
+# Replace all call scopes for a key:
+call = AccountKeychain.set_allowed_calls(
+ key_id="",
+ scopes=[
+ CallScope.transfer(target=ALPHA_USD),
+ CallScope.unrestricted(target=""),
+ ],
+)
+
+# Remove a target contract from allowed call list:
+call = AccountKeychain.remove_allowed_calls(
+ key_id="",
+ target="",
+)
+
+# Query key info (read-only):
+key_info = AccountKeychain.get_key(
+ w3,
+ account_address="",
+ key_id="",
+)
+print(key_info)
+# {'signature_type': 0, 'key_id': '0x...', 'expiry': 1893456000, ...}
+
+# Query remaining spending limit:
+remaining = AccountKeychain.get_remaining_limit(
+ w3,
+ account_address="",
+ key_id="",
+ token_address=str(ALPHA_USD),
+)
+print(f"Remaining: {remaining}")
+```
+
+### Signing with an Access Key
+
+Use `sign_access_key` to sign a transaction as an access key holder:
+
+```python [access_key_sign.py]
+from pytempo import TempoTransaction, Call
+
+tx = TempoTransaction.create(
+ chain_id=w3.eth.chain_id,
+ gas_limit=100_000,
+ max_fee_per_gas=w3.eth.gas_price * 2,
+ max_priority_fee_per_gas=w3.eth.gas_price,
+ nonce=w3.eth.get_transaction_count(root_account_address),
+ calls=(Call.create(to=""),),
+)
+
+signed_tx = tx.sign_access_key( # [!code hl]
+ access_key_private_key="", # [!code hl]
+ root_account="", # [!code hl]
+) # [!code hl]
+tx_hash = w3.eth.send_raw_transaction(signed_tx.encode())
+```
+
## Next Steps
After setting up the Python SDK, you can:
diff --git a/src/snippets/tempo-tx-properties.mdx b/src/snippets/tempo-tx-properties.mdx
index e078dd0e..3080c48a 100644
--- a/src/snippets/tempo-tx-properties.mdx
+++ b/src/snippets/tempo-tx-properties.mdx
@@ -225,7 +225,7 @@ user's preferred fee token and the validator's preferred token.
valid_after,
fee_token, // [!code focus]
fee_payer_signature,
- authorization_list,
+ authorization_list, // T3: renamed to aa_authorization_list
key_authorization,
signature,
])
@@ -840,6 +840,10 @@ to sign transactions on its behalf.
This authorization is then attached to the next transaction (that can be signed by either the primary or the access key), then all
transactions thereafter can be signed by the access key.
+:::info[T3 will change this section]
+Post-T3, access keys gain periodic limits and call scoping, and access-key-signed transactions can no longer create contracts. The comments below show which fields and ABIs change.
+:::
+
@@ -938,6 +942,7 @@ transactions thereafter can be signed by the access key.
key_id: access_key.address(), // [!code hl]
expiry: None, // [!code hl]
limits: None, // [!code hl]
+ // T3: add `allowed_calls: None` here; `limits` entries can also include a period // [!code hl]
}; // [!code hl]
let sig = root.sign_hash_sync(&authorization.signature_hash())?; // [!code hl]
let key_authorization = SignedKeyAuthorization { // [!code hl]
@@ -1017,6 +1022,7 @@ transactions thereafter can be signed by the access key.
key_id=access_key.address, # [!code hl]
expiry=int(time.time()) + 3600, # [!code hl]
limits=None, # [!code hl]
+ # T3: add `allowed_calls=None` here; `limits` entries can also include a period # [!code hl]
) # [!code hl]
signed_auth = auth.sign(account.key.hex()) # [!code hl]
@@ -1092,8 +1098,9 @@ transactions thereafter can be signed by the access key.
gasPrice := big.NewInt(25_000_000_000)
keychainAddr := common.HexToAddress(keychain.AccountKeychainAddress)
- // Authorize the access key via Account Keychain precompile // [!code hl]
- parsed, _ := abi.JSON(strings.NewReader(`[{
+ // Authorize the access key via Account Keychain precompile // [!code hl]
+ // T3: this ABI expands to add `period`, `allowAnyCalls`, and `allowedCalls` // [!code hl]
+ parsed, _ := abi.JSON(strings.NewReader(`[{
"name": "authorizeKey",
"type": "function",
"inputs": [
@@ -1171,6 +1178,7 @@ transactions thereafter can be signed by the access key.
```bash
# 1. Authorize the access key via Account Keychain precompile
+ # T3: this legacy ABI changes to add `period`, `allowAnyCalls`, and `allowedCalls`
$ cast send 0xAAAAAAAA00000000000000000000000000000000 \
'authorizeKey(address,uint8,uint64,bool,(address,uint256)[])' \
$ACCESS_KEY_ADDR 0 1893456000 false "[]" \
@@ -1203,8 +1211,8 @@ transactions thereafter can be signed by the access key.
valid_after,
fee_token,
fee_payer_signature,
- authorization_list,
- key_authorization, // [!code focus]
+ authorization_list, // T3: renamed to aa_authorization_list
+ key_authorization, // T3: expands with call scoping and periodic limits // [!code focus]
signature,
])
```
diff --git a/vocs.config.ts b/vocs.config.ts
index 2b7027c1..2171657a 100644
--- a/vocs.config.ts
+++ b/vocs.config.ts
@@ -454,6 +454,10 @@ export default defineConfig({
text: 'Specification',
link: '/protocol/tip20/spec',
},
+ {
+ text: 'Virtual addresses',
+ link: '/protocol/tip20/virtual-addresses',
+ },
{
text: 'Reference Implementation',
link: 'https://github.com/tempoxyz/tempo/blob/main/tips/ref-impls/src/TIP20.sol',
@@ -670,7 +674,7 @@ export default defineConfig({
link: '/protocol/upgrades/t3',
},
{
- text: 'T2',
+ text: 'T2 (Active)',
link: '/protocol/upgrades/t2',
},
],