ERC8426
ETH-
$ERC8426-
ERC-721 extensionERC-8426: Wallet Pass Extension for NFTs

Your NFT, in the wallet app on your phone.

ERC-8426 is an Ethereum standard that lets an NFT contract say "this token has a pass". Wallets and marketplaces can find it, add it to Apple Wallet or Google Wallet, and know when it needs refreshing. ERC8426 is the first token built on it.

$ERC8426pending
9:415G
Wallet+
Boarding passSEAT 14C
Coffee card6 / 10
Gym membershipACTIVE
ERC8426ERC-8426 PASS
TOKEN#1
NETWORKEthereum
HOLDER0x0000...0000
UPDATEDOn transfer
Added to Wallet
Interface id0xef5f1e71
ExtendsERC-721
CreatedAug 2026
Ethereum block-
The standard

Three small pieces on chain. The rest happens off it.

ERC-8426 doesn't put passes on Ethereum. It adds one view function and two events to an ERC-721 contract, then sets the rules for the server those point to. Pass generation, signing and push delivery stay with whoever issues the pass.

Discovery

Where's the pass?

The contract exposes passURI(tokenId). It returns a URL for that token's pass manifest, a small JSON file that lists how to get the pass on each platform.

  • Advertised through ERC-165 with interface id 0xef5f1e71
  • The URL is the lasting handle, acquisition links can be short-lived
function passURI(uint256 tokenId)
  external view returns (string memory);
Freshness

Is it still current?

When something about a pass changes, most often because the token moved, the contract emits an event. Issuers and indexers watch for it and push the new version to the phone.

  • One event for a single token
  • A batch event for an inclusive range of ids
event PassUpdate(uint256 indexed tokenId);
event BatchPassUpdate(
  uint256 fromTokenId, uint256 toTokenId);
Authorization

Who can act?

A pass can carry buttons that change things. Holding the pass is never enough to press them. Every action needs a signed, single-use challenge and a fresh on-chain ownership read.

  • Sign-In with Ethereum (ERC-4361) is the suggested format
  • Works for normal wallets, ERC-1271 and ERC-6492 accounts
// checked at request time, never cached
ownerOf(tokenId) == signer
How it works

From a token to a card on the lock screen.

This is the path a wallet app or marketplace follows when someone taps "add to wallet" on an ERC-8426 token.

Detect

The app calls supportsInterface(0xef5f1e71). True means the contract speaks ERC-8426.

Resolve

It calls passURI(tokenId) and fetches the JSON manifest at that address.

Prove

For a gated pass, the server answers 401 with a challenge. The holder signs it and the server reads ownerOf.

Acquire

The manifest's formats give an Apple .pkpass link and a Google save link. The phone adds the pass.

Refresh

On transfer the contract emits PassUpdate. The issuer rotates links and pushes the new pass.

What sits on Ethereum

One view function, two events and an ERC-165 answer. Nothing about the pass itself, and no personal data.

passURIPassUpdateBatchPassUpdatesupportsInterface

What sits with the issuer

The manifest, the signed pass files, push registrations, challenges and the ownership checks. Any server that follows the rules can be the issuer.

manifest.json.pkpasssave linkchallenge
Interface

The whole on-chain surface.

Two interfaces. The first is required. The second is optional and lets a contract publish which platform signer its passes should carry, so a wallet can tell a genuine pass from a copy.

IERC721WalletPass.sol
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;

/// ERC-165 interface id: 0xef5f1e71
interface IERC721WalletPass {
    event PassUpdate(uint256 indexed tokenId);
    event BatchPassUpdate(uint256 fromTokenId, uint256 toTokenId);

    function passURI(uint256 tokenId) external view returns (string memory);
}

/// Optional. ERC-165 interface id: 0x470be7e9
interface IERC721WalletPassIssuer {
    function passIssuer() external view returns (string memory);
}
Required interface0xef5f1e71

The selector of passURI(uint256). Events don't count toward an interface id, so this one function is the whole id.

Optional issuer interface0x470be7e9

The selector of passIssuer(). Returns the platform identity the contract's passes are signed under.

Requires
ERC-165ERC-721ERC-1271ERC-4361ERC-6492

The manifest

What passURI points to. A short JSON document served as application/json. Clients ignore manifests with a version or media type they don't know.

version
Required. Currently 1.
formats
Required. Platform keys to https acquisition links. apple and google are defined, other keys can be ignored.
updatedAt
Optional. Unix time of the last change.
issuer
Optional. Platform identities, such as a Google issuer id.
GET passURI(1)
{
  "version": 1,
  "formats": {
    "apple": "https://issuer.example/passes/c3f1.../card.pkpass",
    "google": "https://pay.google.com/gp/v/save/eyJhbGci..."
  },
  "updatedAt": 1754500000,
  "issuer": {
    "google": { "issuerId": "3388000000012345678" }
  }
}
Authorization

