@cryptag/sdk 2.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/LICENSE +140 -0
- package/README.md +262 -0
- package/cryptag.js +16 -0
- package/package.json +56 -0
- package/types/cryptag.d.ts +8 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
Required Notice: Copyright 2026 Serdar Tepekule
|
|
2
|
+
https://github.com/serdartpkl/cryptag
|
|
3
|
+
|
|
4
|
+
CrypTag is free for noncommercial use under the PolyForm Noncommercial
|
|
5
|
+
License 1.0.0, reproduced in full below. Commercial use requires a separate
|
|
6
|
+
commercial license — to arrange one, open an issue at the repository above.
|
|
7
|
+
|
|
8
|
+
================================================================================
|
|
9
|
+
|
|
10
|
+
# PolyForm Noncommercial License 1.0.0
|
|
11
|
+
|
|
12
|
+
<https://polyformproject.org/licenses/noncommercial/1.0.0>
|
|
13
|
+
|
|
14
|
+
## Acceptance
|
|
15
|
+
|
|
16
|
+
In order to get any license under these terms, you must agree
|
|
17
|
+
to them as both strict obligations and conditions to all
|
|
18
|
+
your licenses.
|
|
19
|
+
|
|
20
|
+
## Copyright License
|
|
21
|
+
|
|
22
|
+
The licensor grants you a copyright license for the
|
|
23
|
+
software to do everything you might do with the software
|
|
24
|
+
that would otherwise infringe the licensor's copyright
|
|
25
|
+
in it for any permitted purpose. However, you may
|
|
26
|
+
only distribute the software according to [Distribution
|
|
27
|
+
License](#distribution-license) and make changes or new works
|
|
28
|
+
based on the software according to [Changes and New Works
|
|
29
|
+
License](#changes-and-new-works-license).
|
|
30
|
+
|
|
31
|
+
## Distribution License
|
|
32
|
+
|
|
33
|
+
The licensor grants you an additional copyright license
|
|
34
|
+
to distribute copies of the software. Your license
|
|
35
|
+
to distribute covers distributing the software with
|
|
36
|
+
changes and new works permitted by [Changes and New Works
|
|
37
|
+
License](#changes-and-new-works-license).
|
|
38
|
+
|
|
39
|
+
## Notices
|
|
40
|
+
|
|
41
|
+
You must ensure that anyone who gets a copy of any part of
|
|
42
|
+
the software from you also gets a copy of these terms or the
|
|
43
|
+
URL for them above, as well as copies of any plain-text lines
|
|
44
|
+
beginning with `Required Notice:` that the licensor provided
|
|
45
|
+
with the software. For example:
|
|
46
|
+
|
|
47
|
+
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
48
|
+
|
|
49
|
+
## Changes and New Works License
|
|
50
|
+
|
|
51
|
+
The licensor grants you an additional copyright license to
|
|
52
|
+
make changes and new works based on the software for any
|
|
53
|
+
permitted purpose.
|
|
54
|
+
|
|
55
|
+
## Patent License
|
|
56
|
+
|
|
57
|
+
The licensor grants you a patent license for the software that
|
|
58
|
+
covers patent claims the licensor can license, or becomes able
|
|
59
|
+
to license, that you would infringe by using the software.
|
|
60
|
+
|
|
61
|
+
## Noncommercial Purposes
|
|
62
|
+
|
|
63
|
+
Any noncommercial purpose is a permitted purpose.
|
|
64
|
+
|
|
65
|
+
## Personal Uses
|
|
66
|
+
|
|
67
|
+
Personal use for research, experiment, and testing for
|
|
68
|
+
the benefit of public knowledge, personal study, private
|
|
69
|
+
entertainment, hobby projects, amateur pursuits, or religious
|
|
70
|
+
observance, without any anticipated commercial application,
|
|
71
|
+
is use for a permitted purpose.
|
|
72
|
+
|
|
73
|
+
## Noncommercial Organizations
|
|
74
|
+
|
|
75
|
+
Use by any charitable organization, educational institution,
|
|
76
|
+
public research organization, public safety or health
|
|
77
|
+
organization, environmental protection organization,
|
|
78
|
+
or government institution is use for a permitted purpose
|
|
79
|
+
regardless of the source of funding or obligations resulting
|
|
80
|
+
from the funding.
|
|
81
|
+
|
|
82
|
+
## Fair Use
|
|
83
|
+
|
|
84
|
+
You may have "fair use" rights for the software under the
|
|
85
|
+
law. These terms do not limit them.
|
|
86
|
+
|
|
87
|
+
## No Other Rights
|
|
88
|
+
|
|
89
|
+
These terms do not allow you to sublicense or transfer any of
|
|
90
|
+
your licenses to anyone else, or prevent the licensor from
|
|
91
|
+
granting licenses to anyone else. These terms do not imply
|
|
92
|
+
any other licenses.
|
|
93
|
+
|
|
94
|
+
## Patent Defense
|
|
95
|
+
|
|
96
|
+
If you make any written claim that the software infringes or
|
|
97
|
+
contributes to infringement of any patent, your patent license
|
|
98
|
+
for the software granted under these terms ends immediately. If
|
|
99
|
+
your company makes such a claim, your patent license ends
|
|
100
|
+
immediately for work on behalf of your company.
|
|
101
|
+
|
|
102
|
+
## Violations
|
|
103
|
+
|
|
104
|
+
The first time you are notified in writing that you have
|
|
105
|
+
violated any of these terms, or done anything with the software
|
|
106
|
+
not covered by your licenses, your licenses can nonetheless
|
|
107
|
+
continue if you come into full compliance with these terms,
|
|
108
|
+
and take practical steps to correct past violations, within
|
|
109
|
+
32 days of receiving notice. Otherwise, all your licenses
|
|
110
|
+
end immediately.
|
|
111
|
+
|
|
112
|
+
## No Liability
|
|
113
|
+
|
|
114
|
+
***As far as the law allows, the software comes as is, without
|
|
115
|
+
any warranty or condition, and the licensor will not be liable
|
|
116
|
+
to you for any damages arising out of these terms or the use
|
|
117
|
+
or nature of the software, under any kind of legal claim.***
|
|
118
|
+
|
|
119
|
+
## Definitions
|
|
120
|
+
|
|
121
|
+
The **licensor** is the individual or entity offering these
|
|
122
|
+
terms, and the **software** is the software the licensor makes
|
|
123
|
+
available under these terms.
|
|
124
|
+
|
|
125
|
+
**You** refers to the individual or entity agreeing to these
|
|
126
|
+
terms.
|
|
127
|
+
|
|
128
|
+
**Your company** is any legal entity, sole proprietorship,
|
|
129
|
+
or other kind of organization that you work for, plus all
|
|
130
|
+
organizations that have control over, are under the control of,
|
|
131
|
+
or are under common control with that organization. **Control**
|
|
132
|
+
means ownership of substantially all the assets of an entity,
|
|
133
|
+
or the power to direct its management and policies by vote,
|
|
134
|
+
contract, or otherwise. Control can be direct or indirect.
|
|
135
|
+
|
|
136
|
+
**Your licenses** are all the licenses granted to you for the
|
|
137
|
+
software under these terms.
|
|
138
|
+
|
|
139
|
+
**Use** means anything you do with the software requiring one
|
|
140
|
+
of your licenses.
|
package/README.md
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="cryptag-logo.png" alt="CrypTag" width="320">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/@cryptag/sdk"><img src="https://img.shields.io/npm/v/@cryptag/sdk.svg" alt="npm version"></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/@cryptag/sdk"><img src="https://img.shields.io/node/v/@cryptag/sdk.svg" alt="node version"></a>
|
|
8
|
+
<a href="https://github.com/serdartpkl/cryptag/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-PolyForm%20Noncommercial-blue.svg" alt="PolyForm Noncommercial license"></a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
**CrypTag** is a complete NTAG424 DNA toolkit: one half **programs** tags over a contactless
|
|
14
|
+
reader, the other **verifies** the tap output they produce — sharing the same cryptographic
|
|
15
|
+
core and a single, structured error model.
|
|
16
|
+
|
|
17
|
+
- **Encoder** (`@cryptag/encoder`) — talk to a tag over a PC/SC reader: discover, authenticate
|
|
18
|
+
(EV2 & LRP), read/write files, configure SDM profiles, and manage keys (AN10922 diversification).
|
|
19
|
+
- **Decoder** (`@cryptag/decoder`) — verify the SDM URL/token a tag produces (plain, encrypted and
|
|
20
|
+
full). No hardware required.
|
|
21
|
+
|
|
22
|
+
`@cryptag/sdk` is the umbrella package that re-exports both. `@cryptag/crypto` (primitives) and
|
|
23
|
+
`@cryptag/common` (error model and validation) are shared internals.
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
import { CrypTagEncoder, CrypTagDecoder } from '@cryptag/sdk';
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
> 📖 You can find detailed documentation on [cryptag.io](https://cryptag.io).
|
|
30
|
+
|
|
31
|
+
## Packages
|
|
32
|
+
|
|
33
|
+
| Package | Role |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `@cryptag/sdk` | Umbrella — re-exports `CrypTagEncoder` + `CrypTagDecoder` |
|
|
36
|
+
| `@cryptag/encoder` | Tag programming over PC/SC |
|
|
37
|
+
| `@cryptag/decoder` | SDM URL/token verification |
|
|
38
|
+
| `@cryptag/crypto` | Shared AES/LRP/CMAC/diversification primitives |
|
|
39
|
+
| `@cryptag/common` | Shared error model and argument validation |
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install @cryptag/sdk
|
|
45
|
+
# …or just one half:
|
|
46
|
+
npm install @cryptag/encoder
|
|
47
|
+
npm install @cryptag/decoder
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> The encoder needs a **PC/SC contactless reader**. Its native binding (`nfc-pcsc` →
|
|
51
|
+
> `@pokusew/pcsclite`) is compiled on install. If you switch Node versions, rebuild it with
|
|
52
|
+
> `npm run rebuild`. For **Electron**, build it for the Electron ABI with `npm run rebuild:electron`
|
|
53
|
+
> (defaults to Electron 26; pass a version with `npm run rebuild:electron -- 28.2.0`).
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
A tag carries its SDM data in one of two NDEF records: a **URL** (the chip emits a
|
|
58
|
+
browser-openable link with the `picc_data`/`enc`/`cmac` query params) or a **text**
|
|
59
|
+
record (a JSON blob your own app reads). The cryptography is identical — only the container
|
|
60
|
+
differs, and `readNDEF` parses both into the same `sdmParams.params` (including the
|
|
61
|
+
`cmacSeparator` the tag needs), so the decode call is the same for both.
|
|
62
|
+
|
|
63
|
+
### URL Record
|
|
64
|
+
|
|
65
|
+
Program a tag, read back the URL it emits, then verify that tap on your backend:
|
|
66
|
+
|
|
67
|
+
```js
|
|
68
|
+
import { CrypTagEncoder, CrypTagDecoder } from '@cryptag/sdk';
|
|
69
|
+
|
|
70
|
+
const encoder = new CrypTagEncoder();
|
|
71
|
+
await encoder.connect();
|
|
72
|
+
|
|
73
|
+
// 'full' = encrypted PICC data + encrypted file data + CMAC. encodeTag discovers
|
|
74
|
+
// the tag and authenticates with key 0 internally.
|
|
75
|
+
await encoder.encodeTag('full', {
|
|
76
|
+
ndefType: 'url', // 'url' or 'text'
|
|
77
|
+
url: 'https://cryptag.app/verify',
|
|
78
|
+
fileData: 'HELLO-FROM-CRYPTAG',// plain string encrypted into every tap
|
|
79
|
+
encSize: 128, // enc field length in hex chars (32/64/128)
|
|
80
|
+
counterLimit: 3000, // SDM tap counter stops after 3000 taps
|
|
81
|
+
resetCounter: true, // reset the counter to zero before encoding
|
|
82
|
+
enableTTStatus: false, // TagTamper status mirroring (TagTamper variant only)
|
|
83
|
+
compressed: false, // shorter URLs without parameter names
|
|
84
|
+
sdmSettings: null, // advanced SDM access-right override
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// encodeTag already re-discovered the new SDM config, so readNDEF sees it: the
|
|
88
|
+
// chip fills the placeholders live and readNDEF parses them into separate fields.
|
|
89
|
+
const ndef = await encoder.readNDEF();
|
|
90
|
+
await encoder.disconnect();
|
|
91
|
+
|
|
92
|
+
const sdm = ndef.data.sdmParams.params; // { picc_data, enc, cmac, cmacSeparator } — ready for decodeFull
|
|
93
|
+
|
|
94
|
+
// Verify and decode on your backend (no hardware).
|
|
95
|
+
const decoder = new CrypTagDecoder({
|
|
96
|
+
keyList: { // keys must match the tag (factory = all-zero)
|
|
97
|
+
'2': { masterKey: '00000000000000000000000000000000', diversify: false },
|
|
98
|
+
'3': { masterKey: '00000000000000000000000000000000', diversify: false },
|
|
99
|
+
},
|
|
100
|
+
sdmSettings: { sdmMetaRead: 2, sdmFileRead: 3 },
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const out = decoder.decodeFull(sdm); // sdm.cmacSeparator wires the MAC input automatically
|
|
104
|
+
if (out.success && out.data.cmacValid) {
|
|
105
|
+
console.log('authentic tap →', { uid: out.data.uid, counter: out.data.counter, file: out.data.fileData });
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`readNDEF` also hands you the full link at `ndef.data.url`.
|
|
110
|
+
|
|
111
|
+
### Text Record
|
|
112
|
+
|
|
113
|
+
Same `full` profile, but written as a JSON text record instead of a URL — drop `url`, set
|
|
114
|
+
`ndefType: 'text'`. SDM builds the JSON itself, and the decode side is identical:
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
import { CrypTagEncoder, CrypTagDecoder } from '@cryptag/sdk';
|
|
118
|
+
|
|
119
|
+
const encoder = new CrypTagEncoder();
|
|
120
|
+
await encoder.connect();
|
|
121
|
+
|
|
122
|
+
// 'full' = encrypted PICC data + encrypted file data + CMAC. encodeTag discovers
|
|
123
|
+
// the tag and authenticates with key 0 internally.
|
|
124
|
+
await encoder.encodeTag('full', {
|
|
125
|
+
ndefType: 'text', // JSON text record instead of a URL
|
|
126
|
+
fileData: 'HELLO-FROM-CRYPTAG',// plain string encrypted into every tap
|
|
127
|
+
encSize: 128, // enc field length in hex chars (32/64/128)
|
|
128
|
+
counterLimit: 3000, // SDM tap counter stops after 3000 taps
|
|
129
|
+
resetCounter: true, // reset the counter to zero before encoding
|
|
130
|
+
enableTTStatus: false, // TagTamper status mirroring (TagTamper variant only)
|
|
131
|
+
compressed: false, // shorter token instead of named fields
|
|
132
|
+
sdmSettings: null, // advanced SDM access-right override
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// encodeTag already re-discovered the new SDM config, so readNDEF sees it: the
|
|
136
|
+
// chip fills the placeholders live and readNDEF parses them into separate fields.
|
|
137
|
+
const ndef = await encoder.readNDEF();
|
|
138
|
+
await encoder.disconnect();
|
|
139
|
+
|
|
140
|
+
const sdm = ndef.data.sdmParams.params; // same shape (incl. cmacSeparator) as the URL case
|
|
141
|
+
|
|
142
|
+
// Verify and decode on your backend (no hardware).
|
|
143
|
+
const decoder = new CrypTagDecoder({
|
|
144
|
+
keyList: { // keys must match the tag (factory = all-zero)
|
|
145
|
+
'2': { masterKey: '00000000000000000000000000000000', diversify: false },
|
|
146
|
+
'3': { masterKey: '00000000000000000000000000000000', diversify: false },
|
|
147
|
+
},
|
|
148
|
+
sdmSettings: { sdmMetaRead: 2, sdmFileRead: 3 },
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const out = decoder.decodeFull(sdm); // identical to the URL example
|
|
152
|
+
if (out.success && out.data.cmacValid) {
|
|
153
|
+
console.log('authentic tap →', { uid: out.data.uid, counter: out.data.counter, file: out.data.fileData });
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`readNDEF` hands you the raw record at `ndef.data.text` (e.g. `{"picc_data":"…","enc":"…","cmac":"…"}`).
|
|
158
|
+
|
|
159
|
+
## Commands
|
|
160
|
+
|
|
161
|
+
NTAG424 DNA commands implemented, by communication mode. The full per-method API (encoder +
|
|
162
|
+
decoder), with examples, lives in the **[documentation](https://cryptag.io)**.
|
|
163
|
+
|
|
164
|
+
**Authentication (4 Commands)**
|
|
165
|
+
- EV2First
|
|
166
|
+
- LRPFirst
|
|
167
|
+
- EV2NonFirst
|
|
168
|
+
- LRPNonFirst
|
|
169
|
+
|
|
170
|
+
**Plain Mode (10 Commands)**
|
|
171
|
+
- GetFileSettings
|
|
172
|
+
- ChangeFileSettings
|
|
173
|
+
- GetFileCounters
|
|
174
|
+
- GetVersion
|
|
175
|
+
- ISOReadBinary
|
|
176
|
+
- ISOSelectFile
|
|
177
|
+
- ISOUpdateBinary
|
|
178
|
+
- ReadData
|
|
179
|
+
- WriteData
|
|
180
|
+
- ReadSig
|
|
181
|
+
|
|
182
|
+
**MAC Mode (7 Commands)**
|
|
183
|
+
- GetFileSettings
|
|
184
|
+
- ChangeFileSettings
|
|
185
|
+
- GetFileCounters
|
|
186
|
+
- GetKeyVersion
|
|
187
|
+
- GetVersion
|
|
188
|
+
- ReadData
|
|
189
|
+
- WriteData
|
|
190
|
+
|
|
191
|
+
**Full Mode (11 Commands)**
|
|
192
|
+
- ChangeKey
|
|
193
|
+
- ChangeKey0
|
|
194
|
+
- ChangeFileSettings
|
|
195
|
+
- GetCardUID
|
|
196
|
+
- GetFileCounters
|
|
197
|
+
- ReadData
|
|
198
|
+
- WriteData
|
|
199
|
+
- ReadSig
|
|
200
|
+
- SetConfiguration (FailedCtr)
|
|
201
|
+
- SetConfiguration (RandomID)
|
|
202
|
+
- SetConfiguration (LRP)
|
|
203
|
+
|
|
204
|
+
**Total: 37 commands** (some appear in multiple communication modes with distinct implementations).
|
|
205
|
+
|
|
206
|
+
## Results and Errors
|
|
207
|
+
|
|
208
|
+
**Both halves** return the same result shape (`duration` in ms is added on encoder tag operations):
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
{ success: true, data: { /* method-specific */ }, duration: 12 }
|
|
212
|
+
{ success: false, error: { code, message, details? } }
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
For the **decoder**, `data` holds `{ cmacValid, uid, counter, … }`. `success: true` means the decode
|
|
216
|
+
ran — **authenticity is `data.cmacValid`**, so always check it (a tap can decode cleanly yet still fail
|
|
217
|
+
CMAC verification). A hard failure (bad input or a decode error) returns `{ success: false, error }`.
|
|
218
|
+
|
|
219
|
+
`error.code` is shared across both halves:
|
|
220
|
+
|
|
221
|
+
| Code | Category | When it happens |
|
|
222
|
+
|---|---|---|
|
|
223
|
+
| `E100` | Connection | Reader, card, or transport problem (no reader, no card, discovery failed) |
|
|
224
|
+
| `E200` | Authentication | Wrong key, MAC mismatch, permission denied, or auth temporarily blocked |
|
|
225
|
+
| `E300` | Command | A tag command did not complete (select, read/write, change key/settings) |
|
|
226
|
+
| `E400` | Validation | Bad argument or configuration (encoder + decoder) |
|
|
227
|
+
| `E500` | Unknown | Unmapped/unexpected error |
|
|
228
|
+
| `E600` | Decoding | A decode could not be completed (decoder: malformed data or a key/config problem) |
|
|
229
|
+
|
|
230
|
+
When a failure originates at the tag, its ISO/NTAG424 status word (e.g. `911E`, `919D`, `91AE`) is
|
|
231
|
+
translated into one of the categories above with a descriptive `message`. A result's `error` is always
|
|
232
|
+
a **plain object** `{ code, message, details? }` — no stack, no class — so it logs and `JSON.stringify`s
|
|
233
|
+
identically. (Internally the SDK throws a `CrypTagError`, but that never leaks into a result.)
|
|
234
|
+
|
|
235
|
+
## How They Fit Together
|
|
236
|
+
|
|
237
|
+
`encodeTag()` configures a tag so that, on each tap, it emits a URL containing SDM placeholders
|
|
238
|
+
(`picc_data`, `enc`, `cmac`, …). Your backend parses those query parameters and passes them to the
|
|
239
|
+
matching decoder method (`decodePlain`/`decodeEncrypted`/`decodeFull`), which verifies the CMAC
|
|
240
|
+
and returns the UID, the tap counter, and — for the full profile — the decrypted file data.
|
|
241
|
+
|
|
242
|
+
## Requirements
|
|
243
|
+
|
|
244
|
+
- Node.js ≥ 14 (ES modules).
|
|
245
|
+
- Encoder only: a PC/SC contactless reader (e.g. ACR122U) and an NTAG424 DNA tag.
|
|
246
|
+
|
|
247
|
+
## Development
|
|
248
|
+
|
|
249
|
+
This is an npm-workspaces monorepo. From the repo root:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
npm install # install + link all workspaces
|
|
253
|
+
npm run types # type-check/emit .d.ts for all packages
|
|
254
|
+
npm run rebuild # rebuild the encoder's native binding for Node
|
|
255
|
+
npm run rebuild:electron # …or for the Electron ABI
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## License
|
|
259
|
+
|
|
260
|
+
[PolyForm Noncommercial License 1.0.0](LICENSE) © Serdar Tepekule.
|
|
261
|
+
|
|
262
|
+
Free for noncommercial use. **Commercial use requires a separate license** — open an issue on [GitHub](https://github.com/serdartpkl/cryptag) to arrange one.
|
package/cryptag.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @cryptag/sdk — umbrella package re-exporting the encoder and decoder.
|
|
3
|
+
*
|
|
4
|
+
* import { CrypTagEncoder, CrypTagDecoder } from '@cryptag/sdk';
|
|
5
|
+
*
|
|
6
|
+
* @cryptag/crypto is an internal dependency of the two and is intentionally
|
|
7
|
+
* NOT re-exported here.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { CrypTagEncoder } from '@cryptag/encoder';
|
|
11
|
+
import { CrypTagDecoder } from '@cryptag/decoder';
|
|
12
|
+
|
|
13
|
+
export { CrypTagEncoder, CrypTagDecoder };
|
|
14
|
+
|
|
15
|
+
/** @hidden */
|
|
16
|
+
export default { CrypTagEncoder, CrypTagDecoder };
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cryptag/sdk",
|
|
3
|
+
"version": "2.0.2",
|
|
4
|
+
"description": "CrypTag — NTAG424 DNA Toolkit",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "cryptag.js",
|
|
7
|
+
"types": "types/cryptag.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./cryptag.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"rebuild": "node scripts/rebuild.mjs",
|
|
13
|
+
"rebuild:electron": "node scripts/rebuild.mjs -e",
|
|
14
|
+
"types": "tsc -p packages/common/tsconfig.json && tsc -p packages/crypto/tsconfig.json && tsc -p packages/decoder/tsconfig.json && tsc -p packages/encoder/tsconfig.json && tsc -p tsconfig.json",
|
|
15
|
+
"docs": "npm run build --prefix docs",
|
|
16
|
+
"prepack": "node -e \"require('fs').rmSync('types',{recursive:true,force:true})\" && tsc -p tsconfig.json"
|
|
17
|
+
},
|
|
18
|
+
"workspaces": [
|
|
19
|
+
"packages/common",
|
|
20
|
+
"packages/crypto",
|
|
21
|
+
"packages/encoder",
|
|
22
|
+
"packages/decoder"
|
|
23
|
+
],
|
|
24
|
+
"keywords": [
|
|
25
|
+
"nfc",
|
|
26
|
+
"ntag424",
|
|
27
|
+
"sdm",
|
|
28
|
+
"lrp",
|
|
29
|
+
"ev2"
|
|
30
|
+
],
|
|
31
|
+
"author": "Serdar Tepekule",
|
|
32
|
+
"license": "PolyForm-Noncommercial-1.0.0",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/serdartpkl/cryptag.git"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://cryptag.io",
|
|
38
|
+
"bugs": "https://github.com/serdartpkl/cryptag/issues",
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=14.0.0"
|
|
44
|
+
},
|
|
45
|
+
"files": [
|
|
46
|
+
"cryptag.js",
|
|
47
|
+
"types/"
|
|
48
|
+
],
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@cryptag/decoder": "2.0.2",
|
|
51
|
+
"@cryptag/encoder": "2.0.2"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"typescript": "^6.0.3"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare namespace _default {
|
|
2
|
+
export { CrypTagEncoder };
|
|
3
|
+
export { CrypTagDecoder };
|
|
4
|
+
}
|
|
5
|
+
export default _default;
|
|
6
|
+
import { CrypTagEncoder } from '@cryptag/encoder';
|
|
7
|
+
import { CrypTagDecoder } from '@cryptag/decoder';
|
|
8
|
+
export { CrypTagEncoder, CrypTagDecoder };
|