@spencerls/react-native-nfc 1.0.0 → 1.0.2

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.mjs CHANGED
@@ -1,30 +1,28 @@
1
- // src/services/nfc/NfcService.ts
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // src/services/nfc/service.ts
2
8
  import { Platform } from "react-native";
3
9
  import NfcManager, {
4
- Ndef,
5
- NfcEvents,
6
- NfcTech
10
+ NfcEvents
7
11
  } from "react-native-nfc-manager";
8
12
  var NfcService = class {
9
13
  constructor() {
10
- this.state = "idle";
11
- this.lastTag = null;
14
+ this.state = { mode: "idle", tag: null };
12
15
  this.listeners = /* @__PURE__ */ new Set();
13
16
  NfcManager.start();
14
17
  }
15
18
  // --- internal state mgmt ---
16
- setState(next) {
17
- if (this.state !== next) {
18
- this.state = next;
19
- for (const listener of this.listeners) listener(next);
20
- }
19
+ setState(partial) {
20
+ this.state = { ...this.state, ...partial };
21
+ for (const listener of this.listeners) listener(this.state);
21
22
  }
22
23
  getState() {
23
24
  return this.state;
24
25
  }
25
- getLastTag() {
26
- return this.lastTag;
27
- }
28
26
  subscribe(fn) {
29
27
  this.listeners.add(fn);
30
28
  fn(this.state);
@@ -34,13 +32,13 @@ var NfcService = class {
34
32
  }
35
33
  // --- Reader lifecycle ---
36
34
  async startReader(readerModeFlags, onTag) {
37
- if (this.state !== "idle") {
38
- console.warn(`[NFC] Cannot start reader while ${this.state}`);
35
+ if (this.state.mode !== "idle") {
36
+ console.warn(`[NFC] Cannot start reader while ${this.state.mode}`);
39
37
  return;
40
38
  }
41
- this.setState("starting");
39
+ this.setState({ mode: "starting" });
42
40
  NfcManager.setEventListener(NfcEvents.DiscoverTag, (tag) => {
43
- this.lastTag = tag;
41
+ this.setState({ tag });
44
42
  onTag == null ? void 0 : onTag(tag);
45
43
  });
46
44
  try {
@@ -48,210 +46,333 @@ var NfcService = class {
48
46
  isReaderModeEnabled: true,
49
47
  readerModeFlags
50
48
  });
51
- if (this.state === "starting") {
52
- this.setState("active");
49
+ if (this.state.mode === "starting") {
50
+ this.setState({ mode: "active" });
53
51
  }
54
52
  } catch (err) {
55
53
  console.warn("[NFC] startReader error:", err);
56
- this.setState("idle");
54
+ this.setState({ mode: "idle" });
57
55
  }
58
56
  }
59
57
  async stopReader() {
60
- if (["idle", "stopping"].includes(this.state)) return;
61
- this.setState("stopping");
58
+ if (["idle", "stopping"].includes(this.state.mode)) return;
59
+ this.setState({ mode: "stopping" });
62
60
  try {
63
61
  await NfcManager.unregisterTagEvent();
64
62
  } catch {
65
63
  }
66
- this.setState("idle");
64
+ this.setState({ mode: "idle" });
67
65
  }
68
- // --- Writer ---
69
- async writeNdef(records) {
70
- if (this.state !== "idle") {
71
- throw new Error(`Cannot write while reader is ${this.state}`);
66
+ async withTechnology(tech, handler) {
67
+ if (this.state.mode === "technology") {
68
+ throw new Error(`[NFC] Technology is already in use!`);
72
69
  }
73
- this.setState("writing");
74
- let res = {
75
- success: false,
76
- error: void 0
77
- };
70
+ if (this.state.mode === "starting" || this.state.mode === "active" || this.state.mode === "stopping") {
71
+ await this.stopReader();
72
+ }
73
+ if (this.state.mode !== "idle") {
74
+ throw new Error(
75
+ `[NFC] Cannot start technology session in mode ${this.state.mode}`
76
+ );
77
+ }
78
+ this.setState({ mode: "technology" });
78
79
  try {
79
- await NfcManager.requestTechnology(NfcTech.Ndef, {
80
- alertMessage: "Hold near NFC tag to write"
80
+ await NfcManager.requestTechnology(tech, {
81
+ alertMessage: "Hold near NFC tag"
82
+ // iOS
81
83
  });
82
- const bytes = Ndef.encodeMessage(records);
83
- await NfcManager.ndefHandler.writeNdefMessage(bytes);
84
+ const result = await handler();
84
85
  if (Platform.OS === "ios")
85
- NfcManager.setAlertMessageIOS("Write successful");
86
+ await NfcManager.setAlertMessageIOS("Success!");
87
+ return result;
86
88
  } catch (err) {
87
- console.warn("[NFC] writeNdef error:", err);
88
- res.success = false;
89
- res.error = err;
89
+ const message = typeof err === "string" ? err : (err == null ? void 0 : err.message) || "Unknown NFC error";
90
+ throw new Error(`[NFC] withTechnology error: ${message}`);
90
91
  } finally {
91
92
  try {
92
93
  await NfcManager.cancelTechnologyRequest();
93
- } catch {
94
- } finally {
95
- this.setState("idle");
96
- return res;
94
+ } catch (cancelErr) {
95
+ console.warn("[NFC] cancelTechnologyRequest failed:", cancelErr);
97
96
  }
97
+ this.setState({ mode: "idle" });
98
98
  }
99
99
  }
100
100
  };
101
101
  var nfcService = new NfcService();
102
102
 
103
- // src/services/nfc/NfcUtils.ts
104
- import { Ndef as Ndef2 } from "react-native-nfc-manager";
105
- var toU8 = (v) => {
106
- if (v instanceof Uint8Array) return v;
107
- if (Array.isArray(v)) return Uint8Array.from(v);
108
- return new Uint8Array(v);
109
- };
110
- var toAscii = (u8) => String.fromCharCode(...u8);
111
- function decodeRecord(record) {
112
- const { tnf } = record;
113
- let typeStr;
114
- if (typeof record.type === "string") {
115
- typeStr = record.type;
116
- } else {
117
- typeStr = toAscii(toU8(record.type));
118
- }
119
- const payloadU8 = toU8(record.payload);
120
- if (tnf === Ndef2.TNF_WELL_KNOWN && typeStr === "T") {
121
- const status = payloadU8[0];
122
- const langLen = status & 63;
123
- const lang = toAscii(payloadU8.subarray(1, 1 + langLen));
124
- const textBytes = payloadU8.subarray(1 + langLen);
125
- const text = new TextDecoder().decode(textBytes);
126
- return { kind: "text", text, lang };
103
+ // src/services/nfc/a/index.ts
104
+ var a_exports = {};
105
+ __export(a_exports, {
106
+ operations: () => operations,
107
+ utils: () => utils_exports
108
+ });
109
+
110
+ // src/services/nfc/a/operations.ts
111
+ import NfcManager2, { NfcTech as NfcTech2 } from "react-native-nfc-manager";
112
+ var operations = {
113
+ async transceive(data) {
114
+ return nfcService.withTechnology(NfcTech2.NfcA, async () => {
115
+ return await NfcManager2.transceive(data);
116
+ });
127
117
  }
128
- if (tnf === Ndef2.TNF_WELL_KNOWN && typeStr === "U") {
129
- const uri = Ndef2.uri.decodePayload(payloadU8);
130
- return { kind: "uri", uri };
118
+ };
119
+
120
+ // src/services/nfc/a/utils.ts
121
+ var utils_exports = {};
122
+ __export(utils_exports, {
123
+ NfcAUtils: () => NfcAUtils
124
+ });
125
+ var NfcAUtils = {};
126
+
127
+ // src/services/nfc/ndef/index.ts
128
+ var ndef_exports = {};
129
+ __export(ndef_exports, {
130
+ operations: () => operations2,
131
+ utils: () => utils_exports2
132
+ });
133
+
134
+ // src/services/nfc/ndef/operations.ts
135
+ import NfcManager3, {
136
+ Ndef,
137
+ NfcTech as NfcTech3
138
+ } from "react-native-nfc-manager";
139
+ var operations2 = {
140
+ async writeNdef(records) {
141
+ await nfcService.withTechnology([NfcTech3.Ndef, NfcTech3.NfcA], async () => {
142
+ const bytes = Ndef.encodeMessage(records);
143
+ await NfcManager3.ndefHandler.writeNdefMessage(bytes);
144
+ });
145
+ },
146
+ writeTextNdef(text) {
147
+ const record = Ndef.textRecord(text);
148
+ return this.writeNdef([record]);
149
+ },
150
+ writeUriNdef(uri) {
151
+ const record = Ndef.uriRecord(uri);
152
+ return this.writeNdef([record]);
131
153
  }
132
- if (tnf === Ndef2.TNF_MIME_MEDIA) {
133
- let tryDecodeAsText2 = function(u8) {
134
- try {
135
- return new TextDecoder().decode(u8);
136
- } catch {
137
- return null;
138
- }
139
- };
140
- var tryDecodeAsText = tryDecodeAsText2;
141
- if (typeStr === "application/json") {
142
- return {
143
- kind: "mime",
144
- mimeType: typeStr,
145
- data: JSON.parse(new TextDecoder().decode(payloadU8))
146
- };
154
+ };
155
+
156
+ // src/services/nfc/ndef/utils.ts
157
+ var utils_exports2 = {};
158
+ __export(utils_exports2, {
159
+ NdefUtils: () => NdefUtils
160
+ });
161
+ var NdefUtils = {};
162
+
163
+ // src/services/nfc/v/index.ts
164
+ var v_exports = {};
165
+ __export(v_exports, {
166
+ operations: () => operations3,
167
+ utils: () => utils_exports3
168
+ });
169
+
170
+ // src/services/nfc/v/operations.ts
171
+ import NfcManager4 from "react-native-nfc-manager";
172
+
173
+ // src/services/nfc/v/utils.ts
174
+ var utils_exports3 = {};
175
+ __export(utils_exports3, {
176
+ NfcVUtils: () => NfcVUtils
177
+ });
178
+ import { Platform as Platform2 } from "react-native";
179
+ import { NfcTech as NfcTech4 } from "react-native-nfc-manager";
180
+ var NfcVUtils = {
181
+ tech: Platform2.OS === "ios" ? [NfcTech4.Iso15693IOS] : [NfcTech4.NfcV],
182
+ Flags: {
183
+ HIGH_DATA_RATE: 2,
184
+ ADDRESSED: 32
185
+ // If needed later: OPTION: 0x40 (not commonly used)
186
+ },
187
+ Commands: {
188
+ READ_SINGLE_BLOCK: 32,
189
+ WRITE_SINGLE_BLOCK: 33,
190
+ GET_SYSTEM_INFO: 43
191
+ },
192
+ /**
193
+ * Combine multiple flag bits into one byte.
194
+ * Example: Flags.ADDRESSED | Flags.HIGH_DATA_RATE
195
+ */
196
+ flags(...bits) {
197
+ return bits.reduce((acc, bit) => acc | bit, 0);
198
+ },
199
+ /**
200
+ * Convert tag.id hex string (MSB->LSB) into reversed byte array (LSB->MSB)
201
+ * ISO15693 requires reversed UID for addressed commands.
202
+ */
203
+ reverseUid(tagIdHex) {
204
+ const bytes = [];
205
+ for (let i = 0; i < tagIdHex.length; i += 2) {
206
+ bytes.unshift(parseInt(tagIdHex.substring(i, i + 2), 16));
147
207
  }
148
- return {
149
- kind: "mime",
150
- mimeType: typeStr,
151
- data: payloadU8,
152
- text: typeStr.startsWith("text/") ? tryDecodeAsText2(payloadU8) : null
153
- };
154
- }
155
- if (tnf === Ndef2.TNF_ABSOLUTE_URI) {
156
- return {
157
- kind: "abs-uri",
158
- uri: typeStr,
159
- data: payloadU8
160
- };
161
- }
162
- if (tnf === Ndef2.TNF_EXTERNAL_TYPE) {
163
- return {
164
- kind: "external",
165
- type: typeStr,
166
- data: payloadU8
167
- };
168
- }
169
- if (tnf === Ndef2.TNF_UNKNOWN) {
170
- return {
171
- kind: "unknown",
172
- type: typeStr,
173
- data: payloadU8
174
- };
175
- }
176
- return {
177
- kind: "unknown",
178
- tnf,
179
- type: typeStr,
180
- payload: payloadU8
181
- };
182
- }
183
- function decodeJson(record) {
184
- if (record.tnf !== Ndef2.TNF_MIME_MEDIA) return null;
185
- const typeStr = typeof record.type === "string" ? record.type : toAscii(toU8(record.type));
186
- if (typeStr !== "application/json") return null;
187
- const payloadU8 = toU8(record.payload);
188
- const jsonText = new TextDecoder().decode(payloadU8);
189
- try {
190
- return JSON.parse(jsonText);
191
- } catch (err) {
192
- console.warn("Invalid JSON in NDEF:", err);
193
- return null;
208
+ return bytes;
209
+ },
210
+ /**
211
+ * Build READ_SINGLE_BLOCK command.
212
+ * FLAGS: addressed + high data rate by default.
213
+ */
214
+ buildReadBlock(uidReversed, blockNumber) {
215
+ const flags = this.flags(this.Flags.ADDRESSED, this.Flags.HIGH_DATA_RATE);
216
+ return [
217
+ flags,
218
+ this.Commands.READ_SINGLE_BLOCK,
219
+ ...uidReversed,
220
+ blockNumber
221
+ ];
222
+ },
223
+ /**
224
+ * Build WRITE_SINGLE_BLOCK command.
225
+ * Note: data must match the block size (usually 4 or 8 bytes).
226
+ */
227
+ buildWriteBlock(uidReversed, blockNumber, data) {
228
+ const flags = this.flags(this.Flags.ADDRESSED, this.Flags.HIGH_DATA_RATE);
229
+ return [
230
+ flags,
231
+ this.Commands.WRITE_SINGLE_BLOCK,
232
+ ...uidReversed,
233
+ blockNumber,
234
+ ...data
235
+ ];
236
+ },
237
+ /**
238
+ * Build GET_SYSTEM_INFO command.
239
+ */
240
+ buildGetSystemInfo(uidReversed) {
241
+ const flags = this.flags(this.Flags.ADDRESSED, this.Flags.HIGH_DATA_RATE);
242
+ return [flags, this.Commands.GET_SYSTEM_INFO, ...uidReversed];
243
+ },
244
+ /**
245
+ * Parse a READ_SINGLE_BLOCK response.
246
+ * Response format:
247
+ * - byte[0] = status (0x00 = success)
248
+ * - byte[1..] = block payload bytes
249
+ */
250
+ parseReadResponse(resp) {
251
+ if (!resp || resp.length === 0) {
252
+ throw new Error("Empty NFC-V response");
253
+ }
254
+ if (resp[0] !== 0) {
255
+ throw new Error(`Read failed. Status: 0x${resp[0].toString(16)}`);
256
+ }
257
+ return new Uint8Array(resp.slice(1));
258
+ },
259
+ /**
260
+ * Parse WRITE_SINGLE_BLOCK response.
261
+ * Successful write has resp[0] === 0x00.
262
+ */
263
+ parseWriteResponse(resp) {
264
+ if (!resp || resp.length === 0) {
265
+ throw new Error("Empty NFC-V response");
266
+ }
267
+ if (resp[0] !== 0) {
268
+ throw new Error(`Write failed. Status: 0x${resp[0].toString(16)}`);
269
+ }
270
+ },
271
+ /**
272
+ * Parse GET_SYSTEM_INFO response.
273
+ * Returns: UID, DSFID, AFI, numberOfBlocks, blockSize, manufacturer
274
+ */
275
+ parseSystemInfo(resp) {
276
+ var _a;
277
+ if (!resp || resp.length < 2 || resp[0] !== 0) {
278
+ throw new Error("Invalid System Info response");
279
+ }
280
+ const infoFlags = resp[1] & 15;
281
+ let offset = 2;
282
+ const result = {};
283
+ if (resp.length >= offset + 8) {
284
+ const uidBytes = resp.slice(offset, offset + 8);
285
+ result.uid = uidBytes.slice().reverse().map((b) => b.toString(16).padStart(2, "0")).join("").toUpperCase();
286
+ offset += 8;
287
+ }
288
+ if (infoFlags & 1 && resp.length > offset) {
289
+ result.dsfid = resp[offset++];
290
+ }
291
+ if (infoFlags & 2 && resp.length > offset) {
292
+ result.afi = resp[offset++];
293
+ }
294
+ if (infoFlags & 4 && resp.length >= offset + 2) {
295
+ result.numberOfBlocks = resp[offset++] + 1;
296
+ result.blockSize = resp[offset++] + 1;
297
+ }
298
+ if (infoFlags & 8 && resp.length > offset) {
299
+ result.icReference = resp[offset++];
300
+ }
301
+ if (!result.blockSize) result.blockSize = 4;
302
+ result.manufacturer = this.detectManufacturer((_a = result.uid) != null ? _a : "");
303
+ return result;
304
+ },
305
+ /** Identify common manufacturers based on UID prefix */
306
+ detectManufacturer(uid) {
307
+ if (uid.startsWith("E004") || uid.startsWith("E006"))
308
+ return "EM Microelectronic";
309
+ if (uid.startsWith("E002")) return "STMicroelectronics";
310
+ if (uid.startsWith("E007")) return "Texas Instruments";
311
+ if (uid.startsWith("E010")) return "NXP";
312
+ return "Unknown";
194
313
  }
195
- }
196
- var encodeText = (text, lang = "en") => Ndef2.textRecord(text, lang);
197
- var encodeUri = (uri) => Ndef2.uriRecord(uri);
198
- function encodeJson(obj) {
199
- const json = JSON.stringify(obj);
200
- const payload = new TextEncoder().encode(json);
201
- const typeArray = Array.from(new TextEncoder().encode("application/json"));
202
- return {
203
- tnf: Ndef2.TNF_MIME_MEDIA,
204
- type: typeArray,
205
- // MUST be a number[] of ASCII bytes
206
- id: [],
207
- payload
208
- };
209
- }
210
- function encodeMime(mimeType, data) {
211
- const typeBytes = Array.from(new TextEncoder().encode(mimeType));
212
- return {
213
- tnf: Ndef2.TNF_MIME_MEDIA,
214
- type: typeBytes,
215
- id: [],
216
- payload: data
217
- };
218
- }
219
- function willFit(tag, records) {
220
- if (tag.maxSize === void 0) return null;
221
- const totalSize = Ndef2.encodeMessage(records).length;
222
- return totalSize <= tag.maxSize;
223
- }
224
- function spaceLeft(tag, records) {
225
- if (tag.maxSize === void 0) return null;
226
- const totalSize = Ndef2.encodeMessage(records).length;
227
- return tag.maxSize - totalSize;
228
- }
229
- var NfcUtils = {
230
- Ndef: {
231
- decodeRecord,
232
- decodeJson,
233
- encodeText,
234
- encodeUri,
235
- encodeJson,
236
- encodeMime,
237
- willFit,
238
- spaceLeft
314
+ };
315
+
316
+ // src/services/nfc/v/operations.ts
317
+ var operations3 = {
318
+ async withVTag(handler) {
319
+ return nfcService.withTechnology(NfcVUtils.tech, async () => {
320
+ const tag = await NfcManager4.getTag();
321
+ if (!(tag == null ? void 0 : tag.id)) throw new Error("No NFC-V tag detected");
322
+ return handler(tag);
323
+ });
324
+ },
325
+ async writeBlockNfcV(blockNumber, data) {
326
+ return this.withVTag(async (tag) => {
327
+ const uid = NfcVUtils.reverseUid(tag.id);
328
+ const cmd = NfcVUtils.buildWriteBlock(uid, blockNumber, data);
329
+ const resp = await NfcManager4.transceive(cmd);
330
+ NfcVUtils.parseWriteResponse(resp);
331
+ });
332
+ },
333
+ async readBlockNfcV(blockNumber) {
334
+ return this.withVTag(async (tag) => {
335
+ const uid = NfcVUtils.reverseUid(tag.id);
336
+ const cmd = NfcVUtils.buildReadBlock(uid, blockNumber);
337
+ const resp = await NfcManager4.transceive(cmd);
338
+ return NfcVUtils.parseReadResponse(resp);
339
+ });
340
+ },
341
+ async getSystemInfoNfcV() {
342
+ return this.withVTag(async (tag) => {
343
+ const uid = NfcVUtils.reverseUid(tag.id);
344
+ const cmd = NfcVUtils.buildGetSystemInfo(uid);
345
+ const resp = await NfcManager4.transceive(cmd);
346
+ return NfcVUtils.parseSystemInfo(resp);
347
+ });
239
348
  }
240
349
  };
241
350
 
242
- // src/services/nfc/useNfcState.ts
243
- import { useEffect, useState } from "react";
244
- function useNfcState() {
245
- const [state, setState] = useState(nfcService.getState());
246
- useEffect(() => nfcService.subscribe(setState), []);
247
- return {
248
- state,
249
- lastTag: nfcService.getLastTag()
250
- };
251
- }
351
+ // src/services/nfc/namespace.ts
352
+ var nfc = {
353
+ service: nfcService,
354
+ /** ISO15693 protocol helpers and high-level operations */
355
+ v: {
356
+ ...operations3,
357
+ // NfcVOperations, nfcV
358
+ utils: utils_exports3
359
+ },
360
+ /** NFC-A / Type 2 helpers and operations */
361
+ a: {
362
+ ...operations,
363
+ utils: utils_exports
364
+ },
365
+ /** NDEF read/write utilities and operations */
366
+ ndef: {
367
+ ...operations2,
368
+ utils: utils_exports2
369
+ }
370
+ };
252
371
  export {
253
- NfcUtils,
372
+ ndef_exports as ndef,
373
+ nfc,
374
+ a_exports as nfcA,
254
375
  nfcService,
255
- useNfcState
376
+ v_exports as nfcV
256
377
  };
257
378
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/services/nfc/NfcService.ts","../src/services/nfc/NfcUtils.ts","../src/services/nfc/useNfcState.ts"],"sourcesContent":["// NfcService.ts\r\nimport { Platform } from \"react-native\";\r\nimport NfcManager, {\r\n Ndef,\r\n NdefRecord,\r\n NfcEvents,\r\n NfcTech,\r\n TagEvent,\r\n} from \"react-native-nfc-manager\";\r\n\r\nexport type NfcState = \"idle\" | \"starting\" | \"active\" | \"stopping\" | \"writing\";\r\n\r\nexport type NfcListener = (state: NfcState) => void;\r\n\r\nclass NfcService {\r\n private state: NfcState = \"idle\";\r\n private lastTag: TagEvent | null = null;\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(next: NfcState) {\r\n if (this.state !== next) {\r\n this.state = next;\r\n for (const listener of this.listeners) listener(next);\r\n }\r\n }\r\n\r\n getState() {\r\n return this.state;\r\n }\r\n\r\n getLastTag() {\r\n return this.lastTag;\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 !== \"idle\") {\r\n console.warn(`[NFC] Cannot start reader while ${this.state}`);\r\n return;\r\n }\r\n\r\n this.setState(\"starting\");\r\n\r\n NfcManager.setEventListener(NfcEvents.DiscoverTag, (tag: TagEvent) => {\r\n this.lastTag = 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 as NfcState) === \"starting\") {\r\n this.setState(\"active\");\r\n }\r\n } catch (err) {\r\n console.warn(\"[NFC] startReader error:\", err);\r\n this.setState(\"idle\");\r\n }\r\n }\r\n\r\n async stopReader() {\r\n if ([\"idle\", \"stopping\"].includes(this.state)) return;\r\n this.setState(\"stopping\");\r\n try {\r\n await NfcManager.unregisterTagEvent();\r\n } catch {}\r\n this.setState(\"idle\");\r\n }\r\n\r\n // --- Writer ---\r\n async writeNdef(records: NdefRecord[]) {\r\n if (this.state !== \"idle\") {\r\n throw new Error(`Cannot write while reader is ${this.state}`);\r\n }\r\n\r\n this.setState(\"writing\");\r\n\r\n let res = {\r\n success: false,\r\n error: undefined,\r\n };\r\n\r\n try {\r\n await NfcManager.requestTechnology(NfcTech.Ndef, {\r\n alertMessage: \"Hold near NFC tag to write\",\r\n });\r\n const bytes = Ndef.encodeMessage(records);\r\n await NfcManager.ndefHandler.writeNdefMessage(bytes);\r\n if (Platform.OS === \"ios\")\r\n NfcManager.setAlertMessageIOS(\"Write successful\");\r\n } catch (err: any) {\r\n console.warn(\"[NFC] writeNdef error:\", err);\r\n\r\n res.success = false;\r\n res.error = err;\r\n } finally {\r\n try {\r\n await NfcManager.cancelTechnologyRequest();\r\n } catch {\r\n } finally {\r\n this.setState(\"idle\");\r\n return res;\r\n }\r\n }\r\n }\r\n}\r\n\r\n// Export one stable instance\r\nexport const nfcService = new NfcService();\r\n","import { Ndef, NdefRecord, TagEvent } from \"react-native-nfc-manager\";\r\n\r\nconst toU8 = (v: number[] | Uint8Array | ArrayBuffer): Uint8Array => {\r\n if (v instanceof Uint8Array) return v;\r\n if (Array.isArray(v)) return Uint8Array.from(v);\r\n return new Uint8Array(v);\r\n};\r\n\r\nconst toAscii = (u8: Uint8Array): string => String.fromCharCode(...u8);\r\n\r\nfunction decodeRecord(record: {\r\n tnf: number;\r\n type: number[] | string;\r\n id?: number[];\r\n payload: number[];\r\n}) {\r\n const { tnf } = record;\r\n\r\n // --- TYPE STRING -----------------------------------------------------\r\n let typeStr: string;\r\n if (typeof record.type === \"string\") {\r\n // iOS\r\n typeStr = record.type;\r\n } else {\r\n // Android\r\n typeStr = toAscii(toU8(record.type));\r\n }\r\n\r\n // --- PAYLOAD ---------------------------------------------------------\r\n const payloadU8 = toU8(record.payload);\r\n\r\n // ✅ TEXT RECORD\r\n if (tnf === Ndef.TNF_WELL_KNOWN && typeStr === \"T\") {\r\n const status = payloadU8[0];\r\n const langLen = status & 0x3f;\r\n const lang = toAscii(payloadU8.subarray(1, 1 + langLen));\r\n const textBytes = payloadU8.subarray(1 + langLen);\r\n const text = new TextDecoder().decode(textBytes);\r\n return { kind: \"text\", text, lang };\r\n }\r\n\r\n // ✅ URI RECORD\r\n if (tnf === Ndef.TNF_WELL_KNOWN && typeStr === \"U\") {\r\n const uri = Ndef.uri.decodePayload(payloadU8);\r\n return { kind: \"uri\", uri };\r\n }\r\n\r\n // ✅ MIME RECORD\r\n if (tnf === Ndef.TNF_MIME_MEDIA) {\r\n if (typeStr === \"application/json\") {\r\n return {\r\n kind: \"mime\",\r\n mimeType: typeStr,\r\n data: JSON.parse(new TextDecoder().decode(payloadU8)),\r\n };\r\n }\r\n\r\n function tryDecodeAsText(u8: Uint8Array): string | null {\r\n try {\r\n return new TextDecoder().decode(u8);\r\n } catch {\r\n return null;\r\n }\r\n }\r\n\r\n return {\r\n kind: \"mime\",\r\n mimeType: typeStr,\r\n data: payloadU8,\r\n text: typeStr.startsWith(\"text/\") ? tryDecodeAsText(payloadU8) : null,\r\n };\r\n }\r\n\r\n // ✅ ABSOLUTE URI RECORD\r\n if (tnf === Ndef.TNF_ABSOLUTE_URI) {\r\n return {\r\n kind: \"abs-uri\",\r\n uri: typeStr,\r\n data: payloadU8,\r\n };\r\n }\r\n\r\n // ✅ EXTERNAL RECORD\r\n if (tnf === Ndef.TNF_EXTERNAL_TYPE) {\r\n return {\r\n kind: \"external\",\r\n type: typeStr,\r\n data: payloadU8,\r\n };\r\n }\r\n\r\n // ✅ UNKNOWN RECORD\r\n if (tnf === Ndef.TNF_UNKNOWN) {\r\n return {\r\n kind: \"unknown\",\r\n type: typeStr,\r\n data: payloadU8,\r\n };\r\n }\r\n\r\n // ✅ FALLBACK\r\n return {\r\n kind: \"unknown\",\r\n tnf,\r\n type: typeStr,\r\n payload: payloadU8,\r\n };\r\n}\r\n\r\nfunction decodeJson(record: NdefRecord) {\r\n if (record.tnf !== Ndef.TNF_MIME_MEDIA) return null;\r\n\r\n // Convert type to string\r\n const typeStr =\r\n typeof record.type === \"string\" ? record.type : toAscii(toU8(record.type));\r\n\r\n if (typeStr !== \"application/json\") return null;\r\n\r\n const payloadU8 = toU8(record.payload);\r\n const jsonText = new TextDecoder().decode(payloadU8);\r\n\r\n try {\r\n return JSON.parse(jsonText);\r\n } catch (err) {\r\n console.warn(\"Invalid JSON in NDEF:\", err);\r\n return null;\r\n }\r\n}\r\n\r\nconst encodeText = (text: string, lang = \"en\") => Ndef.textRecord(text, lang);\r\n\r\nconst encodeUri = (uri: string) => Ndef.uriRecord(uri);\r\n\r\nfunction encodeJson(obj: any) {\r\n const json = JSON.stringify(obj);\r\n const payload = new TextEncoder().encode(json); // Uint8Array\r\n const typeArray = Array.from(new TextEncoder().encode(\"application/json\"));\r\n\r\n return {\r\n tnf: Ndef.TNF_MIME_MEDIA,\r\n type: typeArray, // MUST be a number[] of ASCII bytes\r\n id: [],\r\n payload,\r\n };\r\n}\r\n\r\nfunction encodeMime(mimeType: string, data: Uint8Array) {\r\n const typeBytes = Array.from(new TextEncoder().encode(mimeType));\r\n\r\n return {\r\n tnf: Ndef.TNF_MIME_MEDIA,\r\n type: typeBytes,\r\n id: [],\r\n payload: data,\r\n };\r\n}\r\n\r\n// Android only\r\nfunction willFit(tag: TagEvent, records: NdefRecord[]) {\r\n if (tag.maxSize === undefined) return null;\r\n\r\n const totalSize = Ndef.encodeMessage(records).length;\r\n return totalSize <= tag.maxSize;\r\n}\r\n\r\n// Android only\r\nfunction spaceLeft(tag: TagEvent, records: NdefRecord[]) {\r\n if (tag.maxSize === undefined) return null;\r\n\r\n const totalSize = Ndef.encodeMessage(records).length;\r\n return tag.maxSize - totalSize;\r\n}\r\n\r\nexport const NfcUtils = {\r\n Ndef: {\r\n decodeRecord,\r\n decodeJson,\r\n encodeText,\r\n encodeUri,\r\n encodeJson,\r\n encodeMime,\r\n willFit,\r\n spaceLeft,\r\n },\r\n};\r\n","import { useEffect, useState } from \"react\";\r\nimport { nfcService, NfcState } from \"./NfcService\";\r\n\r\nexport function useNfcState() {\r\n const [state, setState] = useState<NfcState>(nfcService.getState());\r\n\r\n useEffect(() => nfcService.subscribe(setState), []);\r\n\r\n return {\r\n state,\r\n lastTag: nfcService.getLastTag(),\r\n };\r\n}\r\n"],"mappings":";AACA,SAAS,gBAAgB;AACzB,OAAO;AAAA,EACL;AAAA,EAEA;AAAA,EACA;AAAA,OAEK;AAMP,IAAM,aAAN,MAAiB;AAAA,EAKf,cAAc;AAJd,SAAQ,QAAkB;AAC1B,SAAQ,UAA2B;AACnC,SAAQ,YAAY,oBAAI,IAAiB;AAGvC,eAAW,MAAM;AAAA,EACnB;AAAA;AAAA,EAGQ,SAAS,MAAgB;AAC/B,QAAI,KAAK,UAAU,MAAM;AACvB,WAAK,QAAQ;AACb,iBAAW,YAAY,KAAK,UAAW,UAAS,IAAI;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,WAAW;AACT,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAAa;AACX,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,UAAU,IAAiB;AACzB,SAAK,UAAU,IAAI,EAAE;AACrB,OAAG,KAAK,KAAK;AACb,WAAO,MAAM;AACX,WAAK,UAAU,OAAO,EAAE;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,YAAY,iBAAyB,OAAiC;AAC1E,QAAI,KAAK,UAAU,QAAQ;AACzB,cAAQ,KAAK,mCAAmC,KAAK,KAAK,EAAE;AAC5D;AAAA,IACF;AAEA,SAAK,SAAS,UAAU;AAExB,eAAW,iBAAiB,UAAU,aAAa,CAAC,QAAkB;AACpE,WAAK,UAAU;AACf,qCAAQ;AAAA,IACV,CAAC;AAED,QAAI;AACF,YAAM,WAAW,iBAAiB;AAAA,QAChC,qBAAqB;AAAA,QACrB;AAAA,MACF,CAAC;AACD,UAAK,KAAK,UAAuB,YAAY;AAC3C,aAAK,SAAS,QAAQ;AAAA,MACxB;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,KAAK,4BAA4B,GAAG;AAC5C,WAAK,SAAS,MAAM;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,aAAa;AACjB,QAAI,CAAC,QAAQ,UAAU,EAAE,SAAS,KAAK,KAAK,EAAG;AAC/C,SAAK,SAAS,UAAU;AACxB,QAAI;AACF,YAAM,WAAW,mBAAmB;AAAA,IACtC,QAAQ;AAAA,IAAC;AACT,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA;AAAA,EAGA,MAAM,UAAU,SAAuB;AACrC,QAAI,KAAK,UAAU,QAAQ;AACzB,YAAM,IAAI,MAAM,gCAAgC,KAAK,KAAK,EAAE;AAAA,IAC9D;AAEA,SAAK,SAAS,SAAS;AAEvB,QAAI,MAAM;AAAA,MACR,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,WAAW,kBAAkB,QAAQ,MAAM;AAAA,QAC/C,cAAc;AAAA,MAChB,CAAC;AACD,YAAM,QAAQ,KAAK,cAAc,OAAO;AACxC,YAAM,WAAW,YAAY,iBAAiB,KAAK;AACnD,UAAI,SAAS,OAAO;AAClB,mBAAW,mBAAmB,kBAAkB;AAAA,IACpD,SAAS,KAAU;AACjB,cAAQ,KAAK,0BAA0B,GAAG;AAE1C,UAAI,UAAU;AACd,UAAI,QAAQ;AAAA,IACd,UAAE;AACA,UAAI;AACF,cAAM,WAAW,wBAAwB;AAAA,MAC3C,QAAQ;AAAA,MACR,UAAE;AACA,aAAK,SAAS,MAAM;AACpB,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF;AAGO,IAAM,aAAa,IAAI,WAAW;;;AC3HzC,SAAS,QAAAA,aAAkC;AAE3C,IAAM,OAAO,CAAC,MAAuD;AACnE,MAAI,aAAa,WAAY,QAAO;AACpC,MAAI,MAAM,QAAQ,CAAC,EAAG,QAAO,WAAW,KAAK,CAAC;AAC9C,SAAO,IAAI,WAAW,CAAC;AACzB;AAEA,IAAM,UAAU,CAAC,OAA2B,OAAO,aAAa,GAAG,EAAE;AAErE,SAAS,aAAa,QAKnB;AACD,QAAM,EAAE,IAAI,IAAI;AAGhB,MAAI;AACJ,MAAI,OAAO,OAAO,SAAS,UAAU;AAEnC,cAAU,OAAO;AAAA,EACnB,OAAO;AAEL,cAAU,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,EACrC;AAGA,QAAM,YAAY,KAAK,OAAO,OAAO;AAGrC,MAAI,QAAQA,MAAK,kBAAkB,YAAY,KAAK;AAClD,UAAM,SAAS,UAAU,CAAC;AAC1B,UAAM,UAAU,SAAS;AACzB,UAAM,OAAO,QAAQ,UAAU,SAAS,GAAG,IAAI,OAAO,CAAC;AACvD,UAAM,YAAY,UAAU,SAAS,IAAI,OAAO;AAChD,UAAM,OAAO,IAAI,YAAY,EAAE,OAAO,SAAS;AAC/C,WAAO,EAAE,MAAM,QAAQ,MAAM,KAAK;AAAA,EACpC;AAGA,MAAI,QAAQA,MAAK,kBAAkB,YAAY,KAAK;AAClD,UAAM,MAAMA,MAAK,IAAI,cAAc,SAAS;AAC5C,WAAO,EAAE,MAAM,OAAO,IAAI;AAAA,EAC5B;AAGA,MAAI,QAAQA,MAAK,gBAAgB;AAS/B,QAASC,mBAAT,SAAyB,IAA+B;AACtD,UAAI;AACF,eAAO,IAAI,YAAY,EAAE,OAAO,EAAE;AAAA,MACpC,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AANS,0BAAAA;AART,QAAI,YAAY,oBAAoB;AAClC,aAAO;AAAA,QACL,MAAM;AAAA,QACN,UAAU;AAAA,QACV,MAAM,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,SAAS,CAAC;AAAA,MACtD;AAAA,IACF;AAUA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,UAAU;AAAA,MACV,MAAM;AAAA,MACN,MAAM,QAAQ,WAAW,OAAO,IAAIA,iBAAgB,SAAS,IAAI;AAAA,IACnE;AAAA,EACF;AAGA,MAAI,QAAQD,MAAK,kBAAkB;AACjC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,KAAK;AAAA,MACL,MAAM;AAAA,IACR;AAAA,EACF;AAGA,MAAI,QAAQA,MAAK,mBAAmB;AAClC,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAGA,MAAI,QAAQA,MAAK,aAAa;AAC5B,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAGA,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AACF;AAEA,SAAS,WAAW,QAAoB;AACtC,MAAI,OAAO,QAAQA,MAAK,eAAgB,QAAO;AAG/C,QAAM,UACJ,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO,QAAQ,KAAK,OAAO,IAAI,CAAC;AAE3E,MAAI,YAAY,mBAAoB,QAAO;AAE3C,QAAM,YAAY,KAAK,OAAO,OAAO;AACrC,QAAM,WAAW,IAAI,YAAY,EAAE,OAAO,SAAS;AAEnD,MAAI;AACF,WAAO,KAAK,MAAM,QAAQ;AAAA,EAC5B,SAAS,KAAK;AACZ,YAAQ,KAAK,yBAAyB,GAAG;AACzC,WAAO;AAAA,EACT;AACF;AAEA,IAAM,aAAa,CAAC,MAAc,OAAO,SAASA,MAAK,WAAW,MAAM,IAAI;AAE5E,IAAM,YAAY,CAAC,QAAgBA,MAAK,UAAU,GAAG;AAErD,SAAS,WAAW,KAAU;AAC5B,QAAM,OAAO,KAAK,UAAU,GAAG;AAC/B,QAAM,UAAU,IAAI,YAAY,EAAE,OAAO,IAAI;AAC7C,QAAM,YAAY,MAAM,KAAK,IAAI,YAAY,EAAE,OAAO,kBAAkB,CAAC;AAEzE,SAAO;AAAA,IACL,KAAKA,MAAK;AAAA,IACV,MAAM;AAAA;AAAA,IACN,IAAI,CAAC;AAAA,IACL;AAAA,EACF;AACF;AAEA,SAAS,WAAW,UAAkB,MAAkB;AACtD,QAAM,YAAY,MAAM,KAAK,IAAI,YAAY,EAAE,OAAO,QAAQ,CAAC;AAE/D,SAAO;AAAA,IACL,KAAKA,MAAK;AAAA,IACV,MAAM;AAAA,IACN,IAAI,CAAC;AAAA,IACL,SAAS;AAAA,EACX;AACF;AAGA,SAAS,QAAQ,KAAe,SAAuB;AACrD,MAAI,IAAI,YAAY,OAAW,QAAO;AAEtC,QAAM,YAAYA,MAAK,cAAc,OAAO,EAAE;AAC9C,SAAO,aAAa,IAAI;AAC1B;AAGA,SAAS,UAAU,KAAe,SAAuB;AACvD,MAAI,IAAI,YAAY,OAAW,QAAO;AAEtC,QAAM,YAAYA,MAAK,cAAc,OAAO,EAAE;AAC9C,SAAO,IAAI,UAAU;AACvB;AAEO,IAAM,WAAW;AAAA,EACtB,MAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACxLA,SAAS,WAAW,gBAAgB;AAG7B,SAAS,cAAc;AAC5B,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAmB,WAAW,SAAS,CAAC;AAElE,YAAU,MAAM,WAAW,UAAU,QAAQ,GAAG,CAAC,CAAC;AAElD,SAAO;AAAA,IACL;AAAA,IACA,SAAS,WAAW,WAAW;AAAA,EACjC;AACF;","names":["Ndef","tryDecodeAsText"]}
1
+ {"version":3,"sources":["../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/utils.ts","../src/services/nfc/namespace.ts"],"sourcesContent":["import { 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 * as 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 NfcAUtils = {};\r\n","export { operations } from \"./operations\";\r\nexport * as 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 NdefUtils = {};\r\n","export { operations } from \"./operations\";\r\nexport * as utils from \"./utils\";\r\n","import NfcManager, { TagEvent } from \"react-native-nfc-manager\";\r\nimport { nfcService } from \"../service\";\r\nimport { NfcVUtils } from \"./utils\";\r\n\r\nexport const operations = {\r\n async withVTag<T>(\r\n handler: (tag: TagEvent & { id: string }) => Promise<T>\r\n ): Promise<T> {\r\n return nfcService.withTechnology(NfcVUtils.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 TagEvent & { id: string });\r\n });\r\n },\r\n\r\n async writeBlockNfcV(blockNumber: number, data: Uint8Array) {\r\n return this.withVTag(async (tag) => {\r\n const uid = NfcVUtils.reverseUid(tag.id);\r\n const cmd = NfcVUtils.buildWriteBlock(uid, blockNumber, data);\r\n const resp = await NfcManager.transceive(cmd);\r\n NfcVUtils.parseWriteResponse(resp);\r\n });\r\n },\r\n\r\n async readBlockNfcV(blockNumber: number) {\r\n return this.withVTag(async (tag) => {\r\n const uid = NfcVUtils.reverseUid(tag.id);\r\n const cmd = NfcVUtils.buildReadBlock(uid, blockNumber);\r\n const resp = await NfcManager.transceive(cmd);\r\n return NfcVUtils.parseReadResponse(resp);\r\n });\r\n },\r\n\r\n async getSystemInfoNfcV() {\r\n return this.withVTag(async (tag) => {\r\n const uid = NfcVUtils.reverseUid(tag.id);\r\n const cmd = NfcVUtils.buildGetSystemInfo(uid);\r\n const resp = await NfcManager.transceive(cmd);\r\n return NfcVUtils.parseSystemInfo(resp);\r\n });\r\n },\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 NfcVUtils = {\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 const flags = this.flags(this.Flags.ADDRESSED, this.Flags.HIGH_DATA_RATE);\r\n return [flags, this.Commands.GET_SYSTEM_INFO, ...uidReversed];\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 (uid.startsWith(\"E004\") || uid.startsWith(\"E006\"))\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","NfcTech","NfcTech","NfcManager","operations","utils_exports","NfcManager","NfcTech","operations","NfcTech","NfcManager","utils_exports","operations","utils_exports","NfcManager","utils_exports","Platform","NfcTech","operations","NfcManager","operations","utils_exports"]}