PC/SC sample in TypeScript (Deno)
To continue the list of PC/SC wrappers initiated in 2010 with "PC/SC sample in different languages" I now present a new sample code in Deno a modern runtime for JavaScript and TypeScript.
pcsc-deno
The wrapper is available at https://github.com/cryptographix/pcsc-deno and https://deno.land/x/pcsc
The author is
Sean Michael Wykes.
The license is MIT.
I used version
0.4.
This version includes the fixes I proposed for GNU/Linux.
Deno
From Wikipedia Deno article:
Deno is a runtime for JavaScript, TypeScript, and WebAssembly that is based on the V8 JavaScript engine and the Rust programming language. Deno was co-created by Ryan Dahl, who also created Node.js.
Deno explicitly takes on the role of both runtime and package manager within a single executable, rather than requiring a separate package-management program.
Installation
Installation is very easy. First install Deno as documented in https://deno.land/#installation
The PC/SC wrapper will be downloaded and installed automatically at run
time.
Source code
import { CommandAPDU, ContextProvider, ISO7816, PCSC, } from 'https://deno.land/x/pcsc/mod.ts'; try { // establish a PC/SC context const context = ContextProvider.establishContext(); // get all available readers const readers = context.listReaders(); for (const reader of readers) { console.log(`Using reader: ${reader.name}`); if (reader.isMute) { console.log(`Reader ${reader.name}: MUTE`); } else if (reader.isPresent) { // connect const card = await reader.connect(); // send Select Applet APDU const selectApplet = CommandAPDU .from([ISO7816.CLA.ISO, ISO7816.INS.SelectFile, 0x04, 0x00]) // ISO SELECT .setData([0xA0, 0x00, 0x00, 0x00, 0x62, 0x03, 0x01, 0x0C, 0x06, 0x01]); const resp = await card.transmitAPDU(selectApplet); // check for 0x90 0x00 if (resp.SW == ISO7816.SW.SUCCESS) { // success .. console.log(`Reader ${reader.name}: applet successfully selected`); // send Test APDU const command = CommandAPDU .from([ISO7816.CLA.ISO, 0, 0, 0]); const resp = await card.transmitAPDU(command); if (resp.SW == ISO7816.SW.SUCCESS) { // success .. console.log(`Reader ${reader.name}: Test command successful`); // convert from bytes to string and display console.log(String.fromCharCode.apply(null, resp.data)); } else { // something went wrong .. console.error( `Reader ${reader.name}: error SW=${resp.SW.toString(16)}`, ); } } else { // something went wrong .. console.error( `Reader ${reader.name}: error SW=${resp.SW.toString(16)}`, ); } // unpower and disconnect await card.disconnect(PCSC.Disposition.UnpowerCard); } else { console.log(`Reader ${reader.name}: NO CARD`); } } // release the PC/SC context context.shutdown(); } catch (e: PCSCException) { console.log(e, "error"); }
Output
$ deno run --unstable --allow-ffi blog.ts Using reader: Gemalto PC Twin Reader (F8345B4A) 00 00 Reader Gemalto PC Twin Reader (F8345B4A) 00 00: applet successfully selected Reader Gemalto PC Twin Reader (F8345B4A) 00 00: command successful Hello world!
Conclusion
Nothing special to say. Thanks Sean for the wrapper.
If you work on a Free Software PC/SC wrapper that is not yet in my list please let me know.