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:
- Selecting a token to transfer.
- Entering the recipient's wallet address.
- Specifying the amount to send.
- Signing the transaction using a physical United Card via NFC or FIDO.
- 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
Tokenobject 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
Requestobject 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
// 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.
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
isValidWalletAddressutility. - 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.
