@spencerls/react-native-nfc 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/services/nfc/index.ts","../src/services/nfc/service.ts","../src/services/nfc/a/index.ts","../src/services/nfc/a/operations.ts","../src/services/nfc/a/utils.ts","../src/services/nfc/ndef/index.ts","../src/services/nfc/ndef/operations.ts","../src/services/nfc/ndef/utils.ts","../src/services/nfc/v/index.ts","../src/services/nfc/v/operations.ts","../src/services/nfc/v/internal.ts","../src/services/nfc/v/utils.ts","../src/services/nfc/namespace.ts"],"sourcesContent":["export { nfc } from \"./namespace\";\r\nexport { nfcService } from \"./service\";\r\n\r\n// Export all protocol bundles\r\nexport * as nfcA from \"./a\";\r\nexport * as ndef from \"./ndef\";\r\nexport * as nfcV from \"./v\";\r\n\r\n// Export shared types\r\nexport * from \"./types\";\r\n","// NfcService.ts\r\nimport { Platform } from \"react-native\";\r\nimport NfcManager, {\r\n NfcEvents,\r\n NfcTech,\r\n TagEvent,\r\n} from \"react-native-nfc-manager\";\r\nimport { NfcMode, NfcState } from \"./types\";\r\n\r\nexport type NfcListener = (state: NfcState) => void;\r\n\r\nexport class NfcService {\r\n private state: NfcState = { mode: \"idle\", tag: null };\r\n\r\n private listeners = new Set<NfcListener>();\r\n\r\n constructor() {\r\n NfcManager.start();\r\n }\r\n\r\n // --- internal state mgmt ---\r\n private setState(partial: Partial<NfcState>) {\r\n this.state = { ...this.state, ...partial };\r\n\r\n for (const listener of this.listeners) listener(this.state);\r\n }\r\n\r\n getState() {\r\n return this.state;\r\n }\r\n\r\n subscribe(fn: NfcListener) {\r\n this.listeners.add(fn);\r\n fn(this.state); // emit current state immediately\r\n return () => {\r\n this.listeners.delete(fn);\r\n };\r\n }\r\n\r\n // --- Reader lifecycle ---\r\n async startReader(readerModeFlags: number, onTag?: (tag: TagEvent) => void) {\r\n if (this.state.mode !== \"idle\") {\r\n console.warn(`[NFC] Cannot start reader while ${this.state.mode}`);\r\n return;\r\n }\r\n\r\n this.setState({ mode: \"starting\" });\r\n\r\n NfcManager.setEventListener(NfcEvents.DiscoverTag, (tag: TagEvent) => {\r\n this.setState({ tag: tag });\r\n onTag?.(tag);\r\n });\r\n\r\n try {\r\n await NfcManager.registerTagEvent({\r\n isReaderModeEnabled: true,\r\n readerModeFlags,\r\n });\r\n if ((this.state.mode as NfcMode) === \"starting\") {\r\n this.setState({ mode: \"active\" });\r\n }\r\n } catch (err) {\r\n console.warn(\"[NFC] startReader error:\", err);\r\n this.setState({ mode: \"idle\" });\r\n }\r\n }\r\n\r\n async stopReader() {\r\n if ([\"idle\", \"stopping\"].includes(this.state.mode)) return;\r\n this.setState({ mode: \"stopping\" });\r\n try {\r\n await NfcManager.unregisterTagEvent();\r\n } catch {}\r\n this.setState({ mode: \"idle\" });\r\n }\r\n\r\n async withTechnology<T>(\r\n tech: NfcTech | NfcTech[],\r\n handler: () => Promise<T>\r\n ): Promise<T> {\r\n if (this.state.mode === \"technology\") {\r\n throw new Error(`[NFC] Technology is already in use!`);\r\n }\r\n if (\r\n this.state.mode === \"starting\" ||\r\n this.state.mode === \"active\" ||\r\n this.state.mode === \"stopping\"\r\n ) {\r\n await this.stopReader();\r\n }\r\n\r\n if (this.state.mode !== \"idle\") {\r\n throw new Error(\r\n `[NFC] Cannot start technology session in mode ${this.state.mode}`\r\n );\r\n }\r\n\r\n this.setState({ mode: \"technology\" });\r\n\r\n try {\r\n await NfcManager.requestTechnology(tech, {\r\n alertMessage: \"Hold near NFC tag\", // iOS\r\n });\r\n\r\n const result = await handler();\r\n\r\n if (Platform.OS === \"ios\")\r\n await NfcManager.setAlertMessageIOS(\"Success!\");\r\n\r\n return result;\r\n } catch (err: any) {\r\n const message =\r\n typeof err === \"string\" ? err : err?.message || \"Unknown NFC error\";\r\n throw new Error(`[NFC] withTechnology error: ${message}`);\r\n } finally {\r\n try {\r\n await NfcManager.cancelTechnologyRequest();\r\n } catch (cancelErr) {\r\n console.warn(\"[NFC] cancelTechnologyRequest failed:\", cancelErr);\r\n }\r\n this.setState({ mode: \"idle\" });\r\n }\r\n }\r\n}\r\n\r\n// Export one stable instance\r\nexport const nfcService = new NfcService();\r\n","export { operations } from \"./operations\";\r\nexport { utils } from \"./utils\";\r\n","import NfcManager, { NfcTech } from \"react-native-nfc-manager\";\r\nimport { nfcService } from \"../service\";\r\n\r\nexport const operations = {\r\n async transceive(data: number[]) {\r\n return nfcService.withTechnology(NfcTech.NfcA, async () => {\r\n return await NfcManager.transceive(data);\r\n });\r\n },\r\n};\r\n","export const utils = {};\r\n","export { operations } from \"./operations\";\r\nexport { utils } from \"./utils\";\r\n","import NfcManager, {\r\n Ndef,\r\n NdefRecord,\r\n NfcTech,\r\n} from \"react-native-nfc-manager\";\r\nimport { nfcService } from \"../service\";\r\n\r\nexport const operations = {\r\n async writeNdef(records: NdefRecord[]) {\r\n // Use NFC-A/Type 2 as fallback (often required on Android)\r\n await nfcService.withTechnology([NfcTech.Ndef, NfcTech.NfcA], async () => {\r\n const bytes = Ndef.encodeMessage(records);\r\n await NfcManager.ndefHandler.writeNdefMessage(bytes);\r\n });\r\n },\r\n\r\n writeTextNdef(text: string) {\r\n const record = Ndef.textRecord(text);\r\n return this.writeNdef([record]);\r\n },\r\n\r\n writeUriNdef(uri: string) {\r\n const record = Ndef.uriRecord(uri);\r\n return this.writeNdef([record]);\r\n },\r\n};\r\n","export const utils = {};\r\n","export { operations } from \"./operations\";\r\nexport { utils } from \"./utils\";\r\n","import NfcManager from \"react-native-nfc-manager\";\r\nimport { nfcService } from \"../service\";\r\nimport {\r\n getSystemInfoRaw,\r\n readBlockRaw,\r\n StrictTagEvent,\r\n writeBlockRaw,\r\n} from \"./internal\";\r\nimport { utils } from \"./utils\";\r\n\r\nexport const operations = {\r\n async withVTag<T>(handler: (tag: StrictTagEvent) => Promise<T>): Promise<T> {\r\n return nfcService.withTechnology(utils.tech, async () => {\r\n const tag = await NfcManager.getTag();\r\n if (!tag?.id) throw new Error(\"No NFC-V tag detected\");\r\n return handler(tag as StrictTagEvent);\r\n });\r\n },\r\n\r\n async writeBlockNfcV(blockNumber: number, data: Uint8Array) {\r\n return this.withVTag((tag) => writeBlockRaw(tag, blockNumber, data));\r\n },\r\n\r\n async readBlockNfcV(blockNumber: number) {\r\n return this.withVTag((tag) => readBlockRaw(tag, blockNumber));\r\n },\r\n\r\n async getSystemInfoNfcV() {\r\n return this.withVTag((tag) => getSystemInfoRaw(tag));\r\n },\r\n};\r\n","import NfcManager, { TagEvent } from \"react-native-nfc-manager\";\r\nimport { utils } from \"./utils\";\r\n\r\nexport type StrictTagEvent = TagEvent & {\r\n id: string;\r\n};\r\n\r\nexport async function readBlockRaw(tag: StrictTagEvent, blockNumber: number) {\r\n const uid = utils.reverseUid(tag.id);\r\n const cmd = utils.buildReadBlock(uid, blockNumber);\r\n const resp = await NfcManager.transceive(cmd);\r\n return utils.parseReadResponse(resp);\r\n}\r\n\r\nexport async function writeBlockRaw(\r\n tag: StrictTagEvent,\r\n blockNumber: number,\r\n data: Uint8Array\r\n) {\r\n const uid = utils.reverseUid(tag.id);\r\n const cmd = utils.buildWriteBlock(uid, blockNumber, data);\r\n const resp = await NfcManager.transceive(cmd);\r\n return utils.parseWriteResponse(resp);\r\n}\r\n\r\nexport async function getSystemInfoRaw(tag: StrictTagEvent) {\r\n const uid = utils.reverseUid(tag.id);\r\n const cmd = utils.buildGetSystemInfo(uid);\r\n const resp = await NfcManager.transceive(cmd);\r\n return utils.parseSystemInfo(resp);\r\n}\r\n","import { Platform } from \"react-native\";\r\nimport { NfcTech } from \"react-native-nfc-manager\";\r\n\r\n// Here's where things get REAL\r\n//\r\n// Only iPhone 7+ supports ISO15693; writing may require\r\n// requestTechnology([NfcTech.Iso15693]) and sometimes doesn’t allow raw\r\n// transceive (depends on firmware)\r\n//\r\n// | Byte | Meaning |\r\n// | ------------- | ---------------------------------------------------- |\r\n// | `0x02` | Flags (high data rate) |\r\n// | `0x20` | Flags (addressed) |\r\n// | `0x22` | Flags (0x02 + 0x20 = 0x22 addressed + high data rate)|\r\n// | `0x20` | Command code: Read Single Block |\r\n// | `0x21` | Command code: Write Single Block |\r\n// | `UID[0..7]` | Tag UID in reverse order (optional if not addressed) |\r\n// | `blockNumber` | Which memory block to write |\r\n// | `data[...]` | The bytes to write (block size usually 4 or 8 bytes) |\r\n//\r\n// Each command is a byte array\r\n// [ FLAGS, COMMAND_CODE, [UID bytes reversed], PARAMS... ]\r\n//\r\n// Tag response:\r\n// The tag response has this structure:\r\n//\r\n// | Byte | Meaning |\r\n// | ---- | --------------------------------------------- |\r\n// | `0` | **Status** (0x00 = success) |\r\n// | `1` | **Info Flags** |\r\n// | … | Data fields, conditional based on those flags |\r\n//\r\n// Info Flags bitmask:\r\n// | Bit | Hex | Meaning |\r\n// | --- | ---- | ------------------------------------------------------------- |\r\n// | 0 | 0x01 | DSFID present |\r\n// | 1 | 0x02 | AFI present |\r\n// | 2 | 0x04 | VICC memory size info present (number of blocks + block size) |\r\n// | 3 | 0x08 | IC reference present |\r\n// | 4–7 | — | RFU (reserved) |\r\n\r\nexport const utils = {\r\n tech: Platform.OS === \"ios\" ? [NfcTech.Iso15693IOS] : NfcTech.NfcV,\r\n\r\n Flags: {\r\n HIGH_DATA_RATE: 0x02,\r\n ADDRESSED: 0x20,\r\n // If needed later: OPTION: 0x40 (not commonly used)\r\n },\r\n\r\n Commands: {\r\n READ_SINGLE_BLOCK: 0x20,\r\n WRITE_SINGLE_BLOCK: 0x21,\r\n GET_SYSTEM_INFO: 0x2b,\r\n },\r\n\r\n /**\r\n * Combine multiple flag bits into one byte.\r\n * Example: Flags.ADDRESSED | Flags.HIGH_DATA_RATE\r\n */\r\n flags(...bits: number[]): number {\r\n return bits.reduce((acc, bit) => acc | bit, 0);\r\n },\r\n\r\n /**\r\n * Convert tag.id hex string (MSB->LSB) into reversed byte array (LSB->MSB)\r\n * ISO15693 requires reversed UID for addressed commands.\r\n */\r\n reverseUid(tagIdHex: string): number[] {\r\n const bytes = [];\r\n for (let i = 0; i < tagIdHex.length; i += 2) {\r\n bytes.unshift(parseInt(tagIdHex.substring(i, i + 2), 16));\r\n }\r\n return bytes;\r\n },\r\n\r\n /**\r\n * Build READ_SINGLE_BLOCK command.\r\n * FLAGS: addressed + high data rate by default.\r\n */\r\n buildReadBlock(uidReversed: number[], blockNumber: number): number[] {\r\n const flags = this.flags(this.Flags.ADDRESSED, this.Flags.HIGH_DATA_RATE);\r\n return [\r\n flags,\r\n this.Commands.READ_SINGLE_BLOCK,\r\n ...uidReversed,\r\n blockNumber,\r\n ];\r\n },\r\n\r\n /**\r\n * Build WRITE_SINGLE_BLOCK command.\r\n * Note: data must match the block size (usually 4 or 8 bytes).\r\n */\r\n buildWriteBlock(\r\n uidReversed: number[],\r\n blockNumber: number,\r\n data: Uint8Array\r\n ): number[] {\r\n const flags = this.flags(this.Flags.ADDRESSED, this.Flags.HIGH_DATA_RATE);\r\n return [\r\n flags,\r\n this.Commands.WRITE_SINGLE_BLOCK,\r\n ...uidReversed,\r\n blockNumber,\r\n ...data,\r\n ];\r\n },\r\n\r\n /**\r\n * Build GET_SYSTEM_INFO command.\r\n */\r\n buildGetSystemInfo(uidReversed: number[]): number[] {\r\n return [this.Flags.HIGH_DATA_RATE, this.Commands.GET_SYSTEM_INFO];\r\n },\r\n\r\n /**\r\n * Parse a READ_SINGLE_BLOCK response.\r\n * Response format:\r\n * - byte[0] = status (0x00 = success)\r\n * - byte[1..] = block payload bytes\r\n */\r\n parseReadResponse(resp: number[]): Uint8Array {\r\n if (!resp || resp.length === 0) {\r\n throw new Error(\"Empty NFC-V response\");\r\n }\r\n if (resp[0] !== 0x00) {\r\n throw new Error(`Read failed. Status: 0x${resp[0].toString(16)}`);\r\n }\r\n return new Uint8Array(resp.slice(1));\r\n },\r\n\r\n /**\r\n * Parse WRITE_SINGLE_BLOCK response.\r\n * Successful write has resp[0] === 0x00.\r\n */\r\n parseWriteResponse(resp: number[]): void {\r\n if (!resp || resp.length === 0) {\r\n throw new Error(\"Empty NFC-V response\");\r\n }\r\n if (resp[0] !== 0x00) {\r\n throw new Error(`Write failed. Status: 0x${resp[0].toString(16)}`);\r\n }\r\n },\r\n\r\n /**\r\n * Parse GET_SYSTEM_INFO response.\r\n * Returns: UID, DSFID, AFI, numberOfBlocks, blockSize, manufacturer\r\n */\r\n parseSystemInfo(resp: number[]) {\r\n if (!resp || resp.length < 2 || resp[0] !== 0x00) {\r\n throw new Error(\"Invalid System Info response\");\r\n }\r\n\r\n const infoFlags = resp[1] & 0x0f;\r\n let offset = 2;\r\n\r\n const result: any = {};\r\n\r\n // UID (always present – next 8 bytes)\r\n if (resp.length >= offset + 8) {\r\n const uidBytes = resp.slice(offset, offset + 8);\r\n result.uid = uidBytes\r\n .slice()\r\n .reverse()\r\n .map((b) => b.toString(16).padStart(2, \"0\"))\r\n .join(\"\")\r\n .toUpperCase();\r\n offset += 8;\r\n }\r\n\r\n // DSFID\r\n if (infoFlags & 0x01 && resp.length > offset) {\r\n result.dsfid = resp[offset++];\r\n }\r\n\r\n // AFI\r\n if (infoFlags & 0x02 && resp.length > offset) {\r\n result.afi = resp[offset++];\r\n }\r\n\r\n // Memory size info\r\n if (infoFlags & 0x04 && resp.length >= offset + 2) {\r\n result.numberOfBlocks = resp[offset++] + 1;\r\n result.blockSize = resp[offset++] + 1;\r\n }\r\n\r\n // IC Reference\r\n if (infoFlags & 0x08 && resp.length > offset) {\r\n result.icReference = resp[offset++];\r\n }\r\n\r\n if (!result.blockSize) result.blockSize = 4; // default for EM Micro\r\n\r\n result.manufacturer = this.detectManufacturer(result.uid ?? \"\");\r\n\r\n return result;\r\n },\r\n\r\n /** Identify common manufacturers based on UID prefix */\r\n detectManufacturer(uid: string): string {\r\n if (\r\n uid.startsWith(\"E004\") ||\r\n uid.startsWith(\"E006\") ||\r\n uid.startsWith(\"E016\")\r\n )\r\n return \"EM Microelectronic\";\r\n if (uid.startsWith(\"E002\")) return \"STMicroelectronics\";\r\n if (uid.startsWith(\"E007\")) return \"Texas Instruments\";\r\n if (uid.startsWith(\"E010\")) return \"NXP\";\r\n return \"Unknown\";\r\n },\r\n} as const;\r\n","import { nfcService } from \"./service\";\r\n\r\nimport { operations as aOps, utils as aUtils } from \"./a\";\r\nimport { operations as ndefOps, utils as ndefUtils } from \"./ndef\";\r\nimport { operations as vOps, utils as vUtils } from \"./v\";\r\n/**\r\n * NFC root namespace providing access to:\r\n * - NfcService\r\n * - ISO15693 NFC-V ops\r\n * - NFC-A ops\r\n * - NDEF operations\r\n */\r\nexport const nfc = {\r\n service: nfcService,\r\n\r\n /** ISO15693 protocol helpers and high-level operations */\r\n v: {\r\n ...vOps, // NfcVOperations, nfcV\r\n utils: vUtils,\r\n },\r\n\r\n /** NFC-A / Type 2 helpers and operations */\r\n a: {\r\n ...aOps,\r\n utils: aUtils,\r\n },\r\n\r\n /** NDEF read/write utilities and operations */\r\n ndef: {\r\n ...ndefOps,\r\n utils: ndefUtils,\r\n },\r\n} as const;\r\n"],"mappings":"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","names":["NfcManager","import_react_native_nfc_manager","NfcManager","operations","utils","import_react_native_nfc_manager","operations","NfcManager","utils","operations","utils","import_react_native_nfc_manager","import_react_native_nfc_manager","import_react_native","import_react_native_nfc_manager","utils","utils","NfcManager","operations","utils","NfcManager","operations","utils"]}
1
+ {"version":3,"sources":["../src/nfc/index.ts","../src/nfc/a/index.ts","../src/nfc/a/operations.ts","../src/nfc/service.ts","../src/nfc/a/utils.ts","../src/nfc/v/index.ts","../src/nfc/v/operations.ts","../src/nfc/v/internal.ts","../src/nfc/v/utils.ts","../src/nfc/ndef/index.ts","../src/nfc/ndef/operations.ts","../src/nfc/ndef/utils.ts","../src/nfc/namespace.ts"],"sourcesContent":["// biome-ignore assist/source/organizeImports: It is already organized well\nexport * as nfcA from \"./a\";\nexport * as nfcV from \"./v\";\nexport * as nfcNdef from \"./ndef\";\n\nexport { nfc } from \"./namespace\";\nexport { nfcService } from \"./service\";\nexport * from \"./types\";\n","export { operations } from \"./operations\";\nexport { utils } from \"./utils\";\n","import NfcManager, { NfcTech } from \"react-native-nfc-manager\";\n\nimport { nfcService } from \"../service\";\n\nexport const operations = {\n async transceive(data: number[]) {\n return nfcService.withTechnology(NfcTech.NfcA, async () => {\n return await NfcManager.transceive(data);\n });\n },\n};\n","import { Platform } from \"react-native\";\nimport NfcManager, {\n NfcEvents,\n type NfcTech,\n type TagEvent,\n} from \"react-native-nfc-manager\";\n\nimport type { NfcMode, NfcState } from \"./types\";\n\nexport type NfcListener = (state: NfcState) => void;\n\nexport class NfcService {\n private state: NfcState = { mode: \"idle\", tag: null };\n private listeners = new Set<NfcListener>();\n\n private isProcessingTag = false;\n private currentOnTag?: (tag: TagEvent) => Promise<void> | void;\n private currentCooldownMs = 1500;\n private lastUsedReaderFlags: number | null = null; // needed for iOS restart\n\n constructor() {\n NfcManager.start();\n }\n\n // -----------------------------\n // Internal state management\n // -----------------------------\n private setState(partial: Partial<NfcState>) {\n this.state = { ...this.state, ...partial };\n for (const listener of this.listeners) listener(this.state);\n }\n\n getState() {\n return this.state;\n }\n\n subscribe(fn: NfcListener) {\n this.listeners.add(fn);\n fn(this.state);\n return () => {\n this.listeners.delete(fn); // ignore boolean\n };\n }\n\n // -----------------------------\n // START READER\n // -----------------------------\n async startReader(\n readerModeFlags: number,\n onTag?: (tag: TagEvent) => Promise<void> | void,\n options?: { cooldownMs?: number },\n ) {\n if (this.state.mode !== \"idle\") {\n console.warn(`[NFC] Cannot start reader while ${this.state.mode}`);\n return;\n }\n\n this.currentOnTag = onTag;\n this.currentCooldownMs = options?.cooldownMs ?? 1500;\n this.lastUsedReaderFlags = readerModeFlags;\n this.isProcessingTag = false;\n\n this.setState({ mode: \"starting\", tag: null });\n\n NfcManager.setEventListener(\n NfcEvents.DiscoverTag,\n async (tag: TagEvent) => {\n if (!tag) return;\n\n // Soft lock to avoid duplicate processing\n if (this.isProcessingTag) return;\n\n this.isProcessingTag = true;\n this.setState({ tag, mode: \"active\" });\n\n try {\n if (this.currentOnTag) {\n await this.currentOnTag(tag);\n }\n } catch (err) {\n console.warn(\"[NFC] onTag handler error:\", err);\n } finally {\n const cooldown = this.currentCooldownMs;\n\n setTimeout(async () => {\n this.isProcessingTag = false;\n this.setState({ tag: null, mode: \"active\" });\n\n // -----------------------------\n // iOS MUST restart reader\n // -----------------------------\n if (Platform.OS === \"ios\") {\n await this._restartIosReader();\n }\n }, cooldown);\n }\n },\n );\n\n try {\n await NfcManager.registerTagEvent({\n isReaderModeEnabled: true,\n readerModeFlags,\n });\n\n if ((this.state.mode as NfcMode) === \"starting\") {\n this.setState({ mode: \"active\" });\n }\n } catch (err) {\n console.warn(\"[NFC] startReader error:\", err);\n this._resetReaderState();\n }\n }\n\n // -----------------------------\n // STOP READER\n // -----------------------------\n async stopReader() {\n if ([\"idle\", \"stopping\"].includes(this.state.mode)) return;\n\n this.setState({ mode: \"stopping\" });\n\n try {\n await NfcManager.unregisterTagEvent();\n } catch (err) {\n console.warn(\"[NFC] unregisterTagEvent error:\", err);\n }\n\n this._resetReaderState();\n }\n\n private _resetReaderState() {\n this.setState({ mode: \"idle\", tag: null });\n this.currentOnTag = undefined;\n this.isProcessingTag = false;\n // keep lastUsedReaderFlags so iOS restart can keep using them\n }\n\n // -----------------------------\n // iOS RESTART\n // -----------------------------\n private async _restartIosReader() {\n if (Platform.OS !== \"ios\") return;\n if (this.lastUsedReaderFlags == null) return;\n\n try {\n await NfcManager.unregisterTagEvent();\n await NfcManager.registerTagEvent({\n isReaderModeEnabled: true,\n readerModeFlags: this.lastUsedReaderFlags,\n });\n\n this.setState({ mode: \"active\" });\n } catch (err) {\n console.warn(\"[NFC] iOS restart error:\", err);\n this._resetReaderState();\n }\n }\n\n // -----------------------------\n // Technology sessions (NDEF, NfcV, etc.)\n // -----------------------------\n async withTechnology<T>(\n tech: NfcTech | NfcTech[],\n handler: () => Promise<T>,\n ): Promise<T> {\n if (this.state.mode === \"technology\") {\n throw new Error(\"[NFC] Technology is already in use!\");\n }\n\n // Reader must be stopped for tech sessions\n if ([\"starting\", \"active\", \"stopping\"].includes(this.state.mode)) {\n await this.stopReader();\n }\n\n if (this.state.mode !== \"idle\") {\n throw new Error(\n `[NFC] Cannot start technology session in mode ${this.state.mode}`,\n );\n }\n\n this.setState({ mode: \"technology\", tag: null });\n\n try {\n await NfcManager.requestTechnology(tech, {\n alertMessage: \"Hold near NFC tag\",\n });\n\n const result = await handler();\n\n if (Platform.OS === \"ios\") {\n await NfcManager.setAlertMessageIOS(\"Success!\");\n }\n\n return result;\n } catch (err: any) {\n const message =\n typeof err === \"string\" ? err : err?.message || \"Unknown NFC error\";\n throw new Error(`[NFC] withTechnology error: ${message}`);\n } finally {\n try {\n await NfcManager.cancelTechnologyRequest();\n } catch {}\n\n this.setState({ mode: \"idle\", tag: null });\n }\n }\n}\n\n// Export one stable instance\nexport const nfcService = new NfcService();\n","export const utils = {};\n","export { operations } from \"./operations\";\nexport { utils } from \"./utils\";\n","import NfcManager from \"react-native-nfc-manager\";\n\nimport { nfcService } from \"../service\";\nimport {\n getSystemInfoRaw,\n readBlockRaw,\n type StrictTagEvent,\n writeBlockRaw,\n} from \"./internal\";\nimport { utils } from \"./utils\";\n\nexport const operations = {\n async withVTag<T>(handler: (tag: StrictTagEvent) => Promise<T>): Promise<T> {\n return nfcService.withTechnology(utils.tech, async () => {\n const tag = await NfcManager.getTag();\n if (!tag?.id) throw new Error(\"No NFC-V tag detected\");\n return handler(tag as StrictTagEvent);\n });\n },\n\n async writeBlockNfcV(blockNumber: number, data: Uint8Array) {\n return this.withVTag((tag) => writeBlockRaw(tag, blockNumber, data));\n },\n\n async readBlockNfcV(blockNumber: number) {\n return this.withVTag((tag) => readBlockRaw(tag, blockNumber));\n },\n\n async getSystemInfoNfcV() {\n return this.withVTag((tag) => getSystemInfoRaw(tag));\n },\n};\n","import NfcManager, { type TagEvent } from \"react-native-nfc-manager\";\n\nimport { utils } from \"./utils\";\n\nexport type StrictTagEvent = TagEvent & {\n id: string;\n};\n\nexport async function readBlockRaw(tag: StrictTagEvent, blockNumber: number) {\n const uid = utils.reverseUid(tag.id);\n const cmd = utils.buildReadBlock(uid, blockNumber);\n const resp = await NfcManager.transceive(cmd);\n return utils.parseReadResponse(resp);\n}\n\nexport async function writeBlockRaw(\n tag: StrictTagEvent,\n blockNumber: number,\n data: Uint8Array,\n) {\n const uid = utils.reverseUid(tag.id);\n const cmd = utils.buildWriteBlock(uid, blockNumber, data);\n const resp = await NfcManager.transceive(cmd);\n return utils.parseWriteResponse(resp);\n}\n\nexport async function getSystemInfoRaw(tag: StrictTagEvent) {\n const uid = utils.reverseUid(tag.id);\n const cmd = utils.buildGetSystemInfo(uid);\n const resp = await NfcManager.transceive(cmd);\n return utils.parseSystemInfo(resp);\n}\n","import { Platform } from \"react-native\";\nimport { NfcTech } from \"react-native-nfc-manager\";\n\n// Here's where things get REAL\n//\n// Only iPhone 7+ supports ISO15693; writing may require\n// requestTechnology([NfcTech.Iso15693]) and sometimes doesn’t allow raw\n// transceive (depends on firmware)\n//\n// | Byte | Meaning |\n// | ------------- | ---------------------------------------------------- |\n// | `0x02` | Flags (high data rate) |\n// | `0x20` | Flags (addressed) |\n// | `0x22` | Flags (0x02 + 0x20 = 0x22 addressed + high data rate)|\n// | `0x20` | Command code: Read Single Block |\n// | `0x21` | Command code: Write Single Block |\n// | `UID[0..7]` | Tag UID in reverse order (optional if not addressed) |\n// | `blockNumber` | Which memory block to write |\n// | `data[...]` | The bytes to write (block size usually 4 or 8 bytes) |\n//\n// Each command is a byte array\n// [ FLAGS, COMMAND_CODE, [UID bytes reversed], PARAMS... ]\n//\n// Tag response:\n// The tag response has this structure:\n//\n// | Byte | Meaning |\n// | ---- | --------------------------------------------- |\n// | `0` | **Status** (0x00 = success) |\n// | `1` | **Info Flags** |\n// | … | Data fields, conditional based on those flags |\n//\n// Info Flags bitmask:\n// | Bit | Hex | Meaning |\n// | --- | ---- | ------------------------------------------------------------- |\n// | 0 | 0x01 | DSFID present |\n// | 1 | 0x02 | AFI present |\n// | 2 | 0x04 | VICC memory size info present (number of blocks + block size) |\n// | 3 | 0x08 | IC reference present |\n// | 4–7 | — | RFU (reserved) |\n\nexport const utils = {\n tech: Platform.OS === \"ios\" ? [NfcTech.Iso15693IOS] : NfcTech.NfcV,\n\n Flags: {\n HIGH_DATA_RATE: 0x02,\n ADDRESSED: 0x20,\n // If needed later: OPTION: 0x40 (not commonly used)\n },\n\n Commands: {\n READ_SINGLE_BLOCK: 0x20,\n WRITE_SINGLE_BLOCK: 0x21,\n GET_SYSTEM_INFO: 0x2b,\n },\n\n /**\n * Combine multiple flag bits into one byte.\n * Example: Flags.ADDRESSED | Flags.HIGH_DATA_RATE\n */\n flags(...bits: number[]): number {\n return bits.reduce((acc, bit) => acc | bit, 0);\n },\n\n /**\n * Convert tag.id hex string (MSB->LSB) into reversed byte array (LSB->MSB)\n * ISO15693 requires reversed UID for addressed commands.\n */\n reverseUid(tagIdHex: string): number[] {\n const bytes = [];\n for (let i = 0; i < tagIdHex.length; i += 2) {\n bytes.unshift(Number.parseInt(tagIdHex.substring(i, i + 2), 16));\n }\n return bytes;\n },\n\n /**\n * Build READ_SINGLE_BLOCK command.\n * FLAGS: addressed + high data rate by default.\n */\n buildReadBlock(uidReversed: number[], blockNumber: number): number[] {\n const flags = this.flags(this.Flags.ADDRESSED, this.Flags.HIGH_DATA_RATE);\n return [\n flags,\n this.Commands.READ_SINGLE_BLOCK,\n ...uidReversed,\n blockNumber,\n ];\n },\n\n /**\n * Build WRITE_SINGLE_BLOCK command.\n * Note: data must match the block size (usually 4 or 8 bytes).\n */\n buildWriteBlock(\n uidReversed: number[],\n blockNumber: number,\n data: Uint8Array,\n ): number[] {\n const flags = this.flags(this.Flags.ADDRESSED, this.Flags.HIGH_DATA_RATE);\n return [\n flags,\n this.Commands.WRITE_SINGLE_BLOCK,\n ...uidReversed,\n blockNumber,\n ...data,\n ];\n },\n\n /**\n * Build GET_SYSTEM_INFO command.\n */\n buildGetSystemInfo(uidReversed: number[]): number[] {\n return [this.Flags.HIGH_DATA_RATE, this.Commands.GET_SYSTEM_INFO];\n },\n\n /**\n * Parse a READ_SINGLE_BLOCK response.\n * Response format:\n * - byte[0] = status (0x00 = success)\n * - byte[1..] = block payload bytes\n */\n parseReadResponse(resp: number[]): Uint8Array {\n if (!resp || resp.length === 0) {\n throw new Error(\"Empty NFC-V response\");\n }\n const status = resp[0];\n if (status === undefined) {\n throw new Error(\"Invalid NFC-V response: missing status byte\");\n }\n if (status !== 0x00) {\n throw new Error(`Read failed. Status: 0x${status.toString(16)}`);\n }\n return new Uint8Array(resp.slice(1));\n },\n\n /**\n * Parse WRITE_SINGLE_BLOCK response.\n * Successful write has resp[0] === 0x00.\n */\n parseWriteResponse(resp: number[]): void {\n if (!resp || resp.length === 0) {\n throw new Error(\"Empty NFC-V response\");\n }\n const status = resp[0];\n if (status === undefined) {\n throw new Error(\"Invalid NFC-V response: missing status byte\");\n }\n if (status !== 0x00) {\n throw new Error(`Write failed. Status: 0x${status.toString(16)}`);\n }\n },\n\n /**\n * Parse GET_SYSTEM_INFO response.\n * Returns: UID, DSFID, AFI, numberOfBlocks, blockSize, manufacturer\n */\n parseSystemInfo(resp: number[]) {\n if (!resp || resp.length < 2) {\n throw new Error(\"Invalid System Info response\");\n }\n const status = resp[0];\n if (status === undefined || status !== 0x00) {\n throw new Error(\"Invalid System Info response\");\n }\n const flagsByte = resp[1];\n if (flagsByte === undefined) {\n throw new Error(\"Invalid System Info response: missing flags byte\");\n }\n\n const infoFlags = flagsByte & 0x0f;\n let offset = 2;\n\n const result: any = {};\n\n // UID (always present – next 8 bytes)\n if (resp.length >= offset + 8) {\n const uidBytes = resp.slice(offset, offset + 8);\n result.uid = uidBytes\n .slice()\n .reverse()\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\")\n .toUpperCase();\n offset += 8;\n }\n\n // DSFID\n if (infoFlags & 0x01 && resp.length > offset) {\n result.dsfid = resp[offset++];\n }\n\n // AFI\n if (infoFlags & 0x02 && resp.length > offset) {\n result.afi = resp[offset++];\n }\n\n // Memory size info\n if (infoFlags & 0x04 && resp.length >= offset + 2) {\n const numBlocks = resp[offset++];\n const blkSize = resp[offset++];\n if (numBlocks !== undefined) {\n result.numberOfBlocks = numBlocks + 1;\n }\n if (blkSize !== undefined) {\n result.blockSize = blkSize + 1;\n }\n }\n\n // IC Reference\n if (infoFlags & 0x08 && resp.length > offset) {\n result.icReference = resp[offset++];\n }\n\n if (!result.blockSize) result.blockSize = 4; // default for EM Micro\n\n result.manufacturer = this.detectManufacturer(result.uid ?? \"\");\n\n return result;\n },\n\n /** Identify common manufacturers based on UID prefix */\n detectManufacturer(uid: string): string {\n if (\n uid.startsWith(\"E004\") ||\n uid.startsWith(\"E006\") ||\n uid.startsWith(\"E016\")\n )\n return \"EM Microelectronic\";\n if (uid.startsWith(\"E002\")) return \"STMicroelectronics\";\n if (uid.startsWith(\"E007\")) return \"Texas Instruments\";\n if (uid.startsWith(\"E010\")) return \"NXP\";\n return \"Unknown\";\n },\n} as const;\n","export { operations } from \"./operations\";\nexport { utils } from \"./utils\";\n","import NfcManager, {\n Ndef,\n type NdefRecord,\n NfcTech,\n} from \"react-native-nfc-manager\";\n\nimport { nfcService } from \"../service\";\n\nexport const operations = {\n async writeNdef(records: NdefRecord[]) {\n // Use NFC-A/Type 2 as fallback (often required on Android)\n await nfcService.withTechnology([NfcTech.Ndef, NfcTech.NfcA], async () => {\n const bytes = Ndef.encodeMessage(records);\n await NfcManager.ndefHandler.writeNdefMessage(bytes);\n });\n },\n\n writeTextNdef(text: string) {\n const record = Ndef.textRecord(text);\n return this.writeNdef([record]);\n },\n\n writeUriNdef(uri: string) {\n const record = Ndef.uriRecord(uri);\n return this.writeNdef([record]);\n },\n};\n","export const utils = {};\n","import { operations as aOps, utils as aUtils } from \"./a\";\nimport { operations as ndefOps, utils as ndefUtils } from \"./ndef\";\nimport { nfcService } from \"./service\";\nimport { operations as vOps, utils as vUtils } from \"./v\";\n/**\n * NFC root namespace providing access to:\n * - NfcService\n * - ISO15693 NFC-V ops\n * - NFC-A ops\n * - NDEF operations\n */\nexport const nfc = {\n service: nfcService,\n\n /** ISO15693 protocol helpers and high-level operations */\n v: {\n ...vOps, // NfcVOperations, nfcV\n utils: vUtils,\n },\n\n /** NFC-A / Type 2 helpers and operations */\n a: {\n ...aOps,\n utils: aUtils,\n },\n\n /** NDEF read/write utilities and operations */\n ndef: {\n ...ndefOps,\n utils: ndefUtils,\n },\n} as const;\n"],"mappings":"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","names":["import_react_native_nfc_manager","NfcManager","NfcManager","operations","utils","import_react_native_nfc_manager","import_react_native_nfc_manager","import_react_native","import_react_native_nfc_manager","utils","utils","NfcManager","operations","utils","NfcManager","operations","utils","import_react_native_nfc_manager","operations","NfcManager","utils","operations","utils"]}
package/dist/index.mjs CHANGED
@@ -4,18 +4,34 @@ var __export = (target, all) => {
4
4
  __defProp(target, name, { get: all[name], enumerable: true });
5
5
  };
