Authorization
The Authorization Page (src/pages/Authorization.vue) serves as the primary entry point for users to interact with their non-custodial hardware (NFC Card). Its main purpose is to authenticate the user's card and establish a secure connection between the hardware and the web application.
Key Features:
- NFC/FIDO Connectivity: Supports multiple communication methods to "talk" to the card.
- Initialization & Registration: Detects if a card is new and redirects to the registration flow if necessary.
- Session Management: Securely stores public keys in the application state (Vuex) to enable wallet operations.
Public Keys
The project utilizes a multi-key architecture to support various blockchain networks and secure communication. The following keys are retrieved from the card during authorization:
| Key Type | Curve | Description |
|---|---|---|
ioPublicKey | P-256 | Used for secure communication between the app and the card (ECDH). It encrypts sensitive data like PINs and seeds. |
secp256k1 | Koblitz | Used for Bitcoin and EVM-compatible chains (Ethereum, BSC, Polygon, etc.). |
ed25519 | Edwards | Used for modern blockchains like Solana, TON, and Venom. |
Functions
Core Card Interface (src/api/card-io.ts)
CmdGetInfo:- Purpose: Retrieves basic card information.
- Returns: Card version, public keys (
ioPublicKey,secp256k1,ed25519), and a flag indicating if the card is new (isNewCard).
CmdSignSecp256k1/CmdSignEd25519:- Purpose: Signs a provided data hash using the respective private key stored on the card.
- Requirement: Requires a valid PIN signature for authorization.
CmdSetPin:- Purpose: Securely updates the card's PIN using
ioPublicKeyfor encryption.
- Purpose: Securely updates the card's PIN using
CmdInit:- Purpose: Initializes a new card with a seed and a PIN.
Page Logic (src/pages/Authorization.vue)
authorizationHandler(): The main wrapper function that triggers the NFC read/sign process, parses the response, and updates the global application state.detectNfcCapabilities(): Utility function to check browser compatibility for Web NFC, WebAuthn, and Web USB.
Implementation
The authorization flow is implemented using a reactive approach:
- Preparation: The app calls
CmdGetInfo.buildRequest()to generate the command buffer. - User Interaction: The
NFCHandlerWindowcomponent is displayed, prompting the user to "Touch your card". - Communication: The Command is sent to the card via the
nfcProgressHandler. - Response Parsing:
CmdGetInfo.parseResponse()validates the card's magic bytes and extracts the public keys. - State Update:
- Public keys are dispatched to
user/setPublicKeyCard. - If a card is registered,
getWalletis called to derive the primary account address. - Navigation occurs based on card state (New -> Registration, Registered -> Dashboard).
- Public keys are dispatched to
Usage Example
Triggering Authorization manually
javascript
import { CmdGetInfo } from '@/api/card-io';
import { getWallet } from '@/api/ApiHandler';
async function performLogin() {
try {
// 1. Prepare Command
const request = await CmdGetInfo.buildRequest();
// 2. Execute via NFC (UI component handles the actual tap)
const result = await nfcHandlerWindow.value.nfcProgressHandler(request, CmdGetInfo);
// 3. Handle public keys
const { keys, isNewCard } = result;
console.log("Derived Public Keys:", keys);
// 4. Get wallet address for the current blockchain
const address = await getWallet(keys);
console.log("Wallet Address:", address);
} catch (error) {
console.error("Authorization failed:", error.message);
}
}