Skip to content

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 TypeCurveDescription
ioPublicKeyP-256Used for secure communication between the app and the card (ECDH). It encrypts sensitive data like PINs and seeds.
secp256k1KoblitzUsed for Bitcoin and EVM-compatible chains (Ethereum, BSC, Polygon, etc.).
ed25519EdwardsUsed 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 ioPublicKey for encryption.
  • 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:

  1. Preparation: The app calls CmdGetInfo.buildRequest() to generate the command buffer.
  2. User Interaction: The NFCHandlerWindow component is displayed, prompting the user to "Touch your card".
  3. Communication: The Command is sent to the card via the nfcProgressHandler.
  4. Response Parsing: CmdGetInfo.parseResponse() validates the card's magic bytes and extracts the public keys.
  5. State Update:
    • Public keys are dispatched to user/setPublicKeyCard.
    • If a card is registered, getWallet is called to derive the primary account address.
    • Navigation occurs based on card state (New -> Registration, Registered -> Dashboard).

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);
  }
}