diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index db7c201..b4e9b40 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -7,6 +7,10 @@ on:
pull_request:
workflow_dispatch:
+permissions:
+ contents: read
+ packages: read
+
jobs:
build-and-test:
runs-on: ubuntu-latest
@@ -21,9 +25,14 @@ jobs:
with:
node-version: 22
cache: "npm"
+ registry-url: "https://npm.pkg.github.com"
+ scope: "@aokiapp"
+ always-auth: true
- name: Install dependencies
run: npm ci
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build all packages
run: npm run build
diff --git a/.github/workflows/rn-android-build.yml b/.github/workflows/rn-android-build.yml
index 7248061..fa1fcab 100644
--- a/.github/workflows/rn-android-build.yml
+++ b/.github/workflows/rn-android-build.yml
@@ -16,6 +16,10 @@ on:
- "docs/android-build.md"
workflow_dispatch:
+permissions:
+ contents: read
+ packages: read
+
jobs:
android:
runs-on: ubuntu-latest
@@ -30,6 +34,9 @@ jobs:
with:
node-version: 22
cache: "npm"
+ registry-url: "https://npm.pkg.github.com"
+ scope: "@aokiapp"
+ always-auth: true
- name: Setup Java 21
uses: actions/setup-java@v5.1.0
@@ -44,6 +51,8 @@ jobs:
- name: Install dependencies
run: npm ci
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build packages (generates nitrogen files)
run: npm run build
@@ -79,6 +88,9 @@ jobs:
with:
node-version: 22
cache: "npm"
+ registry-url: "https://npm.pkg.github.com"
+ scope: "@aokiapp"
+ always-auth: true
- name: Setup Java 21
uses: actions/setup-java@v5.1.0
@@ -94,6 +106,8 @@ jobs:
- name: Install dependencies
run: npm ci
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build packages (generates nitrogen files)
run: npm run build
diff --git a/.npmrc b/.npmrc
index c4fe4b9..fca78bc 100644
--- a/.npmrc
+++ b/.npmrc
@@ -1,2 +1 @@
@aokiapp:registry=https://npm.pkg.github.com
-//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}
diff --git a/examples/rn/README.md b/examples/rn/README.md
index c1d5b2a..eb2a7b3 100644
--- a/examples/rn/README.md
+++ b/examples/rn/README.md
@@ -124,7 +124,6 @@ File: `android/app/src/main/AndroidManifest.xml`
-
```
## Running the App
diff --git a/examples/rn/src/screens/SmartCardTestScreen.tsx b/examples/rn/src/screens/SmartCardTestScreen.tsx
index fca106b..53da842 100644
--- a/examples/rn/src/screens/SmartCardTestScreen.tsx
+++ b/examples/rn/src/screens/SmartCardTestScreen.tsx
@@ -260,7 +260,6 @@ function SmartCardTestScreenInner() {
console.log(`[Plat] Device[${idx}]`, {
id: info.id,
supportsApdu: info.supportsApdu,
- supportsHce: info.supportsHce,
integrated: info.isIntegratedDevice,
removable: info.isRemovableDevice,
d2c: info.d2cProtocol,
diff --git a/package-lock.json b/package-lock.json
index 0094183..d76bdc5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -104,9 +104,9 @@
"link": true
},
"node_modules/@aokiapp/tlv": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/@aokiapp/tlv/-/tlv-0.4.0.tgz",
- "integrity": "sha512-h7PpQnC76xmmycvxJnFuGdXoact11Y2O+Ve0XGwjwb+EYRz4mlIW+XNudDWHYFJvuzThFIMi4MnKrcT0Mz8GCw==",
+ "version": "0.4.1",
+ "resolved": "https://npm.pkg.github.com/download/@aokiapp/tlv/0.4.1/16025aaeacd3c0637563d851551a11bdacf3bc6e",
+ "integrity": "sha512-aaC8/gHvTTgoEC8CMa4ncWWGTJr02pZH2Pa8pDulX+35FFXq58fnDKFjZFGph1deq9WINXopIMiktbiXLKmvdQ==",
"license": "SEE LICENSE IN LICENSE.md"
},
"node_modules/@ark/schema": {
@@ -22654,15 +22654,15 @@
},
"packages/apdu-utils": {
"name": "@aokiapp/apdu-utils",
- "version": "0.0.1",
+ "version": "0.0.4",
"license": "SEE LICENSE IN https://raw.githubusercontent.com/AokiApp/ANAL/refs/heads/main/licenses/ANAL-Tight-1.0.1.md",
"dependencies": {
- "@aokiapp/jsapdu-interface": "^0.0.1"
+ "@aokiapp/jsapdu-interface": "^0.0.3"
}
},
"packages/interface": {
"name": "@aokiapp/jsapdu-interface",
- "version": "0.0.1",
+ "version": "0.0.3",
"license": "SEE LICENSE IN https://raw.githubusercontent.com/AokiApp/ANAL/refs/heads/main/licenses/ANAL-Tight-1.0.1.md",
"dependencies": {
"nanoevents": "^9.1.0"
@@ -22670,15 +22670,15 @@
},
"packages/mynacard": {
"name": "@aokiapp/mynacard",
- "version": "0.0.1",
+ "version": "0.0.3",
"license": "SEE LICENSE IN https://raw.githubusercontent.com/AokiApp/ANAL/refs/heads/main/licenses/ANAL-Tight-1.0.1.md",
"dependencies": {
- "@aokiapp/tlv": "^0.4.0"
+ "@aokiapp/tlv": "^0.4.1"
}
},
"packages/pcsc": {
"name": "@aokiapp/jsapdu-pcsc",
- "version": "0.0.1",
+ "version": "0.0.2",
"license": "SEE LICENSE IN https://raw.githubusercontent.com/AokiApp/ANAL/refs/heads/main/licenses/ANAL-Tight-1.0.1.md",
"dependencies": {
"@aokiapp/jsapdu-interface": "*",
@@ -22687,7 +22687,7 @@
},
"packages/pcsc-ffi-node": {
"name": "@aokiapp/pcsc-ffi-node",
- "version": "0.0.1",
+ "version": "0.0.2",
"license": "SEE LICENSE IN https://raw.githubusercontent.com/AokiApp/ANAL/refs/heads/main/licenses/ANAL-Tight-1.0.1.md",
"dependencies": {
"koffi": "^2.6.1"
@@ -22698,7 +22698,7 @@
},
"packages/rn": {
"name": "@aokiapp/jsapdu-rn",
- "version": "0.1.0",
+ "version": "0.1.1",
"license": "SEE LICENSE IN https://raw.githubusercontent.com/AokiApp/ANAL/refs/heads/main/licenses/ANAL-Tight-1.0.1.md",
"dependencies": {
"nanoevents": "^9.1.0"
diff --git a/packages/interface/README.md b/packages/interface/README.md
index 273c996..58b3d78 100644
--- a/packages/interface/README.md
+++ b/packages/interface/README.md
@@ -76,7 +76,6 @@ class MyPlatform extends SmartCardPlatform {
id: 'device-1',
friendlyName: 'My Reader',
supportsApdu: true,
- supportsHce: false,
isIntegratedDevice: false,
isRemovableDevice: true,
d2cProtocol: 'iso7816',
diff --git a/packages/interface/src/abstracts.ts b/packages/interface/src/abstracts.ts
index 06547c8..6b6455f 100644
--- a/packages/interface/src/abstracts.ts
+++ b/packages/interface/src/abstracts.ts
@@ -155,11 +155,6 @@ export abstract class SmartCardDeviceInfo {
*/
public abstract readonly supportsApdu: boolean;
- /**
- * Supports Host Card Emulation
- */
- public abstract readonly supportsHce: boolean;
-
/**
* The device is an integrated reader (phone inside)
*/
@@ -249,7 +244,7 @@ export abstract class SmartCardDevice<
/**
* Card acquired by the device
*/
- protected card: SmartCard | EmulatedCard | null = null;
+ protected card: SmartCard | null = null;
/**
* Get the device information of itself
@@ -297,10 +292,6 @@ export abstract class SmartCardDevice<
*/
public abstract waitForCardPresence(timeout: number): Promise;
- /**
- * Start HCE session
- */
- public abstract startHceSession(): Promise;
/**
* Release the device and its card session
* @throws {SmartCardError} If release fails
@@ -389,50 +380,3 @@ export abstract class SmartCard {
}
type Atr = Uint8Array;
-
-export abstract class EmulatedCard {
- protected eventEmitter = createNanoEvents();
- /**
- * @constructor
- */
- protected constructor(protected parentDevice: SmartCardDevice) {}
-
- /**
- * Whether acquired device session is active or not
- */
- public abstract isActive(): boolean;
-
- /**
- * Set APDU handler
- * @throws {SmartCardError} If setting handler fails
- */
- public abstract setApduHandler(
- handler: (command: Uint8Array) => Promise,
- ): Promise;
-
- /**
- * Release the session
- * @throws {SmartCardError} If release fails
- */
- public abstract release(): Promise;
-
- /**
- * asyncDispose, use in conjunction with `await using`
- */
- public async [Symbol.asyncDispose]() {
- try {
- await this.release();
- } catch (error) {
- throw fromUnknownError(error);
- }
- }
-
- /**
- * Event emitter for emulated card events
- */
- on(event: K, cb: Events[K]): () => void {
- return this.eventEmitter.on(event, cb);
- }
-
- // emit is not exposed, use eventEmitter directly
-}
diff --git a/packages/pcsc/README.md b/packages/pcsc/README.md
index 147321d..8e5e32d 100644
--- a/packages/pcsc/README.md
+++ b/packages/pcsc/README.md
@@ -480,7 +480,6 @@ Reader information and capabilities. Extends `SmartCardDeviceInfo`.
- `friendlyName: string` - Display name (same as id for PC/SC)
- `description: string` - Reader description
- `supportsApdu: boolean` - Always true for PC/SC readers
-- `supportsHce: boolean` - Always false (PC/SC doesn't support HCE)
- `isIntegratedDevice: boolean` - Always false (PC/SC readers are external)
- `isRemovableDevice: boolean` - Always true
- `d2cProtocol: string` - "iso7816" or "nfc" (detected from reader name)
diff --git a/packages/pcsc/src/device-info.ts b/packages/pcsc/src/device-info.ts
index 3e6d38f..deac454 100644
--- a/packages/pcsc/src/device-info.ts
+++ b/packages/pcsc/src/device-info.ts
@@ -53,14 +53,6 @@ export class PcscDeviceInfo extends SmartCardDeviceInfo {
return true;
}
- /**
- * Supports Host Card Emulation
- * PC/SC readers typically don't support HCE
- */
- public get supportsHce(): boolean {
- return false;
- }
-
/**
* The device is an integrated reader (phone inside)
* PC/SC readers are typically external devices
diff --git a/packages/pcsc/src/device.ts b/packages/pcsc/src/device.ts
index 9e0bd03..760077b 100644
--- a/packages/pcsc/src/device.ts
+++ b/packages/pcsc/src/device.ts
@@ -1,5 +1,4 @@
import {
- EmulatedCard,
SmartCard,
SmartCardDevice,
SmartCardDeviceInfo,
@@ -204,17 +203,6 @@ export class PcscDevice extends SmartCardDevice {
throw new SmartCardError("TIMEOUT", "Timed out waiting for card presence");
}
- /**
- * Start an HCE session
- * @throws {SmartCardError} Always throws as PC/SC doesn't support HCE
- */
- public startHceSession(): Promise {
- throw new SmartCardError(
- "UNSUPPORTED_OPERATION",
- "PC/SC does not support Host Card Emulation",
- );
- }
-
/**
* Release the device and its card session
* @throws {SmartCardError} If release fails
diff --git a/packages/pcsc/tests/pcsc-test.ts b/packages/pcsc/tests/pcsc-test.ts
index f006180..ae673b9 100644
--- a/packages/pcsc/tests/pcsc-test.ts
+++ b/packages/pcsc/tests/pcsc-test.ts
@@ -27,7 +27,6 @@ async function testPcscPlatform() {
console.log(` D2C Protocol: ${info.d2cProtocol}`);
console.log(` P2D Protocol: ${info.p2dProtocol}`);
console.log(` Supports APDU: ${info.supportsApdu}`);
- console.log(` Supports HCE: ${info.supportsHce}`);
});
if (deviceInfos.length > 0) {
diff --git a/packages/rn/README.md b/packages/rn/README.md
index d454b10..5694758 100644
--- a/packages/rn/README.md
+++ b/packages/rn/README.md
@@ -31,7 +31,6 @@ Add to `AndroidManifest.xml`:
```xml
-
```
## Quick Start
@@ -255,7 +254,6 @@ async function getAvailableDevices() {
console.log(` ID: ${device.id}`);
console.log(` Type: ${device.d2cProtocol}`);
console.log(` Supports APDU: ${device.supportsApdu}`);
- console.log(` Supports HCE: ${device.supportsHce}`);
});
// Use specific device
@@ -638,11 +636,6 @@ Whether device supports APDU communication.
**Value:** Always `true` for NFC devices in this package.
-#### `supportsHce: boolean`
-Whether device supports Host Card Emulation.
-
-**Value:** Currently always `false` (HCE support planned for future).
-
#### `isIntegratedDevice: boolean`
Whether device is built into the phone.
diff --git a/packages/rn/android/src/main/java/app/aoki/jsapdu/rn/nfc/NfcPlatformHelper.kt b/packages/rn/android/src/main/java/app/aoki/jsapdu/rn/nfc/NfcPlatformHelper.kt
index fe13030..e45bcec 100644
--- a/packages/rn/android/src/main/java/app/aoki/jsapdu/rn/nfc/NfcPlatformHelper.kt
+++ b/packages/rn/android/src/main/java/app/aoki/jsapdu/rn/nfc/NfcPlatformHelper.kt
@@ -38,7 +38,6 @@ object NfcPlatformHelper {
friendlyName = "Integrated NFC Reader",
description = "Android NFC with ISO-DEP support",
supportsApdu = true,
- supportsHce = false,
isIntegratedDevice = true,
isRemovableDevice = false,
d2cProtocol = D2CProtocol.NFC,
diff --git a/packages/rn/android/src/main/java/app/aoki/jsapdu/rn/omapi/OmapiPlatformHelper.kt b/packages/rn/android/src/main/java/app/aoki/jsapdu/rn/omapi/OmapiPlatformHelper.kt
index 88575e3..54e234d 100644
--- a/packages/rn/android/src/main/java/app/aoki/jsapdu/rn/omapi/OmapiPlatformHelper.kt
+++ b/packages/rn/android/src/main/java/app/aoki/jsapdu/rn/omapi/OmapiPlatformHelper.kt
@@ -35,7 +35,6 @@ object OmapiPlatformHelper {
friendlyName = "$deviceType Secure Element",
description = "OMAPI: $readerName",
supportsApdu = true,
- supportsHce = false,
isIntegratedDevice = deviceType == "eSE",
isRemovableDevice = deviceType == "SIM",
d2cProtocol = D2CProtocol.NFC,
diff --git a/packages/rn/src/JsapduRn.nitro.ts b/packages/rn/src/JsapduRn.nitro.ts
index c157f7d..5e0f800 100644
--- a/packages/rn/src/JsapduRn.nitro.ts
+++ b/packages/rn/src/JsapduRn.nitro.ts
@@ -19,7 +19,6 @@ export interface DeviceInfo {
friendlyName?: string;
description?: string;
supportsApdu: boolean;
- supportsHce: boolean;
isIntegratedDevice: boolean;
isRemovableDevice: boolean;
d2cProtocol: D2CProtocol;
diff --git a/packages/rn/src/device/rn-device-info.ts b/packages/rn/src/device/rn-device-info.ts
index fa748e3..c10a43a 100644
--- a/packages/rn/src/device/rn-device-info.ts
+++ b/packages/rn/src/device/rn-device-info.ts
@@ -14,7 +14,6 @@ import type { DeviceInfo } from '../JsapduRn.nitro';
* For Android NFC implementation:
* - id: "integrated-nfc-0" (example, not fixed)
* - apduApi: ["nfc", "androidnfc"] (both included)
- * - supportsHce: false (initial version)
* - isIntegratedDevice: true
* - isRemovableDevice: false
* - d2cProtocol: "nfc"
@@ -61,12 +60,6 @@ export class RnDeviceInfo extends SmartCardDeviceInfo {
*/
public readonly supportsApdu: boolean;
- /**
- * Whether device supports Host Card Emulation
- * false in initial version
- */
- public readonly supportsHce: boolean;
-
/**
* Whether device is integrated into the phone
* true for built-in NFC reader
@@ -122,7 +115,6 @@ export class RnDeviceInfo extends SmartCardDeviceInfo {
this.friendlyName = info.friendlyName;
this.description = info.description;
this.supportsApdu = info.supportsApdu;
- this.supportsHce = info.supportsHce;
this.isIntegratedDevice = info.isIntegratedDevice;
this.isRemovableDevice = info.isRemovableDevice;
this.d2cProtocol = info.d2cProtocol;
diff --git a/packages/rn/src/device/rn-smart-card-device.ts b/packages/rn/src/device/rn-smart-card-device.ts
index 247d368..c4d4e9f 100644
--- a/packages/rn/src/device/rn-smart-card-device.ts
+++ b/packages/rn/src/device/rn-smart-card-device.ts
@@ -2,7 +2,6 @@ import {
SmartCard,
SmartCardDevice,
SmartCardDeviceInfo,
- EmulatedCard,
SmartCardError,
} from '@aokiapp/jsapdu-interface';
import { mapNitroError } from '../errors/error-mapper';
@@ -379,22 +378,6 @@ export class RnSmartCardDevice extends SmartCardDevice<{
}
}
- /**
- * Start HCE (Host Card Emulation) session
- *
- * @throws {SmartCardError} with code "UNSUPPORTED_OPERATION" - HCE not supported in initial version
- *
- * @remarks
- * HCE is planned for future implementation.
- * This method will be implemented when HCE support is added.
- */
- public startHceSession(): Promise {
- throw new SmartCardError(
- 'UNSUPPORTED_OPERATION',
- 'HCE (Host Card Emulation) is not supported in the initial version'
- );
- }
-
/**
* Release device and deactivate RF
*
diff --git a/packages/rn/src/platform/rn-smart-card-platform.ts b/packages/rn/src/platform/rn-smart-card-platform.ts
index e856823..302cefb 100644
--- a/packages/rn/src/platform/rn-smart-card-platform.ts
+++ b/packages/rn/src/platform/rn-smart-card-platform.ts
@@ -332,7 +332,6 @@ export class RnSmartCardPlatform extends SmartCardPlatform<{
*
* Android implementation returns:
* - apduApi: ["nfc", "androidnfc"] (both included)
- * - supportsHce: false (initial version)
*/
public async getDeviceInfo(): Promise {
this.assertInitialized();