Skip to content

Commit b26a27f

Browse files
committed
feat: initial release — TigerTag JavaScript SDK v1.0.0
Full port of the TigerTag Python SDK to native Node.js (CommonJS, no external runtime dependencies). Includes TigerTag / TigerTag+ / TigerTag Init parsing, ECDSA-P256 signature verification via Node.js built-in crypto, cloud API diff/patch, offline bundled databases, CLI, examples, Jest test suite (75 tests), fixture generator, GitHub Actions workflows, and interactive playground (Node.js server + HTML UI). Protocol: TigerTag Open Source v2.1 Spec: https://github.com/TigerTag-Project/TigerTag-RFID-Guide
0 parents  commit b26a27f

43 files changed

Lines changed: 9721 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Bug report
2+
description: Something doesn't work as expected
3+
labels: ["bug"]
4+
body:
5+
- type: markdown
6+
attributes:
7+
value: |
8+
Before opening a bug report, please check the [existing issues](https://github.com/TigerTag-Project/TigerTag-SDK-JS/issues).
9+
10+
- type: input
11+
id: version
12+
attributes:
13+
label: SDK version
14+
description: Output of `tigertag --version` or `node -e "console.log(require('tigertag/package.json').version)"`
15+
placeholder: "1.0.0"
16+
validations:
17+
required: true
18+
19+
- type: input
20+
id: node
21+
attributes:
22+
label: Node.js version
23+
description: Output of `node --version`
24+
placeholder: "v20.0.0"
25+
validations:
26+
required: true
27+
28+
- type: dropdown
29+
id: tag_type
30+
attributes:
31+
label: Tag type
32+
options:
33+
- TigerTag (Maker)
34+
- TigerTag+
35+
- TigerTag Init
36+
- Unknown
37+
validations:
38+
required: false
39+
40+
- type: dropdown
41+
id: input_method
42+
attributes:
43+
label: Input method
44+
options:
45+
- fromPages()
46+
- fromDump()
47+
- fromFile()
48+
- create() / patch()
49+
- diffApi() / patchFromApi()
50+
- CLI
51+
- Other
52+
validations:
53+
required: false
54+
55+
- type: textarea
56+
id: description
57+
attributes:
58+
label: What happened?
59+
description: Clear description of the bug.
60+
validations:
61+
required: true
62+
63+
- type: textarea
64+
id: expected
65+
attributes:
66+
label: What did you expect?
67+
validations:
68+
required: true
69+
70+
- type: textarea
71+
id: repro
72+
attributes:
73+
label: Minimal reproduction
74+
description: Paste the smallest code snippet or CLI command that reproduces the issue.
75+
render: javascript
76+
validations:
77+
required: false
78+
79+
- type: textarea
80+
id: traceback
81+
attributes:
82+
label: Error / stack trace
83+
render: text
84+
validations:
85+
required: false
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Feature request
2+
description: Suggest an improvement or new capability
3+
labels: ["enhancement"]
4+
body:
5+
- type: textarea
6+
id: problem
7+
attributes:
8+
label: What problem does this solve?
9+
description: Describe the use case or limitation you're running into.
10+
validations:
11+
required: true
12+
13+
- type: textarea
14+
id: proposal
15+
attributes:
16+
label: Proposed solution
17+
description: What would you like to see added or changed?
18+
validations:
19+
required: true
20+
21+
- type: textarea
22+
id: alternatives
23+
attributes:
24+
label: Alternatives considered
25+
description: Any workarounds you've tried or other approaches you considered.
26+
validations:
27+
required: false

‎.github/workflows/publish.yml‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Publish to npm
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
jobs:
8+
test:
9+
name: Run tests before publish
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Set up Node.js
15+
uses: actions/setup-node@v4
16+
with:
17+
node-version: '20'
18+
cache: 'npm'
19+
20+
- name: Install dev dependencies
21+
run: npm ci
22+
23+
- name: Run tests
24+
run: npm test
25+
26+
publish:
27+
name: Publish to npm
28+
needs: test
29+
runs-on: ubuntu-latest
30+
permissions:
31+
id-token: write # required for npm provenance
32+
steps:
33+
- uses: actions/checkout@v4
34+
35+
- name: Set up Node.js
36+
uses: actions/setup-node@v4
37+
with:
38+
node-version: '20'
39+
registry-url: 'https://registry.npmjs.org'
40+
41+
- name: Publish
42+
run: npm publish --provenance --access public
43+
env:
44+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Sync TigerTag Databases
2+
3+
on:
4+
schedule:
5+
- cron: '0 3 * * *' # every day at 03:00 UTC
6+
workflow_dispatch: # manual trigger from the Actions tab
7+
8+
jobs:
9+
sync:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: write
13+
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Node.js
19+
uses: actions/setup-node@v4
20+
with:
21+
node-version: '20'
22+
23+
- name: Sync databases from TigerTag API
24+
run: |
25+
node - <<'EOF'
26+
const path = require('path');
27+
const { syncDatabases } = require('./src/index');
28+
29+
syncDatabases(path.join(__dirname, 'database'), { force: false, verbose: true })
30+
.then((updated) => {
31+
if (updated.length > 0) {
32+
console.log(`\n✓ Updated: ${updated.join(', ')}`);
33+
} else {
34+
console.log('\n✓ All databases are up to date.');
35+
}
36+
})
37+
.catch((err) => {
38+
console.error(`Error: ${err.message}`);
39+
process.exit(1);
40+
});
41+
EOF
42+
43+
- name: Commit and push if databases changed
44+
run: |
45+
git config user.name "github-actions[bot]"
46+
git config user.email "github-actions[bot]@users.noreply.github.com"
47+
git add database/
48+
if git diff --cached --quiet; then
49+
echo "No changes — databases are already up to date."
50+
else
51+
git commit -m "chore: sync TigerTag reference databases [skip ci]"
52+
git push
53+
fi

‎.github/workflows/test.yml‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
name: Node ${{ matrix.node-version }}
12+
runs-on: ubuntu-latest
13+
strategy:
14+
matrix:
15+
node-version: ["18", "20", "22"]
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Set up Node.js ${{ matrix.node-version }}
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: ${{ matrix.node-version }}
24+
cache: 'npm'
25+
26+
- name: Install dev dependencies
27+
run: npm ci
28+
29+
- name: Run tests
30+
run: npm test

‎.gitignore‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
node_modules/
2+
npm-debug.log*
3+
yarn-debug.log*
4+
yarn-error.log*
5+
.npm
6+
dist/
7+
build/
8+
.env
9+
10+
# DO NOT ignore database/*.json — they are bundled and committed.
11+
# syncDatabases() updates them in place.
12+
13+
# Test artifacts — but keep committed fixtures
14+
*.bin
15+
!test/fixtures/*.bin
16+
*.nfc
17+
coverage/
18+
.nyc_output/
19+
20+
# IDE
21+
.vscode/
22+
.idea/
23+
*.swp
24+
*.swo
25+
.DS_Store
26+
27+
# Internal tooling (not for public repo)
28+
.claude/
29+
CLAUDE.md

‎.npmignore‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Exclude development and CI files from the npm package
2+
test/
3+
scripts/
4+
examples/
5+
.github/
6+
.gitignore
7+
CHANGELOG.md
8+
SECURITY.md
9+
CLAUDE.md
10+
*.swp
11+
*.swo
12+
.DS_Store

‎CHANGELOG.md‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
Format based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5+
6+
## [1.0.0] — 2026-05-20
7+
8+
### Added
9+
- `TigerTag.fromPages(payload, uid)` — primary constructor for NFC SDK integration
10+
- `TigerTag.fromDump(data)` — constructor for binary dumps (180B auto-extracts UID)
11+
- `TigerTag.fromFile(path)` — convenience constructor from .bin file
12+
- `TigerTag.create({ ...fields })` — build a new tag from scratch with all fields
13+
- `TigerTag.asInit(uid)` — create a blank TigerTag Init chip ready for programming
14+
- `TigerTag.erase()` — return 80 zero bytes to wipe a chip back to blank NDEF
15+
- `tag.patch({ ...fields })` — immutable surgical field update, signature-safe (protected: idTigertag, idProduct, uid, signatureR/S)
16+
- `tag.patchFromApi()` — auto-apply cloud API values to chip fields; returns patched tag + applied diffs
17+
- `tag.diffApi()` — compare all chip fields vs TigerTag+ cloud API; covers nozzle, bed, drying, type, material, brand, diameter, aspects, colors, quantity, unit
18+
- `tag.rawApi()` — fetch live TigerTag+ cloud product data (uses built-in fetch, Node 18+)
19+
- `tag.verify()` — autonomous ECDSA-P256 signature verification using Node.js built-in `crypto`
20+
- `tag.toDict()` — fully resolved object (all IDs replaced by labels + metadata)
21+
- `tag.toRawDict()` — raw protocol fields, no resolution
22+
- `tag.pretty()` — human-readable summary
23+
- `tag.describe()` — natural-language paragraph for LLM prompt injection
24+
- `tag.validate()` — field-level sanity checks
25+
- `tag.syncDb()` — download or update reference databases
26+
- `TigerTagDB` — loads bundled reference JSONs, auto-updates from API or GitHub
27+
- `syncDatabases()` — standalone database sync with API + GitHub fallback
28+
- `SignatureResult` — result of ECDSA verification with status constants
29+
- `ApiDiff` — (field, chipValue, apiValue) — exported from main package
30+
- `ID_TIGERTAG`, `ID_TIGERTAG_PLUS`, `ID_TIGERTAG_INIT`, `MAKER_PRODUCT_ID`, `INIT_PRODUCT_ID` — exported constants
31+
- CLI: `tigertag dump.bin` and `node -e "require('tigertag')"`
32+
- Bundled reference databases (offline use, no network required on first run)
33+
- Compatible with NTAG213, NTAG215, NTAG216 and ISO 14443 compatible chips
34+
- No external runtime dependencies — Node.js built-in `crypto` and `fetch` only
35+
- Material identification support: filament, resin (extensible to any material type)

‎LICENSE.md‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# GNU General Public License v3.0
2+
3+
TigerTag JavaScript SDK
4+
Copyright (C) 2025 TigerTag
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
19+
---
20+
21+
For commercial OEM licensing inquiries, contact: licensing@tigertag.io

0 commit comments

Comments
 (0)