Skip to content

Send Tokens

Implementation and usage of the Send page in the United Non-custodial project. The Send page enables users to transfer tokens across various supported blockchains using card-based signing.

The Send page provides a user interface for:

  1. Selecting a token to transfer.
  2. Entering the recipient's wallet address.
  3. Specifying the amount to send.
  4. Signing the transaction using a physical United Card via NFC or FIDO.
  5. Tracking the transaction status.

Transfer Requirements

To successfully transfer tokens, the following conditions must be met:

  • Authorization: The user must be authorized (card public keys recovered and wallet address generated).
  • Token Balance: The selected token must have a balance greater than the amount being sent plus gas fees.
  • Public Keys: The publicKeyCard (ed25519 and secp256k1) must be available in the application state.
  • PIN Code: A valid PIN code is required to sign the transaction chunks on the card.
  • NFC/FIDO Support: The device must support NFC or FIDO (WebAuthn) for card interaction.

Key Functions

1. getToken(id: string)

Retrieves a Token instance for the specified token ID (root) associated with the current RPC provider.

  • Location: src/api/ApiHandler.ts
  • Returns: A Token object with methods for balance checking and transfers.

2. token.transfer(transactionData)

Prepares a transaction request for the specified recipient and amount.

  • Arguments:
    • recipient: The destination wallet address.
    • amount: The number of tokens to transfer.
    • keys: The public keys from the card (store.state.user.publicKeyCard).
  • Returns: A Request object containing transaction chunks for card signing.

3. nfcProgressChunksHandler(request, pin, isTransaction)

Handles the interaction with the United Card to sign the transaction chunks.

  • Component: NFCHandlerWindow.vue
  • Arguments:
    • request: The prepared transaction request.
    • pin: The user's PIN code.
    • isTransaction: Boolean flag indicating this is a transaction signing.

4. request.send()

Broadcasts the signed transaction to the blockchain.

  • Returns: A transaction receipt or identifier.

Implementation Details

The core logic resides in the submitFormOrderHandler function within src/pages/Send.vue.

Simple Transaction Flow

javascript
// 1. Get the token instance
const token = getToken(selectedTokenId);

// 2. Prepare transaction data
const transactionData = {
  recipient: formData.wallet,
  amount: formData.amount,
  keys: store.state.user.publicKeyCard
};

// 3. Create transfer request
const request = await token.transfer(transactionData);

// 4. Sign transaction chunks with card
await nfcHandlerWindow.value?.nfcProgressChunksHandler(request, userPin, true);

// 5. Send signed transaction
const receipt = await request.send();

Usage Example

Below is a simplified example of how to implement a token transfer in a component context.

javascript
import { getToken } from '@/api/ApiHandler';
import { useStore } from 'vuex';

const store = useStore();

async function sendTokens(recipient, amount, pin) {
  try {
    // Determine the selected token ID
    const tokenId = store.state.user.selectedToken?.[store.state.settings.rpcProvider?.name]?.root;
    const token = getToken(tokenId);

    // Prepare data
    const transactionData = {
      recipient: recipient,
      amount: amount,
      keys: store.state.user.publicKeyCard
    };

    // Prepare transfer
    const request = await token.transfer(transactionData);

    // Interaction with Card (NFC/FIDO)
    // This typically opens a modal/overlay for the user to touch the card
    await signWithCard(request, pin);

    // Execute transaction
    const result = await request.send();
    console.log('Transaction Successful:', result);
    
  } catch (error) {
    console.error('Transfer failed:', error);
  }
}

Error Handling

The Send page implements comprehensive error handling for several scenarios:

  • Insufficient Funds: Verified before transaction initialization.
  • Invalid Address: Checked using isValidWalletAddress utility.
  • Card Interaction Errors: Gracefully handled during the NFC/FIDO communication phase.
  • Blockchain Rejection: Caught during the request.send() phase.

Errors are displayed to the user via a Panel component with descriptive messages and options to retry.