Skip to content

Start here

Install Seams, create a wallet, and sign your first operation.

Start here

Get a working wallet path running before you add recovery, linked devices, or delegated authority. You need a React app and a Seams project with a wallet origin, relayer URL, and managed-registration credentials.

1. Install the SDK

sh
pnpm add @seams/wallet

2. Mount the provider

Configure the isolated wallet origin once near the root of your app. seamsTestnetConfig takes the four values a wallet cannot start without and fills in the rest from the SDK defaults. The example reads them from import.meta.env; use the same names in your own environment or replace them with your config loader. Pass chains to configure different networks, or use defineSeamsConfig when you are not on testnet.

tsx
import { SeamsWebProvider, seamsTestnetConfig, useSeams } from '@seams/wallet/react';

// Everything else — wallet service path, SDK base path, relayer account, chain
// RPC and explorer URLs — comes from the SDK defaults.
const seamsConfig = seamsTestnetConfig({
  walletOrigin: import.meta.env.VITE_WALLET_ORIGIN,
  relayerUrl: import.meta.env.VITE_RELAYER_URL,
  publishableKey: import.meta.env.VITE_SEAMS_PUBLISHABLE_KEY,
});

function WalletApp() {
  const { loginState } = useSeams();
  return <p>{loginState.isLoggedIn ? 'Wallet unlocked' : 'Wallet locked'}</p>;
}

export function App() {
  return (
    <SeamsWebProvider config={seamsConfig}>
      <WalletApp />
    </SeamsWebProvider>
  );
}

Render your wallet UI inside SeamsWebProvider. Keep the wallet service and SDK assets on the configured wallet origin.

3. Create a wallet

Render the button from the registration example inside the provider. A click opens the passkey prompt and logs progress and the branch-specific result.

tsx
import type { RegistrationFlowEvent } from '@seams/wallet';
import { useSeams } from '@seams/wallet/react';

export function CreateWalletButton() {
  const { registerPasskey, seams } = useSeams();

  const onCreateWallet = async (): Promise<void> => {
    const result = await registerPasskey({
      onEvent: (event: RegistrationFlowEvent) =>
        console.log(event.phase, event.status, event.message),
    });
    if (!result.success) {
      console.error('Registration failed:', result.error);
      return;
    }
    // `walletId` is the stable identifier for every later wallet operation.
    console.log(`Wallet ${result.walletId} registered (${result.kind})`);

    // A mixed registration returns before NEAR provisioning finishes, so the
    // result carries no NEAR account id yet. Wait for one before signing NEAR.
    if (result.kind === 'ecdsa_wallet_registered_near_pending') {
      const near = await seams.registration.awaitNearReady({ walletId: result.walletId });
      console.log('NEAR provisioning finished:', near.kind);
    }
  };

  return <button onClick={() => void onCreateWallet()}>Create wallet</button>;
}

Read Create a wallet for the result branches and retry guidance.

4. Sign a transaction

Registration leaves the wallet ready to sign. useWallet() gives you the signed-in wallet with signing bound to it, so a call names only the transaction. Each request opens the wallet confirmation, and the user approves that transaction with the wallet's auth method.

To target a wallet other than the signed-in one, use useSeams().seams and pass an exact walletSession on the call.

Build actions with functionCall, transfer, and friends rather than the raw { type: ActionType.FunctionCall, … } shape, and pass logWalletEvents() to onEvent when you just want progress in the console.

seams.evm and seams.tempo mirror each other — signTransaction, executeTransaction, advanced — and stay separate because an EVM transaction is EIP-1559 and a Tempo one is EIP-2718.

There is no unlock step here. When your product needs repeated signatures without a prompt for each one, provision a signing session: read wallet sessions and signing lanes.

Add advanced capabilities

Once the first signing path works, continue with linked devices, key export, and recovery. For authentication choices, policies, and deployment boundaries, use the guides.