Integration

Use your Ethereum wallet

Connect MetaMask, Rabby, Rainbow, or Trust Wallet. Sign once. You get a Sigma identity and a Bitcoin address that the same private key already controls.

The Bitcoin option works identically with keys from BTC, BCH, or BSV. They share the same cryptography.

No new seed phraseOne signatureThe key never leaves your wallet

There are two layers here, and keeping them apart is the whole point. Your identity attestation hashes live on BSV. That is the anchor chain, it is where the record is written, and it does not change. Generating the identity is the other layer, and for that you can use keys you already hold somewhere else.

Generate an identity with keys you already hold on
EthereumBitcoinBitcoin CashBitcoin SVLitecoinAvalancheICPSolana
Why this works

Same curve, same key, different encoding

This is arithmetic, not a bridge or a wrapped asset.

One private key produces both an Ethereum address and a Bitcoin addressBecause Ethereum and Bitcoin both use the secp256k1 curve, a single private key generates the same public key on both chains. Only the address encoding differs.Your private keysecp256k1same public keyEthereum address0xa640f4840e7002ba3c8c2677da6986a3a55db7b4Bitcoin (BSV) address195VnjXUbJ953Hcrkfc9boF5aDbQMrM4cF

Ethereum and Bitcoin both use the secp256k1 elliptic curve. One private key produces the same public key on both, and only the address encoding differs. Connecting an EVM wallet therefore produces a Bitcoin address you already control, with nothing new to look after.

Which layer lives where. The identity attestation hashes are written to BSV through BAP. BSV is the anchor chain, and that stays true no matter which wallet you connect. What varies is the key you generate the identity with, which can be one you already hold on Ethereum, Bitcoin, Bitcoin Cash, Bitcoin SV, Litecoin, Avalanche, ICP, or Solana. The wallet you bring decides how the identity is generated. It does not change where the record is anchored.
Quickstart

The EVM path in three calls

Client side. Nothing here sends a private key anywhere.

On the server, the route this posts to is provided by @sigma-auth/better-auth-plugin, so a project already running Better Auth wires this path up as a plugin rather than as a separate SDK.

connect-wallet.ts
// 1. Connect the wallet the user already has
const [address] = await window.ethereum.request({
  method: 'eth_requestAccounts',
});

// 2. Sign the connection message. This is the only signature required.
const message = 'sigma-auth-connect:1:' + address.toLowerCase();
const signature = await window.ethereum.request({
  method: 'personal_sign',
  params: [message, address],
});

// 3. Hand the signature to Sigma. The private key never leaves the wallet.
await fetch('/api/wallet/connect', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ chainId: 1, address, message, signature }),
});

window.ethereum is the injected browser wallet, so this path covers extension and in-app browser wallets. A Ledger or Trezor reaches it the same way, by being connected through one of those wallets rather than through its own desktop app.

What Sigma does with the signature

The public key is recovered from the signature and re-encoded as a Bitcoin address. Sigma never sees the private key, because it never needs to.

derive-address.ts
// 1. User signs message with ETH wallet
const message = "sigma-auth-connect:1:0xa640f4840e7002ba3c8c2677da6986a3a55db7b4";
const signature = await signer.signMessage(message);

// 2. Recover uncompressed ETH public key (65 bytes)
const ethPubkey = recoverPublicKey(message, signature);
// Example: 0x042f472d6c7063546f4deed237666feaa593c44d26...

// 3. Convert to BSV compressed format (33 bytes)
const bsvPubkey = PublicKey.fromString(ethPubkey, "hex");
// Automatically compresses: 02 or 03 prefix + 32 bytes X coordinate

// 4. Derive BSV address
const bsvAddress = bsvPubkey.toAddress().toString();
// Example: 195VnjXUbJ953Hcrkfc9boF5aDbQMrM4cF

Recovering the funds without us

The claim is only worth something if you can leave. For a software wallet that holds the key itself, this is the whole procedure.

recover.sh
# Your Ethereum private key controls the derived BSV address directly.

# 1. Export it from a software wallet that holds it.
#    In MetaMask: Settings > Security and Privacy > Reveal Private Key
#    A hardware device will not do this. See the note below.

# 2. Import that same key into any BSV wallet

# 3. The wallet derives the same address. Your funds are there.
#    No Sigma account required, and no permission to ask for.

A hardware device will not do step one, because it never releases a key. Recovery there means taking your recovery phrase into offline derivation tooling to obtain the account key, which gives up the protection the device exists to provide. Worth knowing before you pick the device path, not after.

Smart account wallets work differently. Coinbase Smart Wallet, Base Account, and other smart account wallets cannot export a private key, because they do not have one in the usual sense. The BSV key is instead derived deterministically from inputs you control, so recovery needs your BAP backup as well as the wallet address. The exact derivation and the full procedure are in the wallet recovery documentation. A wallet that holds its own key has no such requirement.
Context

How this relates to Sign-In with Ethereum

If you have used Sign-In with Ethereum, the shape will be familiar. The user signs a message with a wallet they already control and no password is involved anywhere in the flow. Two differences are worth knowing before you plan an integration.

Difference one

The message format is Sigma's own

The connection message is a short Sigma specific string rather than the structured EIP-4361 message that SIWE defines. If you already parse SIWE messages server side, expect to handle this one separately.

Difference two

You get an identity, not just a session

SIWE authenticates a session for one application. Sigma issues a BAP identity and a standard OAuth 2.0 token, so the same identity can be presented to any other application that accepts Sigma, and it persists beyond the session.

Supported

Wallets you can connect

Externally owned accounts

Two recovery paths, depending on where the key lives

MetaMaskRabbyRainbowTrust WalletLedger, through MetaMask or RabbyTrezor, through MetaMaskWalletConnect, EOA wallets

Software wallets let you export the private key and import it elsewhere. Hardware devices never release a key, so recovery there means deriving the account key from your recovery phrase offline instead.

Smart account wallets

Deterministic derivation on recovery

Coinbase Smart WalletBase Account

Other smart account wallets follow the same path. They sign through their contract rather than with a recoverable key, so they never take the route above.

Next step

Connect a wallet and look at the result

The full derivation and recovery procedure, including the smart contract wallet path, is in the wallet recovery documentation.