Reference
Reference

Error codes, security, and quick reference.

Lookup tables for error handling, the security architecture, and copy-pasteable integration patterns.

Fire API errors

All window.fire.* methods throw FireWalletApiError on failure.

JavaScript
try {
  await window.fire.getBalances();
} catch (err) {
  console.log(err.name);    // 'FireWalletApiError'
  console.log(err.code);    // 'NOT_GRANTED' | 'LOCKED' | 'INVALID_PARAMS' | 'INTERNAL_ERROR'
  console.log(err.message); // Human-readable description
}
Code Meaning
NOT_GRANTED Required permission scope not granted
LOCKED Wallet is locked — user needs to enter PIN
INVALID_PARAMS Bad or missing parameters
INTERNAL_ERROR Wallet internal error or timeout

EIP-1193 errors

Ethereum provider errors follow the EIP-1193 standard.

JavaScript
try {
  await provider.request({ method: 'eth_sendTransaction', params: [tx] });
} catch (err) {
  console.log(err.code);    // numeric
  console.log(err.message); // human-readable
}
Code Meaning
4001 User rejected the request
4200 Method not supported
4902 Unrecognized chain ID
-32602 Invalid parameters
-32603 Internal/RPC error

Security model

Key isolation

Private keys never leave the service worker. The page-injected API (window.fire) communicates through a content script bridge. No page script — including your own — can access keys.

Architecture
Your page  ←→  fire-page-api.js  ←→  Content script  ←→  Service worker (keys here)
 (MAIN)         (MAIN world)        (ISOLATED world)       (extension process)

Trust boundaries

  • The content script validates all page messages via event.source === window
  • Merchant domain is extracted from Chrome's sender.origin (not spoofable)
  • Read-only Ethereum calls are proxied to public RPC nodes without touching keys
  • Write operations always route through a user-facing approval dialog

What you cannot do

  • Access private keys or seed phrases
  • Sign transactions without user approval
  • Read wallet data without explicit permission grants
  • Bypass the approval dialog

Quick reference: payment (address-based)

JavaScript
// 1. Request payment
const result = await window.fire.requestPayment({
  recipientB58: '3Fhv7x...',
  amount: '1000000',
  tokenId: 1,
  merchantRef: 'order-42'
});

// 2. Listen for confirmation
window.addEventListener('fire-payment-update', (e) => {
  if (e.detail.status === 'confirmed') {
    // Done. e.detail.txId has the transaction ID.
  }
});

Quick reference: resolve protocol

JavaScript
// 1. Request payment (address stays server-side)
const result = await window.fire.requestPayment({
  resolveUrl: 'https://yoursite.com/api/resolve',
  intentToken: 'tok_abc123',
  amount: '5000000',
  tokenId: 1,
  merchantRef: 'order-42'
});

// 2. Same event listener
window.addEventListener('fire-payment-update', (e) => {
  if (e.detail.status === 'confirmed') { /* ... */ }
});

Quick reference: Read API

JavaScript
// 1. Request permission
await window.fire.requestPermissions(['balances:read']);

// 2. Read data
const balances = await window.fire.getBalances();

// 3. Handle revocation
window.fire.onPermissionRevoked((scopes) => { /* ... */ });

Quick reference: Ethereum

JavaScript
// 1. Detect wallet (EIP-6963)
window.addEventListener('eip6963:announceProvider', (e) => {
  if (e.detail.info.rdns === 'co.fire.wallet') {
    const provider = e.detail.provider;

    // 2. Connect
    const accounts = await provider.request({
      method: 'eth_requestAccounts'
    });

    // 3. Sign or send
    const sig = await provider.request({
      method: 'personal_sign',
      params: [message, accounts[0]]
    });
  }
});
window.dispatchEvent(new Event('eip6963:requestProvider'));