Skip to content
FidmosDocumentation

Login widget

Add sdk.js and call login — the sign-in window opens, and onSuccess returns the authorization code. Below: the call on each stack, the parameters, window configuration and error codes. An end-to-end “from zero to token” example is the quick start.

Every tab is self-contained — connect and call.

<script src="https://id.fidmos.com/js/sdk.js" data-client-id="YOUR_CLIENT_ID"></script>
<script>
  window.FidmosID.login({
    clientId: 'YOUR_CLIENT_ID',
    redirectUri: 'https://partner.example/callback',
    scope: 'openid profile email',
    onSuccess: async ({ code, state, codeVerifier }) => {
      // exchange code for a token on your backend: POST /login/callback
      await fetch('/login/callback', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ code, state, codeVerifier }),
      });
      location.assign('/logged-in');
    },
    onCancel: () => {
      // the user closed the window — this is not an error
    },
    onError: ({ code }) => {
      // code: 'invalid_arguments' | 'already_open' | 'unavailable'
    },
  });
</script>
Parameter Purpose
clientId your client identifier
redirectUri your application’s return address — the same one registered in the dashboard
scope requested data, e.g. 'openid profile email'; openid is required for id_token
state optional; your string — returned in onSuccess unchanged
nonce optional; goes into id_token — then verify it on the backend (expectedNonce), otherwise the built-in check rejects the token
config window appearance: methods, wallets, language, texts — Window configuration
onSuccess({ code, state, codeVerifier }) sign-in succeeded — the authorization code and the PKCE code_verifier
onCancel() the user closed the window
onError({ code }) the window did not open

code is one-time and does not yield a token on its own: exchange it on your backend at /oauth/token, passing the codeVerifier from onSuccess and your client_secret — as in the quick start.

The optional config object changes the appearance of the window — login methods, the wallet list, language and texts. It is client-side: it lives in your login({ config }) call and changes nothing on the server (the boundary — origin, redirect_uri, scopes — is held by the server). Assemble it visually and copy ready-made code in the configurator.

Option Type Default What it sets
methods ('email' | 'telegram' | 'wallet')[] all three which login methods to show
wallets string[] (rdns) the whole catalog the set of wallets (see below)
locale 'ru' | 'en' 'ru' the window’s interface language
theme 'light' | 'dark' | 'auto' 'dark' the window theme; auto follows the system prefers-color-scheme
title string “Sign in” the window title
terms.tos string (URL) — a link to your Terms of Service
terms.privacy string (URL) — a link to your Privacy Policy

The config object is the same on any stack — it is the second field in login({ …, config }) (the call shape on each stack is in the login method):

config: {
  methods: ['email', 'wallet'],
  wallets: ['io.metamask', 'io.rabby', 'app.phantom'],
  locale: 'en',
  theme: 'light',
  title: 'Sign in to Acme',
  terms: {
    tos: 'https://partner.example/tos',
    privacy: 'https://partner.example/privacy',
  },
}

Terms links are taken only if they are a full http(s) URL; otherwise the string is dropped.

wallets is an allow-list by rdns: it sets which wallets to show. The order in the window is always the catalog order (by popularity), and the wallets the user has installed rise to the top — wallets does not set the order. An empty or missing wallets means the whole catalog.

Wallet rdns
MetaMask io.metamask
Rabby io.rabby
Trust Wallet com.trustwallet.app
Coinbase Wallet com.coinbase.wallet
Phantom app.phantom
OKX Wallet com.okex.wallet
Rainbow me.rainbow
Zerion io.zerion.wallet
Brave Wallet com.brave.wallet

An install prompt for an undetected wallet is provided only by these rdns; a wallet with any other rdns shows only if it is detected in the browser.

Code What happened
invalid_arguments clientId or redirectUri was not passed
already_open the window is already open
unavailable the window did not load (network, timeout, closed before it was ready)

Cancellation (onCancel) is not an error — do not show an error message for it. A breakdown of all error codes is in the reference.