A pass is a bearer card. It proves nothing on its own.

Anyone can screenshot a pass or forward a link. So ERC-8426 never lets possession of a pass authorize anything. The standard defines two ways to hand passes out, and one floor every action has to clear.

Public configuration

Open manifest

Anyone can read the manifest and add the pass. Fits art, collectibles and anything where seeing the pass is harmless.

  • Acquisition links aren't proof of anything
  • The manifest may also be mirrored into tokenURI metadata
  • Actions on the pass still need the full authorization floor
Gated configuration

Holders only

A request without proof gets a 401 that points to a challenge. The holder signs it, and each entitled account gets its own links.

  • Links rotate on transfer, or on a new owner's first claim
  • Fits tickets, memberships and anything with value
  • Clients send the proof in request headers

The authorization floor

Any action a pass can trigger needs both checks, every time. Each one covers a gap the other leaves open: rotating links doesn't stop a forwarded link, and a fresh owner read alone doesn't stop a forwarded link while the owner hasn't changed.

For custodial or email-onboarded products there's a narrower capability configuration, where an unguessable link can stand in for the signature. It's bound to one token, action and account, can't transfer, burn or approve, and the fresh ownership read still applies. The standard says plainly that forwarding isn't prevented in this mode.

1Control proof

A signed challenge naming the chain, contract, token, action and verifier, with a single-use nonce and an expiry. Valid for EOAs, ERC-1271 and ERC-6492 accounts.

2Fresh ownership read

An on-chain check of the current owner at request time, ideally at the latest block. Never served from a cache.

Refusal codeStatusWhen
proof_required401A gated request came without a control proof
nonce_invalid401The challenge was used before, expired or never issued
not_owner403The signer doesn't hold the token right now
rate_limited429Too many requests, retrying later can help
read_failed503The server couldn't read the chain, so it refused rather than guess
Checker

Does a contract speak ERC‑8426?

Paste any ERC-721 contract. This reads the chain directly from your browser: it asks for both interface ids, calls passURI for the token you pick, and tries to load the manifest it points to.

Network

result

Enter a contract address and press Check contract. Nothing is sent from your wallet, these are read-only calls to a public Ethereum node.

The token

ERC8426, the first token on ERC‑8426.

A standard needs a first implementation people can hold. ERC8426 carries the standard's name and answers its interface, so it doubles as a live reference that wallets and marketplaces can test against.

$ERC8426

The token contract reports support for 0xef5f1e71, returns a manifest from passURI, and emits PassUpdate when a token moves, so the pass on the old holder's phone goes stale and the new holder's goes live.

$ERC8426pending
Network
Ethereum
Interface
0xef5f1e71
Pass
Apple, Google

Sign a pass challenge

This builds the kind of Sign-In with Ethereum message an ERC-8426 issuer sends before a pass action, and asks your wallet to sign it. Signing is free and moves nothing.

The challenge names the token, the action, a one-time nonce and a five minute expiry.

Security

What the standard asks issuers to watch for.

Bearer artifacts

Passes can be copied. Possession must never authorize an action.

Bounded freshness

A reorg or a lagging node can briefly let a sold token act. Issuers should read from current, trusted nodes.

Leaked stores

A dump of the issuer's database shouldn't hand out working links or capabilities.

Push fan-out

Device registrations for updates need limits so one token can't be used to flood phones.

Approvals after a sale

Authority granted from a token-controlled account can outlive the sale. Refuse it or revoke it on transfer.

Stale, not gone

Old passes should stay reachable so their holders can see that the content is out of date.

FAQ

Questions.

Who wrote ERC-8426?

Hunt (@huntclubhero), in August 2026. It's discussed on Ethereum Magicians and its text is CC0, so anyone can build on it.

Do I need a crypto wallet on my phone to use a pass?

Not to carry it. The pass lives in Apple Wallet or Google Wallet like any boarding pass. You need your Ethereum wallet when an issuer asks you to prove you hold the token, for a gated pass or an action.

Can someone use my pass if they copy it?

They can show a copy, but they can't act with it. Every action needs a fresh signature from the current holder and an on-chain ownership check.

What happens to my pass when I sell the token?

The contract emits PassUpdate. The issuer rotates the links and pushes an update, so your pass shows it's out of date and the buyer can claim a fresh one.

Does it work with ERC-1155?

ERC-8426 is written for ERC-721 and leaves ERC-1155 out of scope.

Is there code I can start from?

Yes. The standard links a CC0 reference contract and server, and there's an open-source SDK with contracts, an issuer, Apple and Google delivery, a client, React hooks and a conformance suite.

Where's the $ERC8426 contract?

0x53c7aafd56922c89d7456f282d961d7d6e6dbd51 on Ethereum. It's also shown under the main buttons, in the token section and in the footer.