@ukeyfe/react-native-nfc-litecard 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/README.md +250 -178
- package/{README.en.md → README.zh.md} +122 -50
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +8 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/nfc-core.js +3 -1
- package/dist/reader.d.ts +11 -6
- package/dist/reader.js +67 -23
- package/dist/types.d.ts +9 -0
- package/dist/types.js +17 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +53 -0
- package/dist/writer.d.ts +13 -4
- package/dist/writer.js +87 -18
- package/package.json +3 -2
package/dist/types.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
exports.ResultCode = void 0;
|
|
15
|
+
exports.nfcResultRetryCountExhausted = nfcResultRetryCountExhausted;
|
|
15
16
|
exports.errorToCode = errorToCode;
|
|
16
17
|
const react_native_1 = require("react-native");
|
|
17
18
|
// ---------------------------------------------------------------------------
|
|
@@ -30,6 +31,8 @@ exports.ResultCode = {
|
|
|
30
31
|
UPDATE_PASSWORD_SUCCESS: 10204,
|
|
31
32
|
WRITE_NICKNAME_SUCCESS: 10205,
|
|
32
33
|
RESET_SUCCESS: 10206,
|
|
34
|
+
/** Card already has a valid mnemonic backup; write was skipped */
|
|
35
|
+
PRECHECK_HAS_BACKUP: 10207,
|
|
33
36
|
// Failure (4xxxx – shared by reader & writer)
|
|
34
37
|
NFC_CONNECT_FAILED: 40001,
|
|
35
38
|
AUTH_WRONG_PASSWORD: 40002,
|
|
@@ -45,7 +48,20 @@ exports.ResultCode = {
|
|
|
45
48
|
READ_TIMEOUT: 40012,
|
|
46
49
|
NFC_LOCK_TIMEOUT: 40013,
|
|
47
50
|
CRC16_CHECK_FAILED: 40014,
|
|
51
|
+
/** PIN retry counter is 0; no authentication attempts left */
|
|
52
|
+
RETRY_COUNT_EXHAUSTED: 40015,
|
|
48
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* Unified failure result when the PIN retry counter has reached 0.
|
|
56
|
+
* Used by readMnemonic, updateCard, updatePassword, and resetCard.
|
|
57
|
+
*/
|
|
58
|
+
function nfcResultRetryCountExhausted() {
|
|
59
|
+
return {
|
|
60
|
+
code: exports.ResultCode.RETRY_COUNT_EXHAUSTED,
|
|
61
|
+
success: false,
|
|
62
|
+
data: { retryCount: 0 },
|
|
63
|
+
};
|
|
64
|
+
}
|
|
49
65
|
// ---------------------------------------------------------------------------
|
|
50
66
|
// Error → code mapping (internal use)
|
|
51
67
|
// ---------------------------------------------------------------------------
|
|
@@ -71,6 +87,7 @@ function errorToCode(error) {
|
|
|
71
87
|
if (msg.includes('NFC_USER_CANCELED_SIGNAL'))
|
|
72
88
|
return exports.ResultCode.NFC_USER_CANCELED;
|
|
73
89
|
const keywords = [
|
|
90
|
+
['RETRY_COUNT_EXHAUSTED', exports.ResultCode.RETRY_COUNT_EXHAUSTED],
|
|
74
91
|
['AUTH_WRONG_PASSWORD', exports.ResultCode.AUTH_WRONG_PASSWORD],
|
|
75
92
|
['AUTH_INVALID_RESPONSE', exports.ResultCode.AUTH_INVALID_RESPONSE],
|
|
76
93
|
['AUTH_VERIFY_FAILED', exports.ResultCode.AUTH_VERIFY_FAILED],
|
package/dist/utils.d.ts
CHANGED
|
@@ -15,3 +15,13 @@ export declare function crc16ToBytes(crc16: number): Uint8Array;
|
|
|
15
15
|
* @throws if buffer is shorter than 2 bytes.
|
|
16
16
|
*/
|
|
17
17
|
export declare function extractCRC16(data: Uint8Array): number;
|
|
18
|
+
/**
|
|
19
|
+
* Validate whether raw card data contains a valid mnemonic payload.
|
|
20
|
+
* Checks type byte, length, and CRC16 — does NOT decode the mnemonic.
|
|
21
|
+
*
|
|
22
|
+
* @throws INVALID_CARD_DATA / EMPTY_CARD / CRC16_CHECK_FAILED
|
|
23
|
+
* @returns The mnemonic type description string.
|
|
24
|
+
*/
|
|
25
|
+
export declare function validateMnemonicPayload(data: Uint8Array): {
|
|
26
|
+
type: string;
|
|
27
|
+
};
|
package/dist/utils.js
CHANGED
|
@@ -8,6 +8,8 @@ exports.hexToBytes = hexToBytes;
|
|
|
8
8
|
exports.calculateCRC16 = calculateCRC16;
|
|
9
9
|
exports.crc16ToBytes = crc16ToBytes;
|
|
10
10
|
exports.extractCRC16 = extractCRC16;
|
|
11
|
+
exports.validateMnemonicPayload = validateMnemonicPayload;
|
|
12
|
+
const constants_1 = require("./constants");
|
|
11
13
|
// ---------------------------------------------------------------------------
|
|
12
14
|
// Hex ↔ bytes
|
|
13
15
|
// ---------------------------------------------------------------------------
|
|
@@ -61,3 +63,54 @@ function extractCRC16(data) {
|
|
|
61
63
|
}
|
|
62
64
|
return data[data.length - 2] | (data[data.length - 1] << 8);
|
|
63
65
|
}
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
// Mnemonic payload validation
|
|
68
|
+
// ---------------------------------------------------------------------------
|
|
69
|
+
/**
|
|
70
|
+
* Validate whether raw card data contains a valid mnemonic payload.
|
|
71
|
+
* Checks type byte, length, and CRC16 — does NOT decode the mnemonic.
|
|
72
|
+
*
|
|
73
|
+
* @throws INVALID_CARD_DATA / EMPTY_CARD / CRC16_CHECK_FAILED
|
|
74
|
+
* @returns The mnemonic type description string.
|
|
75
|
+
*/
|
|
76
|
+
function validateMnemonicPayload(data) {
|
|
77
|
+
if (data.length < 19)
|
|
78
|
+
throw new Error('INVALID_CARD_DATA');
|
|
79
|
+
if (data.every(b => b === 0))
|
|
80
|
+
throw new Error('EMPTY_CARD');
|
|
81
|
+
const typeId = data[0];
|
|
82
|
+
let entropyLength;
|
|
83
|
+
let typeStr;
|
|
84
|
+
switch (typeId) {
|
|
85
|
+
case constants_1.MNEMONIC_TYPE_12:
|
|
86
|
+
entropyLength = 16;
|
|
87
|
+
typeStr = '12 words (128-bit)';
|
|
88
|
+
break;
|
|
89
|
+
case constants_1.MNEMONIC_TYPE_15:
|
|
90
|
+
entropyLength = 20;
|
|
91
|
+
typeStr = '15 words (160-bit)';
|
|
92
|
+
break;
|
|
93
|
+
case constants_1.MNEMONIC_TYPE_18:
|
|
94
|
+
entropyLength = 24;
|
|
95
|
+
typeStr = '18 words (192-bit)';
|
|
96
|
+
break;
|
|
97
|
+
case constants_1.MNEMONIC_TYPE_21:
|
|
98
|
+
entropyLength = 28;
|
|
99
|
+
typeStr = '21 words (224-bit)';
|
|
100
|
+
break;
|
|
101
|
+
case constants_1.MNEMONIC_TYPE_24:
|
|
102
|
+
entropyLength = 32;
|
|
103
|
+
typeStr = '24 words (256-bit)';
|
|
104
|
+
break;
|
|
105
|
+
default: throw new Error('INVALID_CARD_DATA');
|
|
106
|
+
}
|
|
107
|
+
const expectedTotal = 1 + entropyLength + 2;
|
|
108
|
+
if (data.length < expectedTotal)
|
|
109
|
+
throw new Error('INVALID_CARD_DATA');
|
|
110
|
+
const dataBlock = data.slice(0, 1 + entropyLength);
|
|
111
|
+
const storedCRC = extractCRC16(data.slice(1 + entropyLength, expectedTotal));
|
|
112
|
+
const calcCRC = calculateCRC16(dataBlock);
|
|
113
|
+
if (storedCRC !== calcCRC)
|
|
114
|
+
throw new Error('CRC16_CHECK_FAILED');
|
|
115
|
+
return { type: typeStr };
|
|
116
|
+
}
|
package/dist/writer.d.ts
CHANGED
|
@@ -19,14 +19,23 @@ export { ResultCode, type NfcResult, isNfcOperationLocked, releaseNfcOperationLo
|
|
|
19
19
|
export declare function initializeCard(mnemonic: string, password: string, onCardIdentified?: () => void): Promise<NfcResult>;
|
|
20
20
|
/**
|
|
21
21
|
* Update card: authenticate with old password, then write new mnemonic + new password.
|
|
22
|
+
*
|
|
23
|
+
* When `options.precheckExistingMnemonic` is true, the card is read after authentication.
|
|
24
|
+
* If a valid mnemonic backup already exists, the write is skipped and PRECHECK_HAS_BACKUP
|
|
25
|
+
* is returned (`success: true` — operation completed; distinguish outcome by `code`).
|
|
26
|
+
* Otherwise the normal write flow proceeds.
|
|
22
27
|
*/
|
|
23
|
-
export declare function updateCard(oldPassword: string, newPassword: string, newMnemonic: string, onCardIdentified?: () => void
|
|
28
|
+
export declare function updateCard(oldPassword: string, newPassword: string, newMnemonic: string, onCardIdentified?: () => void, options?: {
|
|
29
|
+
precheckExistingMnemonic?: boolean;
|
|
30
|
+
}): Promise<NfcResult>;
|
|
24
31
|
/** Change password only (old password required). */
|
|
25
32
|
export declare function updatePassword(oldPassword: string, newPassword: string, onCardIdentified?: () => void): Promise<NfcResult>;
|
|
26
33
|
/** Write a user nickname (password required for authentication). */
|
|
27
|
-
export declare function writeUserNickname(password: string, nickname: string): Promise<NfcResult>;
|
|
34
|
+
export declare function writeUserNickname(password: string, nickname: string, onCardIdentified?: () => void): Promise<NfcResult>;
|
|
28
35
|
/**
|
|
29
|
-
* Reset card: wipe
|
|
36
|
+
* Reset card: wipe mnemonic data and set a new password.
|
|
30
37
|
* @param password – current card password (required if protection is enabled).
|
|
38
|
+
* @param newPassword – password to set after reset.
|
|
39
|
+
* @param onCardIdentified – callback when card is identified.
|
|
31
40
|
*/
|
|
32
|
-
export declare function resetCard(password
|
|
41
|
+
export declare function resetCard(password: string | undefined, newPassword: string, onCardIdentified?: () => void): Promise<NfcResult>;
|
package/dist/writer.js
CHANGED
|
@@ -77,13 +77,14 @@ async function writePage(page, data) {
|
|
|
77
77
|
await (0, nfc_core_1.transceive)([constants_1.CMD_WRITE, page, ...data]);
|
|
78
78
|
}
|
|
79
79
|
/**
|
|
80
|
-
* Write data to
|
|
80
|
+
* Write data to mnemonic area (pages 0x08–0x24).
|
|
81
|
+
* Does NOT touch the nickname area (pages 0x25–0x27).
|
|
81
82
|
* iOS: inserts small delays and periodic keep-alive reads.
|
|
82
83
|
*/
|
|
83
84
|
async function writeUserMemory(data) {
|
|
84
|
-
const buffer = new Uint8Array(constants_1.
|
|
85
|
-
buffer.set(data, 0);
|
|
86
|
-
const totalPages = constants_1.
|
|
85
|
+
const buffer = new Uint8Array(constants_1.MNEMONIC_MEMORY_SIZE);
|
|
86
|
+
buffer.set(data.slice(0, constants_1.MNEMONIC_MEMORY_SIZE), 0);
|
|
87
|
+
const totalPages = constants_1.MNEMONIC_PAGE_END - constants_1.USER_PAGE_START + 1;
|
|
87
88
|
for (let i = 0; i < totalPages; i++) {
|
|
88
89
|
const page = constants_1.USER_PAGE_START + i;
|
|
89
90
|
const offset = i * constants_1.PAGE_SIZE;
|
|
@@ -101,6 +102,13 @@ async function writeUserMemory(data) {
|
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
104
|
}
|
|
105
|
+
/** FAST_READ pages 0x08–0x27 (user memory). */
|
|
106
|
+
async function readUserMemory() {
|
|
107
|
+
const response = await (0, nfc_core_1.transceive)([constants_1.CMD_FAST_READ, constants_1.USER_PAGE_START, constants_1.USER_PAGE_END]);
|
|
108
|
+
if (!response || response.length < constants_1.USER_MEMORY_SIZE)
|
|
109
|
+
throw new Error('READ_FAILED');
|
|
110
|
+
return new Uint8Array(response.slice(0, constants_1.USER_MEMORY_SIZE));
|
|
111
|
+
}
|
|
104
112
|
/**
|
|
105
113
|
* Write a 16-byte AES key to AES_KEY0 (pages 0x30–0x33).
|
|
106
114
|
* Byte order is reversed per the datasheet.
|
|
@@ -273,8 +281,13 @@ async function initializeCard(mnemonic, password, onCardIdentified) {
|
|
|
273
281
|
}
|
|
274
282
|
/**
|
|
275
283
|
* Update card: authenticate with old password, then write new mnemonic + new password.
|
|
284
|
+
*
|
|
285
|
+
* When `options.precheckExistingMnemonic` is true, the card is read after authentication.
|
|
286
|
+
* If a valid mnemonic backup already exists, the write is skipped and PRECHECK_HAS_BACKUP
|
|
287
|
+
* is returned (`success: true` — operation completed; distinguish outcome by `code`).
|
|
288
|
+
* Otherwise the normal write flow proceeds.
|
|
276
289
|
*/
|
|
277
|
-
async function updateCard(oldPassword, newPassword, newMnemonic, onCardIdentified) {
|
|
290
|
+
async function updateCard(oldPassword, newPassword, newMnemonic, onCardIdentified, options) {
|
|
278
291
|
try {
|
|
279
292
|
await (0, nfc_core_1.acquireNfcLock)();
|
|
280
293
|
}
|
|
@@ -291,22 +304,57 @@ async function updateCard(oldPassword, newPassword, newMnemonic, onCardIdentifie
|
|
|
291
304
|
return { code: types_1.ResultCode.NFC_CONNECT_FAILED, success: false };
|
|
292
305
|
}
|
|
293
306
|
try {
|
|
294
|
-
const entropyResult = mnemonicToEntropyWithCRC(newMnemonic);
|
|
295
307
|
try {
|
|
296
308
|
const n = await (0, nfc_core_1.decrementRetryCountInSession)();
|
|
297
309
|
if (typeof n === 'number')
|
|
298
310
|
retryCountAfterPreDecrement = n;
|
|
299
311
|
}
|
|
300
|
-
catch {
|
|
312
|
+
catch (error) {
|
|
313
|
+
const code = (0, types_1.errorToCode)(error);
|
|
314
|
+
if (code === types_1.ResultCode.RETRY_COUNT_EXHAUSTED) {
|
|
315
|
+
await (0, nfc_core_1.releaseNfcTech)();
|
|
316
|
+
(0, nfc_core_1.releaseNfcLock)();
|
|
317
|
+
return (0, types_1.nfcResultRetryCountExhausted)();
|
|
318
|
+
}
|
|
319
|
+
// Communication failure — counter was not decremented, continue to auth
|
|
320
|
+
}
|
|
301
321
|
const oldKey = (0, crypto_1.passwordToAesKey)(oldPassword);
|
|
302
322
|
await (0, nfc_core_1.authenticate)(oldKey);
|
|
303
323
|
try {
|
|
304
324
|
await (0, nfc_core_1.writeRetryCountInSession)(constants_1.DEFAULT_PIN_RETRY_COUNT);
|
|
325
|
+
retryCountAfterPreDecrement = constants_1.DEFAULT_PIN_RETRY_COUNT;
|
|
305
326
|
}
|
|
306
327
|
catch { /* non-fatal */ }
|
|
307
328
|
onCardIdentified?.();
|
|
308
|
-
|
|
329
|
+
if (options?.precheckExistingMnemonic) {
|
|
330
|
+
try {
|
|
331
|
+
const data = await readUserMemory();
|
|
332
|
+
const decoded = (0, utils_1.validateMnemonicPayload)(data);
|
|
333
|
+
await (0, nfc_core_1.releaseNfcTech)();
|
|
334
|
+
(0, nfc_core_1.releaseNfcLock)();
|
|
335
|
+
return {
|
|
336
|
+
code: types_1.ResultCode.PRECHECK_HAS_BACKUP,
|
|
337
|
+
success: true,
|
|
338
|
+
data: { type: decoded.type, retryCount: constants_1.DEFAULT_PIN_RETRY_COUNT },
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
catch (e) {
|
|
342
|
+
const c = (0, types_1.errorToCode)(e);
|
|
343
|
+
if (c === types_1.ResultCode.CHECK_EMPTY ||
|
|
344
|
+
c === types_1.ResultCode.CRC16_CHECK_FAILED ||
|
|
345
|
+
c === types_1.ResultCode.INVALID_CARD_DATA) {
|
|
346
|
+
// No valid mnemonic on card — fall through to write
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
await (0, nfc_core_1.releaseNfcTech)();
|
|
350
|
+
(0, nfc_core_1.releaseNfcLock)();
|
|
351
|
+
return { code: c, success: false };
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const entropyResult = mnemonicToEntropyWithCRC(newMnemonic);
|
|
309
356
|
await writeUserMemory(entropyResult.data);
|
|
357
|
+
await disableAuth();
|
|
310
358
|
const newKey = (0, crypto_1.passwordToAesKey)(newPassword);
|
|
311
359
|
const aesKeyHex = (0, utils_1.bytesToHex)(newKey);
|
|
312
360
|
await writeAesKey(newKey);
|
|
@@ -366,11 +414,20 @@ async function updatePassword(oldPassword, newPassword, onCardIdentified) {
|
|
|
366
414
|
if (typeof n === 'number')
|
|
367
415
|
retryCountAfterPreDecrement = n;
|
|
368
416
|
}
|
|
369
|
-
catch {
|
|
417
|
+
catch (error) {
|
|
418
|
+
const code = (0, types_1.errorToCode)(error);
|
|
419
|
+
if (code === types_1.ResultCode.RETRY_COUNT_EXHAUSTED) {
|
|
420
|
+
await (0, nfc_core_1.releaseNfcTech)();
|
|
421
|
+
(0, nfc_core_1.releaseNfcLock)();
|
|
422
|
+
return (0, types_1.nfcResultRetryCountExhausted)();
|
|
423
|
+
}
|
|
424
|
+
// Communication failure — counter was not decremented, continue to auth
|
|
425
|
+
}
|
|
370
426
|
const oldKey = (0, crypto_1.passwordToAesKey)(oldPassword);
|
|
371
427
|
await (0, nfc_core_1.authenticate)(oldKey);
|
|
372
428
|
try {
|
|
373
429
|
await (0, nfc_core_1.writeRetryCountInSession)(constants_1.DEFAULT_PIN_RETRY_COUNT);
|
|
430
|
+
retryCountAfterPreDecrement = constants_1.DEFAULT_PIN_RETRY_COUNT;
|
|
374
431
|
}
|
|
375
432
|
catch { /* non-fatal */ }
|
|
376
433
|
onCardIdentified?.();
|
|
@@ -404,7 +461,7 @@ async function updatePassword(oldPassword, newPassword, onCardIdentified) {
|
|
|
404
461
|
}
|
|
405
462
|
}
|
|
406
463
|
/** Write a user nickname (password required for authentication). */
|
|
407
|
-
async function writeUserNickname(password, nickname) {
|
|
464
|
+
async function writeUserNickname(password, nickname, onCardIdentified) {
|
|
408
465
|
try {
|
|
409
466
|
await (0, nfc_core_1.acquireNfcLock)();
|
|
410
467
|
}
|
|
@@ -422,6 +479,7 @@ async function writeUserNickname(password, nickname) {
|
|
|
422
479
|
try {
|
|
423
480
|
const aesKey = (0, crypto_1.passwordToAesKey)(password);
|
|
424
481
|
await (0, nfc_core_1.authenticate)(aesKey);
|
|
482
|
+
onCardIdentified?.();
|
|
425
483
|
await disableAuth();
|
|
426
484
|
await writeNicknameToCard(nickname);
|
|
427
485
|
await configureAuth();
|
|
@@ -445,10 +503,12 @@ async function writeUserNickname(password, nickname) {
|
|
|
445
503
|
}
|
|
446
504
|
}
|
|
447
505
|
/**
|
|
448
|
-
* Reset card: wipe
|
|
506
|
+
* Reset card: wipe mnemonic data and set a new password.
|
|
449
507
|
* @param password – current card password (required if protection is enabled).
|
|
508
|
+
* @param newPassword – password to set after reset.
|
|
509
|
+
* @param onCardIdentified – callback when card is identified.
|
|
450
510
|
*/
|
|
451
|
-
async function resetCard(password, onCardIdentified) {
|
|
511
|
+
async function resetCard(password, newPassword, onCardIdentified) {
|
|
452
512
|
try {
|
|
453
513
|
await (0, nfc_core_1.acquireNfcLock)();
|
|
454
514
|
}
|
|
@@ -471,12 +531,21 @@ async function resetCard(password, onCardIdentified) {
|
|
|
471
531
|
if (typeof n === 'number')
|
|
472
532
|
retryCountAfterPreDecrement = n;
|
|
473
533
|
}
|
|
474
|
-
catch {
|
|
534
|
+
catch (error) {
|
|
535
|
+
const code = (0, types_1.errorToCode)(error);
|
|
536
|
+
if (code === types_1.ResultCode.RETRY_COUNT_EXHAUSTED) {
|
|
537
|
+
await (0, nfc_core_1.releaseNfcTech)();
|
|
538
|
+
(0, nfc_core_1.releaseNfcLock)();
|
|
539
|
+
return (0, types_1.nfcResultRetryCountExhausted)();
|
|
540
|
+
}
|
|
541
|
+
// Communication failure — counter was not decremented, continue to auth
|
|
542
|
+
}
|
|
475
543
|
const aesKey = (0, crypto_1.passwordToAesKey)(password);
|
|
476
544
|
try {
|
|
477
545
|
await (0, nfc_core_1.authenticate)(aesKey);
|
|
478
546
|
try {
|
|
479
547
|
await (0, nfc_core_1.writeRetryCountInSession)(constants_1.DEFAULT_PIN_RETRY_COUNT);
|
|
548
|
+
retryCountAfterPreDecrement = constants_1.DEFAULT_PIN_RETRY_COUNT;
|
|
480
549
|
}
|
|
481
550
|
catch { /* non-fatal */ }
|
|
482
551
|
}
|
|
@@ -507,11 +576,11 @@ async function resetCard(password, onCardIdentified) {
|
|
|
507
576
|
}
|
|
508
577
|
onCardIdentified?.();
|
|
509
578
|
}
|
|
510
|
-
// Wipe
|
|
511
|
-
await writeUserMemory(new Uint8Array(constants_1.
|
|
512
|
-
// Set
|
|
513
|
-
const
|
|
514
|
-
await writeAesKey(
|
|
579
|
+
// Wipe mnemonic data (nickname is preserved)
|
|
580
|
+
await writeUserMemory(new Uint8Array(constants_1.MNEMONIC_MEMORY_SIZE));
|
|
581
|
+
// Set new password
|
|
582
|
+
const resetKey = (0, crypto_1.passwordToAesKey)(newPassword);
|
|
583
|
+
await writeAesKey(resetKey);
|
|
515
584
|
// Ensure protection is disabled
|
|
516
585
|
try {
|
|
517
586
|
await disableAuth();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ukeyfe/react-native-nfc-litecard",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "NFC read/write for MIFARE Ultralight AES (LiteCard mnemonic storage)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"files": [
|
|
29
29
|
"dist",
|
|
30
|
-
"README.md"
|
|
30
|
+
"README.md",
|
|
31
|
+
"README.zh.md"
|
|
31
32
|
]
|
|
32
33
|
}
|