6
6
 
7
- // src/services/nfc/service.ts
7
+ // src/nfc/a/index.ts
8
+ var a_exports = {};
9
+ __export(a_exports, {
10
+ operations: () => operations,
11
+ utils: () => utils
12
+ });
13
+
14
+ // src/nfc/a/operations.ts
15
+ import NfcManager2, { NfcTech } from "react-native-nfc-manager";
16
+
17
+ // src/nfc/service.ts
8
18
  import { Platform } from "react-native";
9
19
  import NfcManager, {
10
20
  NfcEvents
11
21
  } from "react-native-nfc-manager";
12
22
  var NfcService = class {
23
+ // needed for iOS restart
13
24
  constructor() {
14
25
  this.state = { mode: "idle", tag: null };
15
26
  this.listeners = /* @__PURE__ */ new Set();
27
+ this.isProcessingTag = false;
28
+ this.currentCooldownMs = 1500;
29
+ this.lastUsedReaderFlags = null;
16
30
  NfcManager.start();
17
31
  }
18
- // --- internal state mgmt ---
32
+ // -----------------------------
33
+ // Internal state management
34
+ // -----------------------------
19
35
  setState(partial) {
20
36
  this.state = { ...this.state, ...partial };
21
37
  for (const listener of this.listeners) listener(this.state);
@@ -30,17 +46,45 @@ var NfcService = class {
30
46
  this.listeners.delete(fn);
31
47
  };
32
48
  }
33
- // --- Reader lifecycle ---
34
- async startReader(readerModeFlags, onTag) {
49
+ // -----------------------------
50
+ // START READER
51
+ // -----------------------------
52
+ async startReader(readerModeFlags, onTag, options) {
53
+ var _a;
35
54
  if (this.state.mode !== "idle") {
36
55
  console.warn(`[NFC] Cannot start reader while ${this.state.mode}`);
37
56
  return;
38
57
  }
39
- this.setState({ mode: "starting" });
40
- NfcManager.setEventListener(NfcEvents.DiscoverTag, (tag) => {
41
- this.setState({ tag });
42
- onTag == null ? void 0 : onTag(tag);
43
- });
58
+ this.currentOnTag = onTag;
59
+ this.currentCooldownMs = (_a = options == null ? void 0 : options.cooldownMs) != null ? _a : 1500;
60
+ this.lastUsedReaderFlags = readerModeFlags;
61
+ this.isProcessingTag = false;
62
+ this.setState({ mode: "starting", tag: null });
63
+ NfcManager.setEventListener(
64
+ NfcEvents.DiscoverTag,
65
+ async (tag) => {
66
+ if (!tag) return;
67
+ if (this.isProcessingTag) return;
68
+ this.isProcessingTag = true;
69
+ this.setState({ tag, mode: "active" });
70
+ try {
71
+ if (this.currentOnTag) {
72
+ await this.currentOnTag(tag);
73
+ }
74
+ } catch (err) {
75
+ console.warn("[NFC] onTag handler error:", err);
76
+ } finally {
77
+ const cooldown = this.currentCooldownMs;
78
+ setTimeout(async () => {
79
+ this.isProcessingTag = false;
80
+ this.setState({ tag: null, mode: "active" });
81
+ if (Platform.OS === "ios") {
82
+ await this._restartIosReader();
83
+ }
84
+ }, cooldown);
85
+ }
86
+ }
87
+ );
44
88
  try {
45
89
  await NfcManager.registerTagEvent({
46
90
  isReaderModeEnabled: true,
@@ -51,23 +95,53 @@ var NfcService = class {
51
95
  }
52
96
  } catch (err) {
53
97
  console.warn("[NFC] startReader error:", err);
54
- this.setState({ mode: "idle" });
98
+ this._resetReaderState();
55
99
  }
56
100
  }
101
+ // -----------------------------
102
+ // STOP READER
103
+ // -----------------------------
57
104
  async stopReader() {
58
105
  if (["idle", "stopping"].includes(this.state.mode)) return;
59
106
  this.setState({ mode: "stopping" });
60
107
  try {
61
108
  await NfcManager.unregisterTagEvent();
62
- } catch {
109
+ } catch (err) {
110
+ console.warn("[NFC] unregisterTagEvent error:", err);
111
+ }
112
+ this._resetReaderState();
113
+ }
114
+ _resetReaderState() {
115
+ this.setState({ mode: "idle", tag: null });
116
+ this.currentOnTag = void 0;
117
+ this.isProcessingTag = false;
118
+ }
119
+ // -----------------------------
120
+ // iOS RESTART
121
+ // -----------------------------
122
+ async _restartIosReader() {
123
+ if (Platform.OS !== "ios") return;
124
+ if (this.lastUsedReaderFlags == null) return;
125
+ try {
126
+ await NfcManager.unregisterTagEvent();
127
+ await NfcManager.registerTagEvent({
128
+ isReaderModeEnabled: true,
129
+ readerModeFlags: this.lastUsedReaderFlags
130
+ });
131
+ this.setState({ mode: "active" });
132
+ } catch (err) {
133
+ console.warn("[NFC] iOS restart error:", err);
134
+ this._resetReaderState();
63
135
  }
64
- this.setState({ mode: "idle" });
65
136
  }
137
+ // -----------------------------
138
+ // Technology sessions (NDEF, NfcV, etc.)
139
+ // -----------------------------
66
140
  async withTechnology(tech, handler) {
67
141
  if (this.state.mode === "technology") {
68
- throw new Error(`[NFC] Technology is already in use!`);
142
+ throw new Error("[NFC] Technology is already in use!");
69
143
  }
70
- if (this.state.mode === "starting" || this.state.mode === "active" || this.state.mode === "stopping") {
144
+ if (["starting", "active", "stopping"].includes(this.state.mode)) {
71
145
  await this.stopReader();
72
146
  }
73
147
  if (this.state.mode !== "idle") {
@@ -75,15 +149,15 @@ var NfcService = class {
75
149
  `[NFC] Cannot start technology session in mode ${this.state.mode}`
76
150
  );
77
151
  }
78
- this.setState({ mode: "technology" });
152
+ this.setState({ mode: "technology", tag: null });
79
153
  try {
80
154
  await NfcManager.requestTechnology(tech, {
81
155
  alertMessage: "Hold near NFC tag"
82
- // iOS
83
156
  });
84
157
  const result = await handler();
85
- if (Platform.OS === "ios")
158
+ if (Platform.OS === "ios") {
86
159
  await NfcManager.setAlertMessageIOS("Success!");
160
+ }
87
161
  return result;
88
162
  } catch (err) {
89
163
  const message = typeof err === "string" ? err : (err == null ? void 0 : err.message) || "Unknown NFC error";
@@ -91,85 +165,44 @@ var NfcService = class {
91
165
  } finally {
92
166
  try {
93
167
  await NfcManager.cancelTechnologyRequest();
94
- } catch (cancelErr) {
95
- console.warn("[NFC] cancelTechnologyRequest failed:", cancelErr);
168
+ } catch {
96
169
  }
97
- this.setState({ mode: "idle" });
170
+ this.setState({ mode: "idle", tag: null });
98
171
  }
99
172
  }
100
173
  };
101
174
  var nfcService = new NfcService();
102
175
 
103
- // src/services/nfc/a/index.ts
104
- var a_exports = {};
105
- __export(a_exports, {
106
- operations: () => operations,
107
- utils: () => utils
108
- });
109
-
110
- // src/services/nfc/a/operations.ts
111
- import NfcManager2, { NfcTech as NfcTech2 } from "react-native-nfc-manager";
176
+ // src/nfc/a/operations.ts
112
177
  var operations = {
113
178
  async transceive(data) {
114
- return nfcService.withTechnology(NfcTech2.NfcA, async () => {
179
+ return nfcService.withTechnology(NfcTech.NfcA, async () => {
115
180
  return await NfcManager2.transceive(data);
116
181
  });
117
182
  }
118
183
  };
119
184
 
120
- // src/services/nfc/a/utils.ts
185
+ // src/nfc/a/utils.ts
121
186
  var utils = {};
122
187
 
123
- // src/services/nfc/ndef/index.ts
124
- var ndef_exports = {};
125
- __export(ndef_exports, {
126
- operations: () => operations2,
127
- utils: () => utils2
128
- });
129
-
130
- // src/services/nfc/ndef/operations.ts
131
- import NfcManager3, {
132
- Ndef,
133
- NfcTech as NfcTech3
134
- } from "react-native-nfc-manager";
135
- var operations2 = {
136
- async writeNdef(records) {
137
- await nfcService.withTechnology([NfcTech3.Ndef, NfcTech3.NfcA], async () => {
138
- const bytes = Ndef.encodeMessage(records);
139
- await NfcManager3.ndefHandler.writeNdefMessage(bytes);
140
- });
141
- },
142
- writeTextNdef(text) {
143
- const record = Ndef.textRecord(text);
144
- return this.writeNdef([record]);
145
- },
146
- writeUriNdef(uri) {
147
- const record = Ndef.uriRecord(uri);
148
- return this.writeNdef([record]);
149
- }
150
- };
151
-
152
- // src/services/nfc/ndef/utils.ts
153
- var utils2 = {};
154
-
155
- // src/services/nfc/v/index.ts
188
+ // src/nfc/v/index.ts
156
189
  var v_exports = {};
157
190
  __export(v_exports, {
158
- operations: () => operations3,
159
- utils: () => utils3
191
+ operations: () => operations2,
192
+ utils: () => utils2
160
193
  });
161
194
 
162
- // src/services/nfc/v/operations.ts
163
- import NfcManager5 from "react-native-nfc-manager";
164
-
165
- // src/services/nfc/v/internal.ts
195
+ // src/nfc/v/operations.ts
166
196
  import NfcManager4 from "react-native-nfc-manager";
167
197
 
168
- // src/services/nfc/v/utils.ts
198
+ // src/nfc/v/internal.ts
199
+ import NfcManager3 from "react-native-nfc-manager";
200
+
201
+ // src/nfc/v/utils.ts
169
202
  import { Platform as Platform2 } from "react-native";
170
- import { NfcTech as NfcTech4 } from "react-native-nfc-manager";
171
- var utils3 = {
172
- tech: Platform2.OS === "ios" ? [NfcTech4.Iso15693IOS] : NfcTech4.NfcV,
203
+ import { NfcTech as NfcTech2 } from "react-native-nfc-manager";
204
+ var utils2 = {
205
+ tech: Platform2.OS === "ios" ? [NfcTech2.Iso15693IOS] : NfcTech2.NfcV,
173
206
  Flags: {
174
207
  HIGH_DATA_RATE: 2,
175
208
  ADDRESSED: 32
@@ -194,7 +227,7 @@ var utils3 = {
194
227
  reverseUid(tagIdHex) {
195
228
  const bytes = [];
196
229
  for (let i = 0; i < tagIdHex.length; i += 2) {
197
- bytes.unshift(parseInt(tagIdHex.substring(i, i + 2), 16));
230
+ bytes.unshift(Number.parseInt(tagIdHex.substring(i, i + 2), 16));
198
231
  }
199
232
  return bytes;
200
233
  },
@@ -241,8 +274,12 @@ var utils3 = {
241
274
  if (!resp || resp.length === 0) {
242
275
  throw new Error("Empty NFC-V response");
243
276
  }
244
- if (resp[0] !== 0) {
245
- throw new Error(`Read failed. Status: 0x${resp[0].toString(16)}`);
277
+ const status = resp[0];
278
+ if (status === void 0) {
279
+ throw new Error("Invalid NFC-V response: missing status byte");
280
+ }
281
+ if (status !== 0) {
282
+ throw new Error(`Read failed. Status: 0x${status.toString(16)}`);
246
283
  }
247
284
  return new Uint8Array(resp.slice(1));
248
285
  },
@@ -254,8 +291,12 @@ var utils3 = {
254
291
  if (!resp || resp.length === 0) {
255
292
  throw new Error("Empty NFC-V response");
256
293
  }
257
- if (resp[0] !== 0) {
258
- throw new Error(`Write failed. Status: 0x${resp[0].toString(16)}`);
294
+ const status = resp[0];
295
+ if (status === void 0) {
296
+ throw new Error("Invalid NFC-V response: missing status byte");
297
+ }
298
+ if (status !== 0) {
299
+ throw new Error(`Write failed. Status: 0x${status.toString(16)}`);
259
300
  }
260
301
  },
261
302
  /**
@@ -264,10 +305,18 @@ var utils3 = {
264
305
  */
265
306
  parseSystemInfo(resp) {
266
307
  var _a;
267
- if (!resp || resp.length < 2 || resp[0] !== 0) {
308
+ if (!resp || resp.length < 2) {
268
309
  throw new Error("Invalid System Info response");
269
310
  }
270
- const infoFlags = resp[1] & 15;
311
+ const status = resp[0];
312
+ if (status === void 0 || status !== 0) {
313
+ throw new Error("Invalid System Info response");
314
+ }
315
+ const flagsByte = resp[1];
316
+ if (flagsByte === void 0) {
317
+ throw new Error("Invalid System Info response: missing flags byte");
318
+ }
319
+ const infoFlags = flagsByte & 15;
271
320
  let offset = 2;
272
321
  const result = {};
273
322
  if (resp.length >= offset + 8) {
@@ -282,8 +331,14 @@ var utils3 = {
282
331
  result.afi = resp[offset++];
283
332
  }
284
333
  if (infoFlags & 4 && resp.length >= offset + 2) {
285
- result.numberOfBlocks = resp[offset++] + 1;
286
- result.blockSize = resp[offset++] + 1;
334
+ const numBlocks = resp[offset++];
335
+ const blkSize = resp[offset++];
336
+ if (numBlocks !== void 0) {
337
+ result.numberOfBlocks = numBlocks + 1;
338
+ }
339
+ if (blkSize !== void 0) {
340
+ result.blockSize = blkSize + 1;
341
+ }
287
342
  }
288
343
  if (infoFlags & 8 && resp.length > offset) {
289
344
  result.icReference = resp[offset++];
@@ -303,31 +358,31 @@ var utils3 = {
303
358
  }
304
359
  };
305
360
 
306
- // src/services/nfc/v/internal.ts
361
+ // src/nfc/v/internal.ts
307
362
  async function readBlockRaw(tag, blockNumber) {
308
- const uid = utils3.reverseUid(tag.id);
309
- const cmd = utils3.buildReadBlock(uid, blockNumber);
310
- const resp = await NfcManager4.transceive(cmd);
311
- return utils3.parseReadResponse(resp);
363
+ const uid = utils2.reverseUid(tag.id);
364
+ const cmd = utils2.buildReadBlock(uid, blockNumber);
365
+ const resp = await NfcManager3.transceive(cmd);
366
+ return utils2.parseReadResponse(resp);
312
367
  }
313
368
  async function writeBlockRaw(tag, blockNumber, data) {
314
- const uid = utils3.reverseUid(tag.id);
315
- const cmd = utils3.buildWriteBlock(uid, blockNumber, data);
316
- const resp = await NfcManager4.transceive(cmd);
317
- return utils3.parseWriteResponse(resp);
369
+ const uid = utils2.reverseUid(tag.id);
370
+ const cmd = utils2.buildWriteBlock(uid, blockNumber, data);
371
+ const resp = await NfcManager3.transceive(cmd);
372
+ return utils2.parseWriteResponse(resp);
318
373
  }
319
374
  async function getSystemInfoRaw(tag) {
320
- const uid = utils3.reverseUid(tag.id);
321
- const cmd = utils3.buildGetSystemInfo(uid);
322
- const resp = await NfcManager4.transceive(cmd);
323
- return utils3.parseSystemInfo(resp);
375
+ const uid = utils2.reverseUid(tag.id);
376
+ const cmd = utils2.buildGetSystemInfo(uid);
377
+ const resp = await NfcManager3.transceive(cmd);
378
+ return utils2.parseSystemInfo(resp);
324
379
  }
325
380
 
326
- // src/services/nfc/v/operations.ts
327
- var operations3 = {
381
+ // src/nfc/v/operations.ts
382
+ var operations2 = {
328
383
  async withVTag(handler) {
329
- return nfcService.withTechnology(utils3.tech, async () => {
330
- const tag = await NfcManager5.getTag();
384
+ return nfcService.withTechnology(utils2.tech, async () => {
385
+ const tag = await NfcManager4.getTag();
331
386
  if (!(tag == null ? void 0 : tag.id)) throw new Error("No NFC-V tag detected");
332
387
  return handler(tag);
333
388
  });
@@ -343,14 +398,46 @@ var operations3 = {
343
398
  }
344
399
  };
345
400
 
346
- // src/services/nfc/namespace.ts
401
+ // src/nfc/ndef/index.ts
402
+ var ndef_exports = {};
403
+ __export(ndef_exports, {
404
+ operations: () => operations3,
405
+ utils: () => utils3
406
+ });
407
+
408
+ // src/nfc/ndef/operations.ts
409
+ import NfcManager5, {
410
+ Ndef,
411
+ NfcTech as NfcTech3
412
+ } from "react-native-nfc-manager";
413
+ var operations3 = {
414
+ async writeNdef(records) {
415
+ await nfcService.withTechnology([NfcTech3.Ndef, NfcTech3.NfcA], async () => {
416
+ const bytes = Ndef.encodeMessage(records);
417
+ await NfcManager5.ndefHandler.writeNdefMessage(bytes);
418
+ });
419
+ },
420
+ writeTextNdef(text) {
421
+ const record = Ndef.textRecord(text);
422
+ return this.writeNdef([record]);
423
+ },
424
+ writeUriNdef(uri) {
425
+ const record = Ndef.uriRecord(uri);
426
+ return this.writeNdef([record]);
427
+ }
428
+ };
429
+
430
+ // src/nfc/ndef/utils.ts
431
+ var utils3 = {};
432
+
433
+ // src/nfc/namespace.ts
347
434
  var nfc = {
348
435
  service: nfcService,
349
436
  /** ISO15693 protocol helpers and high-level operations */
350
437
  v: {
351
- ...operations3,
438
+ ...operations2,
352
439
  // NfcVOperations, nfcV
353
- utils: utils3
440
+ utils: utils2
354
441
  },
355
442
  /** NFC-A / Type 2 helpers and operations */
356
443
  a: {
@@ -359,14 +446,14 @@ var nfc = {
359
446
  },
360
447
  /** NDEF read/write utilities and operations */
361
448
  ndef: {
362
- ...operations2,
363
- utils: utils2
449
+ ...operations3,
450
+ utils: utils3
364
451
  }
365
452
  };
366
453
  export {
367
- ndef_exports as ndef,
368
454
  nfc,
369
455
  a_exports as nfcA,
456
+ ndef_exports as nfcNdef,
370
457
  nfcService,
371
458
  v_exports as nfcV
372
459
  };