You control every byte
Set the ATR, answer each APDU yourself — real ISO 7816-4 line traffic, not a canned simulation.
Flash a STM32 Blackpill, plug it into your Android or PC, and play the card in JavaScript — straight from the browser, thanks to WebUSB.

npm install yolocard-sdkRequires a Chromium-based browser (Chrome, Edge, Opera) served over HTTPS or localhost. link.requestUsbTransport() must be called from a user gesture. Connecting to the reader may need an adapter, depending on the reader's contacts.
link moves bytes, protocol frames them — that's the whole seam, joined below. Call it from a user gesture (WebUSB opens the picker on a click). There's no card state machine tracking command boundaries for you: collect the reader's bytes yourself and reach for card.parseApdu(bytes) once you have a complete command.
let debounce;
const waitAllFramesFinished = (cb, ms) => {
clearTimeout(debounce);
setTimeout(cb, ms)
}
import {link, protocol} from 'yolocard-sdk';
// TS T0 [historical: 80 31 e0 73], no interface bytes, T=0 only (no TCK).
const ATR = '3B 04 80 31 E0 73'; // or [0x3b, 0x04, 0x80, 0x31, 0xe0, 0x73]
const comm = protocol.createCommunicator(await link.requestUsbTransport());
comm.onATRSet(atr => console.log('New ATR', atr))
comm.onResetCold(_ => console.log('Cold reset'))
comm.onResetWarm(_ => console.log('Cold reset'))
comm.onATRTransmitted(_ => console.log('ATR Transmitted'))
comm.onSpeedNegotiated(speed => console.log('Negotiated speed:', speed))
comm.onVoltageSkip(voltage => console.log('Skipped voltage class:', voltage))
comm.onClockStart(speed => console.log(`Clocking started: ${speed} Hz`))
comm.onClockStop(_ => console.log('Clock is down'))
comm.onHardwareFail(_ => console.log('Yolocard reported it has an internal failure.'))
comm.onFrame(frame => {
console.log(`${frame.side}\t${frame.clock}\t-> ${frame.byteHex}`)
})
comm.onFrame(frame => {
waitAllFramesFinished(() => frame.comm.sendBytes([0x6d, 0x00]))
});
await comm.connect(); // may raise Firmware Unsupported
await comm.setAtr(ATR);
// Ready to insert!
// comm.clearCallbacks()
// comm.disconnect()