From 964716f5a55bea88f6e5224f0fda9e55277b45aa Mon Sep 17 00:00:00 2001 From: Centaur AI Date: Wed, 10 Jun 2026 15:05:06 +0000 Subject: [PATCH] docs: showcase TIP-1053 login flow --- .../use-accounts/authorize-access-keys.mdx | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/pages/guide/use-accounts/authorize-access-keys.mdx b/src/pages/guide/use-accounts/authorize-access-keys.mdx index a88b554c..317febe2 100644 --- a/src/pages/guide/use-accounts/authorize-access-keys.mdx +++ b/src/pages/guide/use-accounts/authorize-access-keys.mdx @@ -15,10 +15,6 @@ import { Tabs, Tab } from 'vocs' Send stablecoin payments using an access key: a secondary signing key that lets you transact without repeated passkey prompts. Access keys can be scoped with spending limits and expiry for security. -:::info[Coming with T5] -After the [T5 network upgrade](/protocol/upgrades/t5), `key_authorization` gains an optional `witness: bytes32` field ([TIP-1053](https://github.com/tempoxyz/tempo/blob/main/tips/tip-1053.md)). "Sign-In with Tempo" style apps can derive a 32-byte witness from their challenge and include it in the access-key authorization, so a single user signature both authorizes the access key and binds to the app's challenge — replacing the current two-prompt flow. No breaking change; existing flows continue to work unchanged. -::: - ## Demo By the end of this guide you will be able to send payments on Tempo using an access key. Notice that no passkey prompt appears when sending a payment. @@ -29,6 +25,37 @@ By the end of this guide you will be able to send payments on Tempo using an acc +To turn this into a login flow, ask your server for a single-use challenge before connect, derive a 32-byte `witness`, and include it in the same access-key authorization. The user approves one passkey prompt, and the signed authorization can be verified by your server before the app uses the access key. + +```ts twoslash [login.ts] +// @noErrors +import { keccak256, parseUnits, stringToBytes } from 'viem' +import { Expiry } from 'accounts' + +const challenge = await fetch('/api/login/challenge').then((res) => res.text()) + +const witness = keccak256( + stringToBytes(`tempo-login:${window.location.origin}:${challenge}`), +) + +const authorizeAccessKey = { + expiry: Expiry.days(7), + limits: [{ + token: '0x20c0000000000000000000000000000000000001', + limit: parseUnits('100', 6), // 100 AlphaUSD + }], + scopes: [{ + target: '0x20c0000000000000000000000000000000000001', + selector: 'transfer(address,uint256)', + }], + witness, +} +``` + +If you are signing the authorization directly with Viem, pass the same `witness` to `accessKey.authorize` or `accessKey.signAuthorization`. + +Your server should verify that the returned key authorization was signed by the expected account, contains the expected `witness`, and matches the expiry, limits, and scopes your app requested. The protocol treats `witness` as opaque `bytes32`, so include your app origin or domain in the witness preimage and make the underlying challenge single-use. + ## Steps ::::steps