@ukeyfe/react-native-nfc-litecard 1.0.5 → 1.0.7
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.d.ts +239 -7
- package/dist/index.js +1486 -49
- package/package.json +4 -2
- package/dist/constants.d.ts +0 -87
- package/dist/constants.js +0 -117
- package/dist/crypto.d.ts +0 -55
- package/dist/crypto.js +0 -271
- package/dist/nfc-core.d.ts +0 -74
- package/dist/nfc-core.js +0 -376
- package/dist/reader.d.ts +0 -98
- package/dist/reader.js +0 -619
- package/dist/types.d.ts +0 -80
- package/dist/types.js +0 -113
- package/dist/utils.d.ts +0 -43
- package/dist/utils.js +0 -124
- package/dist/writer.d.ts +0 -46
- package/dist/writer.js +0 -623
package/dist/types.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Unified result codes, NfcResult interface, and error mapping helpers.
|
|
4
|
-
*
|
|
5
|
-
* All codes are unique across reader and writer to prevent ambiguity.
|
|
6
|
-
* - Reader success : 101xx
|
|
7
|
-
* - Writer success : 102xx
|
|
8
|
-
* - Failure : 4xxxx (shared)
|
|
9
|
-
*
|
|
10
|
-
* This library does NOT provide user-facing messages.
|
|
11
|
-
* The caller should map NfcStatusCode to their own localised strings.
|
|
12
|
-
*/
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.NfcStatusCode = void 0;
|
|
15
|
-
exports.nfcResultRetryCountExhausted = nfcResultRetryCountExhausted;
|
|
16
|
-
exports.errorToCode = errorToCode;
|
|
17
|
-
const react_native_1 = require("react-native");
|
|
18
|
-
// ---------------------------------------------------------------------------
|
|
19
|
-
// Unified result codes
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
exports.NfcStatusCode = {
|
|
22
|
-
// Reader success (101xx)
|
|
23
|
-
READ_SUCCESS: 10102,
|
|
24
|
-
READ_NICKNAME_SUCCESS: 10103,
|
|
25
|
-
CHECK_EMPTY: 10104,
|
|
26
|
-
CHECK_HAS_DATA: 10105,
|
|
27
|
-
READ_RETRY_COUNT_SUCCESS: 10106,
|
|
28
|
-
GET_VERSION_SUCCESS: 10107,
|
|
29
|
-
READ_SIG_SUCCESS: 10108,
|
|
30
|
-
// Writer success (102xx)
|
|
31
|
-
INIT_SUCCESS: 10201,
|
|
32
|
-
WRITE_SUCCESS: 10203,
|
|
33
|
-
UPDATE_PASSWORD_SUCCESS: 10204,
|
|
34
|
-
WRITE_NICKNAME_SUCCESS: 10205,
|
|
35
|
-
RESET_SUCCESS: 10206,
|
|
36
|
-
/** Card already has a valid mnemonic backup; write was skipped */
|
|
37
|
-
PRECHECK_HAS_BACKUP: 10207,
|
|
38
|
-
// Failure (4xxxx – shared by reader & writer)
|
|
39
|
-
NFC_CONNECT_FAILED: 40001,
|
|
40
|
-
AUTH_WRONG_PASSWORD: 40002,
|
|
41
|
-
AUTH_INVALID_RESPONSE: 40003,
|
|
42
|
-
AUTH_VERIFY_FAILED: 40004,
|
|
43
|
-
READ_FAILED: 40005,
|
|
44
|
-
WRITE_FAILED: 40006,
|
|
45
|
-
INVALID_MNEMONIC: 40007,
|
|
46
|
-
UNSUPPORTED_MNEMONIC_LENGTH: 40008,
|
|
47
|
-
INVALID_CARD_DATA: 40009,
|
|
48
|
-
UNKNOWN_ERROR: 40010,
|
|
49
|
-
NFC_USER_CANCELED: 40011,
|
|
50
|
-
READ_TIMEOUT: 40012,
|
|
51
|
-
NFC_LOCK_TIMEOUT: 40013,
|
|
52
|
-
CRC16_CHECK_FAILED: 40014,
|
|
53
|
-
/** PIN retry counter is 0; no authentication attempts left */
|
|
54
|
-
RETRY_COUNT_EXHAUSTED: 40015,
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* Unified failure result when the PIN retry counter has reached 0.
|
|
58
|
-
* Used by readMnemonic, updateCard, updatePassword, and resetCard.
|
|
59
|
-
*/
|
|
60
|
-
function nfcResultRetryCountExhausted() {
|
|
61
|
-
return {
|
|
62
|
-
code: exports.NfcStatusCode.RETRY_COUNT_EXHAUSTED,
|
|
63
|
-
success: false,
|
|
64
|
-
data: { retryCount: 0 },
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
// ---------------------------------------------------------------------------
|
|
68
|
-
// Error → code mapping (internal use)
|
|
69
|
-
// ---------------------------------------------------------------------------
|
|
70
|
-
/**
|
|
71
|
-
* Derive a NfcStatusCode from an error thrown during NFC operations.
|
|
72
|
-
* Handles iOS-specific cancel detection, known error strings, and fallback.
|
|
73
|
-
*/
|
|
74
|
-
function errorToCode(error) {
|
|
75
|
-
const msg = (typeof error === 'string'
|
|
76
|
-
? error
|
|
77
|
-
: (error?.message || '')).trim();
|
|
78
|
-
// iOS user-cancel detection
|
|
79
|
-
if (react_native_1.Platform.OS === 'ios') {
|
|
80
|
-
if (error &&
|
|
81
|
-
typeof error === 'object' &&
|
|
82
|
-
(error.name === 'UserCancel' || error.constructor?.name === 'UserCancel')) {
|
|
83
|
-
return exports.NfcStatusCode.NFC_USER_CANCELED;
|
|
84
|
-
}
|
|
85
|
-
if (!msg || msg.includes('User Canceled') || msg.includes('Unknown empty error')) {
|
|
86
|
-
return exports.NfcStatusCode.NFC_USER_CANCELED;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (msg.includes('NFC_USER_CANCELED_SIGNAL'))
|
|
90
|
-
return exports.NfcStatusCode.NFC_USER_CANCELED;
|
|
91
|
-
const keywords = [
|
|
92
|
-
['RETRY_COUNT_EXHAUSTED', exports.NfcStatusCode.RETRY_COUNT_EXHAUSTED],
|
|
93
|
-
['AUTH_WRONG_PASSWORD', exports.NfcStatusCode.AUTH_WRONG_PASSWORD],
|
|
94
|
-
['AUTH_INVALID_RESPONSE', exports.NfcStatusCode.AUTH_INVALID_RESPONSE],
|
|
95
|
-
['AUTH_VERIFY_FAILED', exports.NfcStatusCode.AUTH_VERIFY_FAILED],
|
|
96
|
-
['READ_FAILED', exports.NfcStatusCode.READ_FAILED],
|
|
97
|
-
['WRITE_FAILED', exports.NfcStatusCode.WRITE_FAILED],
|
|
98
|
-
['CRC16_CHECK_FAILED', exports.NfcStatusCode.CRC16_CHECK_FAILED],
|
|
99
|
-
['EMPTY_CARD', exports.NfcStatusCode.CHECK_EMPTY],
|
|
100
|
-
['INVALID_CARD_DATA', exports.NfcStatusCode.INVALID_CARD_DATA],
|
|
101
|
-
['INVALID_MNEMONIC', exports.NfcStatusCode.INVALID_MNEMONIC],
|
|
102
|
-
['UNSUPPORTED_MNEMONIC_LENGTH', exports.NfcStatusCode.UNSUPPORTED_MNEMONIC_LENGTH],
|
|
103
|
-
['NFC_LOCK_TIMEOUT', exports.NfcStatusCode.NFC_LOCK_TIMEOUT],
|
|
104
|
-
['NFC_CONNECT_FAILED', exports.NfcStatusCode.NFC_CONNECT_FAILED],
|
|
105
|
-
['connection failed', exports.NfcStatusCode.NFC_CONNECT_FAILED],
|
|
106
|
-
['transceive fail', exports.NfcStatusCode.NFC_CONNECT_FAILED],
|
|
107
|
-
];
|
|
108
|
-
for (const [keyword, code] of keywords) {
|
|
109
|
-
if (msg.includes(keyword))
|
|
110
|
-
return code;
|
|
111
|
-
}
|
|
112
|
-
return exports.NfcStatusCode.UNKNOWN_ERROR;
|
|
113
|
-
}
|
package/dist/utils.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure utility functions – no NFC or platform dependencies.
|
|
3
|
-
*/
|
|
4
|
-
export declare function bytesToHex(bytes: Uint8Array | number[]): string;
|
|
5
|
-
export declare function hexToBytes(hex: string): Uint8Array;
|
|
6
|
-
/**
|
|
7
|
-
* CRC16-Modbus checksum.
|
|
8
|
-
* Polynomial 0xA001, initial value 0xFFFF, right-shift algorithm.
|
|
9
|
-
*/
|
|
10
|
-
export declare function calculateCRC16(data: Uint8Array): number;
|
|
11
|
-
/** Convert CRC16 to 2-byte little-endian array. */
|
|
12
|
-
export declare function crc16ToBytes(crc16: number): Uint8Array;
|
|
13
|
-
/**
|
|
14
|
-
* Extract CRC16 from the last 2 bytes of a data buffer (little-endian).
|
|
15
|
-
* @throws if buffer is shorter than 2 bytes.
|
|
16
|
-
*/
|
|
17
|
-
export declare function extractCRC16(data: Uint8Array): number;
|
|
18
|
-
/**
|
|
19
|
-
* Get entropy length and description for a mnemonic type ID.
|
|
20
|
-
* @throws INVALID_CARD_DATA if the type ID is unknown.
|
|
21
|
-
*/
|
|
22
|
-
export declare function getMnemonicTypeInfo(typeId: number): {
|
|
23
|
-
entropyLength: number;
|
|
24
|
-
description: string;
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* Get type ID and description for a given entropy byte length.
|
|
28
|
-
* @throws UNSUPPORTED_MNEMONIC_LENGTH if the length is not recognized.
|
|
29
|
-
*/
|
|
30
|
-
export declare function getMnemonicTypeByEntropyLength(entropyLength: number): {
|
|
31
|
-
typeId: number;
|
|
32
|
-
description: string;
|
|
33
|
-
};
|
|
34
|
-
/**
|
|
35
|
-
* Validate whether raw card data contains a valid mnemonic payload.
|
|
36
|
-
* Checks type byte, length, and CRC16 — does NOT decode the mnemonic.
|
|
37
|
-
*
|
|
38
|
-
* @throws INVALID_CARD_DATA / EMPTY_CARD / CRC16_CHECK_FAILED
|
|
39
|
-
* @returns The mnemonic type description string.
|
|
40
|
-
*/
|
|
41
|
-
export declare function validateMnemonicPayload(data: Uint8Array): {
|
|
42
|
-
type: string;
|
|
43
|
-
};
|
package/dist/utils.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Pure utility functions – no NFC or platform dependencies.
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.bytesToHex = bytesToHex;
|
|
7
|
-
exports.hexToBytes = hexToBytes;
|
|
8
|
-
exports.calculateCRC16 = calculateCRC16;
|
|
9
|
-
exports.crc16ToBytes = crc16ToBytes;
|
|
10
|
-
exports.extractCRC16 = extractCRC16;
|
|
11
|
-
exports.getMnemonicTypeInfo = getMnemonicTypeInfo;
|
|
12
|
-
exports.getMnemonicTypeByEntropyLength = getMnemonicTypeByEntropyLength;
|
|
13
|
-
exports.validateMnemonicPayload = validateMnemonicPayload;
|
|
14
|
-
const constants_1 = require("./constants");
|
|
15
|
-
// ---------------------------------------------------------------------------
|
|
16
|
-
// Hex ↔ bytes
|
|
17
|
-
// ---------------------------------------------------------------------------
|
|
18
|
-
function bytesToHex(bytes) {
|
|
19
|
-
let hex = '';
|
|
20
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
21
|
-
hex += bytes[i].toString(16).padStart(2, '0');
|
|
22
|
-
}
|
|
23
|
-
return hex;
|
|
24
|
-
}
|
|
25
|
-
function hexToBytes(hex) {
|
|
26
|
-
const bytes = new Uint8Array(hex.length / 2);
|
|
27
|
-
for (let i = 0; i < hex.length; i += 2) {
|
|
28
|
-
bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);
|
|
29
|
-
}
|
|
30
|
-
return bytes;
|
|
31
|
-
}
|
|
32
|
-
// ---------------------------------------------------------------------------
|
|
33
|
-
// CRC16-Modbus
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
/**
|
|
36
|
-
* CRC16-Modbus checksum.
|
|
37
|
-
* Polynomial 0xA001, initial value 0xFFFF, right-shift algorithm.
|
|
38
|
-
*/
|
|
39
|
-
function calculateCRC16(data) {
|
|
40
|
-
let crc = 0xffff;
|
|
41
|
-
for (let i = 0; i < data.length; i++) {
|
|
42
|
-
crc ^= data[i];
|
|
43
|
-
for (let j = 0; j < 8; j++) {
|
|
44
|
-
if ((crc & 0x0001) !== 0) {
|
|
45
|
-
crc = (crc >> 1) ^ 0xa001;
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
crc = crc >> 1;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return crc & 0xffff;
|
|
53
|
-
}
|
|
54
|
-
/** Convert CRC16 to 2-byte little-endian array. */
|
|
55
|
-
function crc16ToBytes(crc16) {
|
|
56
|
-
return new Uint8Array([crc16 & 0xff, (crc16 >> 8) & 0xff]);
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Extract CRC16 from the last 2 bytes of a data buffer (little-endian).
|
|
60
|
-
* @throws if buffer is shorter than 2 bytes.
|
|
61
|
-
*/
|
|
62
|
-
function extractCRC16(data) {
|
|
63
|
-
if (data.length < 2) {
|
|
64
|
-
throw new Error('INVALID_CARD_DATA');
|
|
65
|
-
}
|
|
66
|
-
return data[data.length - 2] | (data[data.length - 1] << 8);
|
|
67
|
-
}
|
|
68
|
-
// ---------------------------------------------------------------------------
|
|
69
|
-
// Mnemonic type info
|
|
70
|
-
// ---------------------------------------------------------------------------
|
|
71
|
-
/** Mnemonic type info table: [typeId, entropyLength, description] */
|
|
72
|
-
const MNEMONIC_TYPE_TABLE = [
|
|
73
|
-
[constants_1.MNEMONIC_TYPE_12, 16, '12 words (128-bit)'],
|
|
74
|
-
[constants_1.MNEMONIC_TYPE_15, 20, '15 words (160-bit)'],
|
|
75
|
-
[constants_1.MNEMONIC_TYPE_18, 24, '18 words (192-bit)'],
|
|
76
|
-
[constants_1.MNEMONIC_TYPE_21, 28, '21 words (224-bit)'],
|
|
77
|
-
[constants_1.MNEMONIC_TYPE_24, 32, '24 words (256-bit)'],
|
|
78
|
-
];
|
|
79
|
-
/**
|
|
80
|
-
* Get entropy length and description for a mnemonic type ID.
|
|
81
|
-
* @throws INVALID_CARD_DATA if the type ID is unknown.
|
|
82
|
-
*/
|
|
83
|
-
function getMnemonicTypeInfo(typeId) {
|
|
84
|
-
const entry = MNEMONIC_TYPE_TABLE.find(([id]) => id === typeId);
|
|
85
|
-
if (!entry)
|
|
86
|
-
throw new Error('INVALID_CARD_DATA');
|
|
87
|
-
return { entropyLength: entry[1], description: entry[2] };
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Get type ID and description for a given entropy byte length.
|
|
91
|
-
* @throws UNSUPPORTED_MNEMONIC_LENGTH if the length is not recognized.
|
|
92
|
-
*/
|
|
93
|
-
function getMnemonicTypeByEntropyLength(entropyLength) {
|
|
94
|
-
const entry = MNEMONIC_TYPE_TABLE.find(([, len]) => len === entropyLength);
|
|
95
|
-
if (!entry)
|
|
96
|
-
throw new Error('UNSUPPORTED_MNEMONIC_LENGTH');
|
|
97
|
-
return { typeId: entry[0], description: entry[2] };
|
|
98
|
-
}
|
|
99
|
-
// ---------------------------------------------------------------------------
|
|
100
|
-
// Mnemonic payload validation
|
|
101
|
-
// ---------------------------------------------------------------------------
|
|
102
|
-
/**
|
|
103
|
-
* Validate whether raw card data contains a valid mnemonic payload.
|
|
104
|
-
* Checks type byte, length, and CRC16 — does NOT decode the mnemonic.
|
|
105
|
-
*
|
|
106
|
-
* @throws INVALID_CARD_DATA / EMPTY_CARD / CRC16_CHECK_FAILED
|
|
107
|
-
* @returns The mnemonic type description string.
|
|
108
|
-
*/
|
|
109
|
-
function validateMnemonicPayload(data) {
|
|
110
|
-
if (data.length < 19)
|
|
111
|
-
throw new Error('INVALID_CARD_DATA');
|
|
112
|
-
if (data.every(b => b === 0))
|
|
113
|
-
throw new Error('EMPTY_CARD');
|
|
114
|
-
const { entropyLength, description } = getMnemonicTypeInfo(data[0]);
|
|
115
|
-
const expectedTotal = 1 + entropyLength + 2;
|
|
116
|
-
if (data.length < expectedTotal)
|
|
117
|
-
throw new Error('INVALID_CARD_DATA');
|
|
118
|
-
const dataBlock = data.slice(0, 1 + entropyLength);
|
|
119
|
-
const storedCRC = extractCRC16(data.slice(1 + entropyLength, expectedTotal));
|
|
120
|
-
const calcCRC = calculateCRC16(dataBlock);
|
|
121
|
-
if (storedCRC !== calcCRC)
|
|
122
|
-
throw new Error('CRC16_CHECK_FAILED');
|
|
123
|
-
return { type: description };
|
|
124
|
-
}
|
package/dist/writer.d.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* NFC Writer Module
|
|
3
|
-
*
|
|
4
|
-
* Public API:
|
|
5
|
-
* - initializeCard() – write mnemonic + set password on a blank card
|
|
6
|
-
* - updateCard() – update mnemonic & password (old password required)
|
|
7
|
-
* - updatePassword() – change password only
|
|
8
|
-
* - writeUserNickname() – write user nickname (password required)
|
|
9
|
-
* - resetCard() – wipe card and set password to "000000"
|
|
10
|
-
*
|
|
11
|
-
* Based on MIFARE Ultralight AES (MF0AES(H)20) datasheet.
|
|
12
|
-
*/
|
|
13
|
-
import { NfcStatusCode, type NfcResult } from './types';
|
|
14
|
-
import { isNfcOperationLocked, releaseNfcOperationLock } from './nfc-core';
|
|
15
|
-
export { NfcStatusCode, type NfcResult, isNfcOperationLocked, releaseNfcOperationLock };
|
|
16
|
-
/**
|
|
17
|
-
* Initialize a card: authenticate with the default password, then write
|
|
18
|
-
* mnemonic and set a new password.
|
|
19
|
-
*
|
|
20
|
-
* @param mnemonic BIP-39 mnemonic to write.
|
|
21
|
-
* @param newPassword Password to protect the card with after initialization.
|
|
22
|
-
* @param defaultPassword Current (factory-default) password on the card.
|
|
23
|
-
*/
|
|
24
|
-
export declare function initializeCard(mnemonic: string, newPassword: string, defaultPassword: string, onCardIdentified?: () => void): Promise<NfcResult>;
|
|
25
|
-
/**
|
|
26
|
-
* Update card: authenticate with old password, then write new mnemonic + new password.
|
|
27
|
-
*
|
|
28
|
-
* When `options.precheckExistingMnemonic` is true, the card is read after authentication.
|
|
29
|
-
* If a valid mnemonic backup already exists, the write is skipped and PRECHECK_HAS_BACKUP
|
|
30
|
-
* is returned (`success: true` — operation completed; distinguish outcome by `code`).
|
|
31
|
-
* Otherwise the normal write flow proceeds.
|
|
32
|
-
*/
|
|
33
|
-
export declare function updateCard(oldPassword: string, newPassword: string, newMnemonic: string, onCardIdentified?: () => void, options?: {
|
|
34
|
-
precheckExistingMnemonic?: boolean;
|
|
35
|
-
}): Promise<NfcResult>;
|
|
36
|
-
/** Change password only (old password required). */
|
|
37
|
-
export declare function updatePassword(oldPassword: string, newPassword: string, onCardIdentified?: () => void): Promise<NfcResult>;
|
|
38
|
-
/** Write a user nickname (password required for authentication). */
|
|
39
|
-
export declare function writeUserNickname(password: string, nickname: string, onCardIdentified?: () => void): Promise<NfcResult>;
|
|
40
|
-
/**
|
|
41
|
-
* Reset card: wipe mnemonic data and set a new password.
|
|
42
|
-
* @param password – current card password (required if protection is enabled).
|
|
43
|
-
* @param newPassword – password to set after reset.
|
|
44
|
-
* @param onCardIdentified – callback when card is identified.
|
|
45
|
-
*/
|
|
46
|
-
export declare function resetCard(password: string | undefined, newPassword: string, onCardIdentified?: () => void): Promise<NfcResult>;
|