project screenshot 1
project screenshot 2
project screenshot 3
project screenshot 4
project screenshot 5

NFC wallet

Turn any NFC tag into an abstracted account on @Base and tap to pay at whitelisted stations.

NFC wallet

Created At

ETHGlobal London

Winner of


Base - Best use of 4337 Account Abstraction 2nd place


ETHGlobal - 🏆 ETHGlobal London Finalist

Project Description

When you organize an event or manage a community space, it’s great to be able to give participants an NFC card, tag or wristband for access control.

With Account Abstraction, we can now turn those NFC tags into a wallet that can hold any asset. People can now top up their NFC tag and tap to pay at a series of whitelisted stations (terminals that have their own account that is whitelisted to avoid abuse).

It allows you to do simple transactions in stablecoins or any other token that can represent finite resources (e.g. number of drinks, food, etc.).

It can be used at events like Ethglobal to manage payment and finite resources to make sure that these are distributed fairly.

Tokens can represent resources like: Food Drinks (e.g. coffee machine) Meeting rooms Workshop access Print credits ….

Next to the NFC wallet we implemented a native NFC payment terminal/PoS application (using Flutter) that can easily withdraw assets from the NFC wallet.

For security reasons the withdrawal devices need to be whitelisted to be able to withdraw funds from the cards.

How it's Made

Cards & Tags Tech: Solidity, ERC4337, ERC20, Smart Contract Accounts, NFC Web API, NFC (iOS & Android)

Purpose: Provide something physical which has a unique identifier that people can use to hold and pay with assets on chain. Side goal: convert all ETHGlobal wristbands into Smart Accounts.

The core concept here is that based on a serial number, we are able to generate a Smart Contract Address. The serial number is not stored or sent to the chain, it is converted to a hash off-chain and then sent to the Smart Contract.

The serial numbers are obtained by reading the serial number of NFC tags.

This is a hexadecimal number that we pack and keccack256 hash together with the chain id and smart contract address to generate a bytes32 “cardHash”.

This “cardHash” is used to get, create or withdraw from a card.

This stops people being able to just scan the contract for created accounts and creates the necessity for the original NFC tag to be read.

For this to work, we use two smart contracts. A Manager contract and a smart account contract. The Manager contract uses CREATE2 to counterfactually generate account addresses.

Cards are fully-fledged Smart Account Contracts and can always be “detached” from their Card Manager by transferring ownership away.

Whitelist Tech: Solidity

Purpose: Have control over who can withdraw from the Cards. Register known vendors or kiosks that would accept these cards.

Cards have a “withdrawTo” function which can only be called by accounts in a whitelist. This whitelist is stored in the Manager that deploys them. This whitelist is therefore global to all Cards and can be updated by the owner of the Manager contract.

NFC POS App Tech: Flutter, iOS, Android, NFC, ERC4337, Smart Contract Accounts, Bundler

Purpose: Provide an easy way for a vendor to specify products, amounts and collect assets from an NFC tag’s Smart Account.

A simple Flutter app with two screens: Configuration: create a list of products with names and prices. Vendor mode: tap a product to enable NFC tag scanning and collect the amount specified

When the POS App starts, it generates a private key for itself and a Smart Account associated with it. Its Account address can then be whitelisted on the Card Manager.

It is then able to withdraw from Cards without the need for gas.

Since Cards don’t need to be deployed until a function call is required, they are only deployed the first time the “withdrawTo” function is called on the Card Manager.

Same with the App’s own Smart Account. In true ERC4337 fashion, it is only deployed when the first transaction is made to withdraw from a card.

NFC Web Reader Tech: NextJS, React, Scaffold ETH 2, Web NFC API

Purpose: Provide an easy way for users to view the balance of their NFC tag. Bonus: load the profile photo and name from the ETHGlobal wristband.

Anyone who has an NFC tag can tap it to a device that is compatible with the Web NFC API and has an NFC reader. This works with any recent Android device on Chrome. iOS is not supported.

If it is an ETHGlobal wristband and contains a link to the user’s profile, display their photo and name.

Users can see the balance of their wristband’s Smart Account on the assets that it supports.

ERC4337 Tech: Bundler, Paymaster

In order to create a smooth experience, gas fees are sponsored using ERC4337.

We use Citizen Wallet’s Community Entrypoint, Bundler and Paymaster to process the user operations. It’s simple, fast and restricted to the ERC20 token we are working with.

Chain Tech: Base Mainnet and Base Sepolia

We tested our implementation on Base Sepolia and then published to Base Mainnet.

Base is fast, reliable and has become cost effective to use thanks to the recent L2 gas optimizations that have been implemented.


We turned all ETHGlobal NFC bracelets into Smart Accounts that can transact USDC on Base. These bracelets can be topped up and pay using the POS App.


Card Manager is an adaptation of the Ethereum Foundation’s “Simple Account Factory” ( ).

Card is an adaptation of the Ethereum Foundation’s “Simple Account” ( ).

Card Manager is deployed along with an implementation of Card ( ). This allows it to be a factory for cards.

A Sample Card that was deployed by the Card Manager ( ). It has received 1 USDC ( ) and paid 1 USDC ( ) to a POS App’s Smart Contract Account.

POS App Smart Contract Account ( ).

Keep in mind that the code is stored in 2 separate Git repos NFC Web Read:

POS App + Smart Contracts:

background image mobile

Join the mailing list

Get the latest news and updates