{"id":26045814,"url":"https://github.com/somq/nfccard-tool","last_synced_at":"2025-04-10T11:43:26.819Z","repository":{"id":51542680,"uuid":"114557095","full_name":"somq/nfccard-tool","owner":"somq","description":"💳 🛠️ The missing toolbox for reading and writing NFC cards","archived":false,"fork":false,"pushed_at":"2018-10-26T15:43:09.000Z","size":1363,"stargazers_count":24,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-24T10:38:50.815Z","etag":null,"topics":["javascript","ndef","nfc","nodejs","ntag"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/somq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-12-17T17:55:25.000Z","updated_at":"2024-12-28T06:56:56.000Z","dependencies_parsed_at":"2022-08-22T05:01:27.522Z","dependency_job_id":null,"html_url":"https://github.com/somq/nfccard-tool","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/somq%2Fnfccard-tool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/somq%2Fnfccard-tool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/somq%2Fnfccard-tool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/somq%2Fnfccard-tool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/somq","download_url":"https://codeload.github.com/somq/nfccard-tool/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248212208,"owners_count":21065923,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","ndef","nfc","nodejs","ntag"],"created_at":"2025-03-07T20:48:21.108Z","updated_at":"2025-04-10T11:43:26.793Z","avatar_url":"https://github.com/somq.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nfccard-tool\n\n\n\u003e The toolbox for reading and writing nfc cards.\n\u003e Parse card header, ndef message and records, prepare ndef records for writing...\n\n## Table of Contents\n\n* [Install](#install)\n* [Features](#features)\n* [Quick start examples](#quick-start-examples-with-the-help-of-nfc-pcsc)\n* [Usage](#usage)\n  * [1 - Require the lib:](#1---require-the-lib)\n  * [2 - Parse a card header:](#2---parse-a-card-header)\n  * [3 - Parse a NDEF message:](#3---parse-a-ndef-message)\n  * [4 - Prepare a NDEF message:](#4---prepare-a-ndef-message)\n* [API](#api)\n  * [Methods](#methods)\n  * [tag object](#tag-object)\n* [Troubleshoot](#troubleshoot)\n* [Third party](#thirdparty)\n* [License](#license)\n\n\n## Install\n\n[npm](https://www.npmjs.com/):\n\n```sh\nnpm install nfccard-tool --save\n```\n\n[yarn](https://yarnpkg.com/):\n\n```sh\nyarn add nfccard-tool --save\n```\n\n## Features\n\n* Parse a card header and wrap raw and human readable data in a object:\n  * Locks states\n  * Capability Container\n    * Magic number\n    * Spec version\n    * Max NDEF length\n    * Read and write accesses\n  * NDEF message detection and length\n* Parse and prepare a NDEF message of types:\n  * Text\n  * Uri\n  * Android App Record\n\n\n## Quick start examples (with the help of [nfc-pcsc](https://github.com/pokusew/nfc-pcsc))\n### Read a card header and parse a NDEF message\n\n```\nnpm run read-nfcpcsc\n```\n### Write a NDEF message\n\n```\nnpm run write-nfcpcsc\n```\n\n## Usage\n### 1 - Require the lib:\n\n```js\nconst ndef = require('nfccard-tool');\n```\n\n### 2 - Parse a card header:\n\nWith the card reader of your choice, read from block 0 until end of block 4. Which means a 20 bytes long read.\n\n\u003e Note: before any NDEF parsing or preparing we need to parse the card header first using a **read** command.\n\n```js\n// Starts reading in block 0 for 20 bytes long\nconst cardHeader = await reader.read(0, 20);\n\nconst tag = nfcCard.parseInfo(cardHeader);\nconsole.log('tag info:', JSON.stringify(tag));\n```\nWhich logs:\n```json\ntag info:\n{\n    \"headerValues\":{\n        \"raw\":{\n            \"Lock\":{\n                \"LOCK0\":0,\n                \"LOCK1\":0\n            },\n            \"capabilityContainer\":{\n                \"MAGIC_NUMBER\":225,\n                \"SPEC_VERSION\":16,\n                \"MAX_NDEF_LENGTH\":109,\n                \"READ_ACCESS\":0,\n                \"WRITE_ACCESS\":0\n            },\n            \"NDEFMessageHeader\":{\n                \"HAS_NDEF\":3,\n                \"MESSAGE_LENGTH\":86\n            }\n        },\n        \"string\":{\n            \"Lock\":{\n                \"LOCK0\":\"0\",\n                \"LOCK1\":\"0\"\n            },\n            \"capabilityContainer\":{\n                \"MAGIC_NUMBER\":\"E1\",\n                \"SPEC_VERSION\":\"10\",\n                \"MAX_NDEF_LENGTH\":\"6D\",\n                \"READ_ACCESS\":\"0\",\n                \"WRITE_ACCESS\":\"0\"\n            },\n            \"NDEFMessageHeader\":{\n                \"HAS_NDEF\":\"3\",\n                \"MESSAGE_LENGTH\":\"56\"\n            }\n        }\n    },\n    \"parsedHeader\":{\n        \"isFormatedAsNDEF\":true,\n        \"type2SpecVersion\":\"1.0\",\n        \"maxNDEFMessageSize\":872,\n        \"hasReadPermissions\":true,\n        \"getReadPermissionsType\":\"HAS_READ_ACCESS\",\n        \"hasWritePermissions\":true,\n        \"writePermissionsType\":\"HAS_WRITE_ACCESS\",\n        \"hasNDEFMessage\":true,\n        \"NDEFMessageLength\":86,\n        \"lengthToReadFromBlock4\":88\n    }\n\n}\n```\n\n### 3 - Parse a NDEF message:\n\u003e If card header parsing let us know *there might be* a NDEF message we can try to parse it:\n\n```js\n// There might be a NDEF message and we are able to read the tag\nif(nfcCard.isFormatedAsNDEF() \u0026\u0026 nfcCard.hasReadPermissions() \u0026\u0026 nfcCard.hasNDEFMessage()) {\n\n  // Read the appropriate length to get the NDEF message as buffer\n  const NDEFRawMessage = await reader.read(4, nfcCard.getNDEFMessageLengthToRead()); // starts reading in block 0 until 6\n\n  // Parse the buffer as a NDEF raw message\n  const NDEFMessage = nfcCard.parseNDEF(NDEFRawMessage);\n\n  console.log('NDEFMessage:', NDEFMessage);\n\n} else {\n  console.log('Could not parse anything from this tag: \\n The tag is either empty, locked, has a wrong NDEF format or is unreadable.')\n}\n```\n\n### 4 - Prepare a NDEF message:\n\u003e We can use the convenient method *prepareBytesToWrite* to get the appropriate Buffer we need to write a ndef message.\n```js\n// 1 - READ HEADER\n\n// Starts reading in block 0 until end of block 4\nconst cardHeader = await reader.read(0, 20);\n\nconst tag = nfcCard.parseInfo(cardHeader);\nconsole.log('tag info:', JSON.stringify(tag));\n\n\n// 2 - WRITE A NDEF MESSAGE AND ITS RECORDS\n\nconst message = [\n  { type: 'text', text: 'I\\'m a text message', language: 'en' },\n  { type: 'uri', uri: 'https://github.com/somq' },\n  { type: 'aar', packageName: 'https://github.com/somq' },\n]\n\n// Prepare the buffer to write on the card\nconst rawDataToWrite = nfcCard.prepareBytesToWrite(message);\n\n// Write the buffer on the card starting at block 4\nconst preparationWrite = await reader.write(4, rawDataToWrite.preparedData);\n\n// Success !\nif (preparationWrite) {\n  console.log('Data have been written successfully.')\n}\n```\nWhich logs:\n```js\nNDEFMessage:\n[\n  { NDEFLibRecord:\n     { LanguageCode: null,\n       text: null,\n       _typeNameFormat: 1,\n       _type: [Array],\n       _id: [],\n       _payload: [Array] },\n    type: 'text',\n    text: 'I\\'m a text message',\n    language: 'en' },\n  { NDEFLibRecord:\n     { RawUri: [],\n       Uri: '',\n       _typeNameFormat: 1,\n       _type: [Array],\n       _id: [],\n       _payload: [Array],\n       type: 'U' },\n    type: 'uri',\n    uri: 'https://github.com/somq' },\n  { NDEFLibRecord:\n     { packageName: '',\n       _typeNameFormat: 4,\n       _type: [Array],\n       _id: [],\n       _payload: [Array],\n       type: 'android.com:pkg' },\n    type: 'aar',\n    packageName: 'https://github.com/somq' }\n]\n```\n---\n\n## API\n\n### Methods\n```js\n// Magic number\nnfcCard.isFormatedAsNDEF();\n\n// Type 2 Tag Specification version, eg. 1.0\nnfcCard.getType2SpecVersion();\n\n// Max NDEF size for the current tag\nnfcCard.getMaxNDEFMessageLength();\n\n// Read locked ?\nnfcCard.hasReadPermissions();\n\n// Read types: HAS_READ_ACCESS, RFU, PROPRIETARY, UNKNOWN\nnfcCard.getReadPermissionsType();\n\n// Write locked ?\nnfcCard.hasWritePermissions();\n\n// Write types: HAS_READ_ACCESS, RFU, PROPRIETARY, UNKNOWN\nnfcCard.getWritePermissionsType();\n\n// NDEF message flag is present ?\nnfcCard.hasNDEFMessage();\n\n// NDEF message length on exists on the tag\nnfcCard.getNDEFMessageLength();\n\n```\n### tag *object*\n\n```js\n{\n    \"headerValues\":{\n        \"raw\":{ // Raw buffer values\n            \"Lock\":{\n                \"LOCK0\":0, // Lock 0 status - block 2, byte 2\n                \"LOCK1\":0 // Lock 1 status - block 2, byte 3\n            },\n            \"capabilityContainer\":{\n                \"MAGIC_NUMBER\":225, // magic number - block 3, byte 0 (CC0)\n                \"SPEC_VERSION\":16, // type 2 spec version - block 3, byte 1 (CC1)\n                \"MAX_NDEF_LENGTH\":109, // max ndef message length - block 3, byte 2 (CC2)\n                \"READ_ACCESS\":0, // read access - block 3, byte 3 (CC3)\n                \"WRITE_ACCESS\":0 // write access - block 3, byte 3 (CC3)\n            },\n            \"NDEFMessageHeader\":{\n                \"HAS_NDEF\":3, // NDEF header 0 - block 4, byte 0\n                \"MESSAGE_LENGTH\":86 // NDEF header 1 - block 4, byte 1\n            }\n        },\n        \"string\":{ // Hex string values\n            \"Lock\":{\n                \"LOCK0\":\"0\",\n                \"LOCK1\":\"0\"\n            },\n            \"capabilityContainer\":{\n                \"MAGIC_NUMBER\":\"E1\",\n                \"SPEC_VERSION\":\"10\",\n                \"MAX_NDEF_LENGTH\":\"6D\",\n                \"READ_ACCESS\":\"0\",\n                \"WRITE_ACCESS\":\"0\"\n            },\n            \"NDEFMessageHeader\":{\n                \"HAS_NDEF\":\"3\",\n                \"MESSAGE_LENGTH\":\"56\"\n            }\n        }\n    },\n    \"parsedHeader\":{\n        \"isFormatedAsNDEF\":true, // magic number - block 3, byte 0 (CC0)\n        \"type2SpecVersion\":\"1.0\", // type 2 spec version - block 3, byte 1 (CC1)\n        \"maxNDEFMessageSize\":872, // max ndef message length - block 3, byte 2\n        \"hasReadPermissions\":true, // read access - block 3, byte 3 (CC3)\n        \"getReadPermissionsType\":\"HAS_READ_ACCESS\",\n        \"hasWritePermissions\":true, // write access - block 3, byte 3 (CC3)\n        \"writePermissionsType\":\"HAS_WRITE_ACCESS\",\n        \"hasNDEFMessage\":true, // NDEF header 0 - block 4, byte 0\n        \"NDEFMessageLength\":86, // NDEF header 1 - block 4, byte 1\n        \"lengthToReadFromBlock4\":88 // NDEFMessageLength + 2\n    }\n\n}\n```\n\n## Compatibility\n\nOnly a part of [Type 2 tag specification](docs/NFCForum-TS-Type-2-Tag_1.1.pdf) is implemented.\n\nThis lib does not support yet:\n* Dynamical memory structure\n* Lock preparing\n* *... some are probably missing*\n\n## Troubleshoot\n\u003eError: *path*\\node_modules\\@pokusew\\pcsclite\\build\\Release\\ **pcsclite.node**\n\n```\nnpm rebuild\n```\n\n## Third party\nWe are natively using [ndef-lib](https://github.com/somq/ndef-lib) for parsing but you could give a try at https://github.com/TapTrack/NdefJS or have a deep look at https://github.com/googlearchive/chrome-nfc\n\nIf you are looking for a nfc tag reading library take a look at https://github.com/pokusew/nfc-pcsc\n\n\n\n## License\n\n[MIT](LICENSE) © somq\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsomq%2Fnfccard-tool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsomq%2Fnfccard-tool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsomq%2Fnfccard-tool/lists"}