Skip to content

Advanced wallet operations

Link another device, synchronize wallet recovery, and export Ed25519 or ECDSA key material through explicit user flows.

Advanced wallet operations ​

These operations change access or disclose key material. Start each one from a fresh user action. Keep progress visible. Retain the returned identity or receipt for your audit trail.

Prerequisites ​

Complete wallet setup and authentication and obtain an active wallet session. Device linking also needs a camera or a way to deliver the QR payload between devices.

Device 2 starts a short-lived session and displays its QR code. Device 1 scans that code and approves the request with fresh authentication.

tsx
import { useState } from 'react';
import { QRScanMode, ShowQRCode, useDeviceLinking } from '@seams/wallet/react';
import type { LinkDeviceFlowEvent, QrLinkedDeviceSessionPayloadV5 } from '@seams/wallet';

function logLinkEvent(event: LinkDeviceFlowEvent): void {
  console.log(event.phase, event.status, event.message);
}

// Device 2: `ShowQRCode` runs the whole start/display/expire cycle, including
// picking the target factor and cancelling an abandoned session.
export function NewDeviceLinkCode() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <>
      <button onClick={() => setIsOpen(true)}>Show link code</button>
      <ShowQRCode
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        onEvent={logLinkEvent}
        onError={(error) => console.error('Device link failed', error)}
      />
    </>
  );
}

// Device 1: scan the code and approve.
export function ApproveLinkedDevice(props: { qrData: QrLinkedDeviceSessionPayloadV5 }) {
  const { linkDevice } = useDeviceLinking({
    onEvent: logLinkEvent,
    onError: (error) => console.error('Device link failed', error),
  });

  return (
    <button onClick={() => void linkDevice(props.qrData, QRScanMode.CAMERA)}>Approve device</button>
  );
}

On Device 2, ShowQRCode starts the session and displays the code. It cancels an abandoned session when closed. Expire abandoned QR sessions. After success, show the device name so the user can recognize and revoke it later.

Recover a wallet account ​

Call recovery synchronization with the wallet id from the account record.

This synchronizes account state for a known wallet. The hosted wallet menu handles recovery-code entry and verification of the new authentication method. See wallet-user recovery.

ts
import type { SeamsWeb } from '@seams/wallet';

type SyncAccountResult = Awaited<ReturnType<SeamsWeb['recovery']['syncAccount']>>;

export async function recoverWalletAccount(
  seams: SeamsWeb,
  walletId: string,
): Promise<SyncAccountResult> {
  const result = await seams.recovery.syncAccount({ walletId });
  if (!result.success) {
    throw new Error(result.error);
  }

  console.log('wallet account restored', result.walletId, result.nearAccountId);
  return result;
}

The successful result exposes the restored wallet id and NEAR account id. Use the returned values to refresh app state before rendering signing controls.

Export an Ed25519 or ECDSA key ​

exportKey resolves the exact export lane and opens the wallet-origin export viewer in one call.

ts
import { logWalletEvents, type SeamsWeb } from '@seams/wallet';

export async function exportNearKey(seams: SeamsWeb): Promise<void> {
  await seams.keys.exportKey({
    kind: 'ed25519',
    options: { onEvent: logWalletEvents() },
  });
}

export async function exportEvmKey(seams: SeamsWeb): Promise<void> {
  await seams.keys.exportKey({
    kind: 'ecdsa',
    chainTarget: 'tempo-testnet',
    options: { onEvent: logWalletEvents() },
  });
}

exportNearKey exports the Ed25519 lane for the wallet's NEAR account. exportEvmKey exports the ECDSA lane for a configured chain. Both default to the authenticated wallet and receive progress through KeyExportFlowEvent.

The SDK owns lane selection and passes the selected lane directly to the wallet-origin viewer. If this device has no exact export lane or material, exportKey rejects with an export-lane or material error.

Expected result ​

  • Device linking creates a separate device credential and lane.
  • Recovery synchronization returns the restored wallet and NEAR identity.
  • Export opens a protected viewer after the exact lane is authorized.

Recoverable failures ​

  • A cancelled or expired QR session must be started again. Do not approve an old QR payload.
  • Recovery can return a failure result. Keep the existing account state until synchronization succeeds.
  • Export rejects when this device has no exact export lane or material. Show the error. The SDK never selects another lane.
  • Export authorization and viewer errors should end the current disclosure attempt. Ask for fresh authentication before another export.

Read next: linked devices, recovery, export, and rotation, or results and errors.