@kramdev-sol/nfc-module
v0.1.0
Published
NFC module for sharing bypass Apple Wallet
Maintainers
Readme
nfc-module
🚀 A React Native (Expo) module for seamless Peer-to-Peer NFC sharing via Host Card Emulation (HCE).
Designed specifically to power IRL-first Web3 experiences, allowing users to share Solana transaction links, wallet addresses, or custom payloads simply by tapping their phones together.
Features
- Android HCE Support: Emulates an NFC Forum Type 4 Tag in the background.
- Smart Payload Generation: Automatically encodes URIs into proper NDEF Short Records directly in TypeScript.
- Promise-based API: Easy-to-use asynchronous methods with proper error handling.
- Event Listeners: React to successful NFC reads in real-time.
- Built for Web3 & Solana: Safely handles custom URI schemes (like
solana:) without corrupting the payload.
Note on iOS: Apple restricts HCE (Host Card Emulation) to Apple Wallet. Therefore, this library is for broadcasting from Android devices. However, iPhones (and other NFC-enabled devices) can seamlessly act as receivers to read the broadcasted data natively without needing an app.
Installation
npm install nfc-moduleAndroid Setup
To allow your app to use NFC and Host Card Emulation, you must update your Android configuration.
- Add the necessary permissions and service declaration to your
android/src/main/AndroidManifest.xml:
<manifest xmlns:android="[http://schemas.android.com/apk/res/android](http://schemas.android.com/apk/res/android)">
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc.hce" android:required="true" />
<application>
<service
android:name="expo.modules.nfcmodule.NdefHostApduService"
android:exported="true"
android:enabled="false"
android:permission="android.permission.BIND_NFC_SERVICE">
<intent-filter>
<action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE" />
</intent-filter>
<meta-data
android:name="android.nfc.cardemulation.host_apdu_service"
android:resource="@xml/apduservice" />
</service>
</application>
</manifest>- Create an
apduservice.xmlfile inandroid/src/main/res/xml/:
<?xml version="1.0" encoding="utf-8"?>
<host-apdu-service xmlns:android="[http://schemas.android.com/apk/res/android](http://schemas.android.com/apk/res/android)"
android:requireDeviceUnlock="false">
<aid-group android:category="other">
<aid-filter android:name="D2760000850101" />
</aid-group>
</host-apdu-service>Usage
Here is a basic example of how to start broadcasting a Solana Pay link or a custom URL.
import { useEffect, useState } from 'react';
import { View, Text, Button, Alert } from 'react-native';
import * as NfcModule from 'nfc-module';
export default function App() {
const [isSharing, setIsSharing] = useState(false);
const payload = 'solana:Fw35M...?amount=0.01'; // Can be any URI or deep link
useEffect(() => {
// Listen for successful reads from another device
const subscription = NfcModule.addNfcReadListener(() => {
Alert.alert('Success', 'Tag was successfully read by another device!');
});
// CRITICAL: Always clean up and stop sharing when unmounting
return () => {
subscription.remove();
if (isSharing) NfcModule.stopSharing();
};
}, [isSharing]);
const toggleSharing = async () => {
try {
if (isSharing) {
await NfcModule.stopSharing();
setIsSharing(false);
} else {
await NfcModule.startSharing(payload);
setIsSharing(true);
}
} catch (error) {
console.error('NFC Error:', error);
}
};
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Status: {isSharing ? 'Broadcasting...' : 'Idle'}</Text>
<Button
title={isSharing ? "Stop Sharing" : "Start Sharing"}
onPress={toggleSharing}
/>
</View>
);
}License
This project is licensed under the MIT License - see the LICENSE file for details.
