Signing
Signing calls resolve the authenticated wallet automatically. Name an exact wallet or chain when your application handles more than one. The snippets below keep progress events visible so your UI can show what the signer is doing.
Prerequisites
You need a configured SeamsWebProvider and a signed-in wallet. See wallet setup and authentication if the wallet is still locked.
Signing does not require a separate unlock step. Each request opens the wallet confirmation so the user can approve that transaction. unlock provisions a signing session when your product needs a burst of signatures without a prompt for each one.
import type { UnlockFlowEvent } from '@seams/wallet';
import type { SeamsContextType } from '@seams/wallet/react';
export async function unlockWallet(unlock: SeamsContextType['unlock'], walletId: string) {
const result = await unlock(walletId, {
onEvent: (event: UnlockFlowEvent) => console.log(event.phase, event.status, event.message),
});
if (!result.success) {
throw new Error(result.error);
}
// Read `nearAccountId` only from the NEAR branch.
if (result.kind === 'near_wallet_unlocked') {
console.log('NEAR account ready', result.nearAccountId);
} else {
console.log('EVM-family wallet ready', result.walletId);
}
return result;
}Send a NEAR transaction
The example sends a set_greeting function call to a NEAR testnet account and waits for EXECUTED_OPTIMISTIC.
import {
functionCall,
logWalletEvents,
TxExecutionStatus,
useSeams,
type BoundNearSigner,
} from '@seams/wallet/react';
async function signGreeting(near: BoundNearSigner): Promise<void> {
await near.signAndSendTransaction({
receiverId: 'guest-book.testnet',
actions: [functionCall({ method: 'set_greeting', args: { greeting: 'Hello from Seams' } })],
options: {
waitUntil: TxExecutionStatus.EXECUTED_OPTIMISTIC,
onEvent: logWalletEvents(),
},
});
}
export function SetGreetingButton() {
const { wallet } = useSeams();
if (wallet?.access !== 'wallet' || !wallet.near) return null;
// Each request opens wallet confirmation for this transaction.
return <button onClick={signGreeting.bind(null, wallet.near)}>Sign transaction</button>;
}The button resolves after the configured execution status. useSeams() returns wallet: null while signed out and wallet.near: null until a NEAR account is ready. The type guard before the button prevents signing without that account.
Sign a NEP-413 message
Use NEP-413 for an off-chain, domain-bound message such as a checkout approval.
import { logWalletEvents, type SeamsWeb } from '@seams/wallet';
export async function signCheckoutMessage(seams: SeamsWeb) {
const result = await seams.near.signMessage({
// Omitting the subject targets the authenticated wallet and its NEAR
// account; pass `walletSession` (a wallet id is enough) or `nearAccount` to
// name an exact one.
params: {
message: 'Approve checkout quote #quote_123',
recipient: 'merchant.example',
state: 'quote_123',
},
options: { onEvent: logWalletEvents() },
});
if (!result.success) {
throw new Error(result.error);
}
return result;
}The successful result contains the signed message data. The helper throws only after the SDK returns success: false, so callers can replace the throw with an inline error state when needed.
Execute an EVM-family transaction
Create a typed EIP-1559 request and provide the chain target for the network you support.
The default seamsTestnetConfig selects NEAR and Tempo. To run the Ethereum Sepolia example, configure it explicitly before creating the provider:
import { defineSeamsConfig } from '@seams/wallet/react';
const config = defineSeamsConfig({
walletOrigin: import.meta.env.VITE_WALLET_ORIGIN,
relayerUrl: import.meta.env.VITE_RELAYER_URL,
publishableKey: import.meta.env.VITE_SEAMS_PUBLISHABLE_KEY,
chains: [
{ network: 'near-testnet' },
{ network: 'ethereum-sepolia', chainId: 11_155_111 },
],
});import { logWalletEvents, parseEther, type SeamsWeb } from '@seams/wallet';
// EIP-1559 on any configured EVM chain. `seams.tempo` mirrors this API for
// Tempo's EIP-2718 typed transactions; the two stay separate because the
// envelopes and the signed results differ.
export async function executeEvmTransaction(seams: SeamsWeb): Promise<string> {
const execution = await seams.evm.signAndSendTransaction({
// A configured network slug. The RPC endpoint comes from that chain, and
// `tx.chainId` is filled in from it. Omitting `walletSession` targets the
// authenticated wallet.
chainTarget: 'ethereum-sepolia',
request: {
chain: 'evm',
kind: 'eip1559',
senderSignatureAlgorithm: 'secp256k1',
tx: {
maxPriorityFeePerGas: 1n,
maxFeePerGas: 1n,
gasLimit: 21_000n,
to: '0x1234567890abcdef1234567890abcdef12345678',
value: parseEther('0'),
data: '0x',
},
},
options: { onEvent: logWalletEvents() },
});
console.log('transaction hash', execution.txHash);
return execution.txHash;
}The sample targets Ethereum Sepolia and returns the transaction hash. Replace the recipient, fees, and chain target with values from your app's transaction builder before sending a real transaction. tx.chainId and the RPC endpoint both come from the chain target, so neither is repeated on the call.
For Tempo's EIP-2718 typed transactions use seams.tempo, which mirrors this API method for method.
Expected result
- NEAR signing resolves after the requested transaction execution status.
- NEP-413 returns a successful signed-message result.
- EVM-family execution returns
txHashafter the transaction is submitted.
Progress callbacks receive SigningFlowEvent values. Use them for a status indicator and keep the final operation identity for reconciliation.
Recoverable failures
- A cancelled approval or policy denial ends the current request. Preserve the draft intent so the person can review and retry it.
- An expired or exhausted wallet session needs a fresh unlock before retrying.
- A signing or RPC failure should remain attached to the operation being attempted. Wait until the first transaction hash or nonce state is reconciled before submitting a second transaction.
- Validate chain ids, recipients, fees, and account references in your app before calling the SDK.
Read next: advanced wallet operations, events and progress, or results and errors.