Drop-in widget · Tier B1

Sign in with EU Wallet — one script tag

Add EU Wallet sign-in to any web page in about 30 seconds. The widget renders a branded button, opens a QR modal on click, polls the CodeB verifier for the wallet’s response, and fires a codeb:wallet-signed-in DOM event on the host page. No backend integration is required on your side beyond verifying the returned assertion server-side.

Live demo

Click the button below. A modal will open with a scannable QR pointing at the CodeB verifier on this domain.

Nothing wires the button to your app until you handle the event — the demo just prints the payload below.

Waiting for a wallet response…

Integration snippet (copy-paste)

<!-- 1. Placeholder where the button should render --> <div id="my-login" data-codeb-widget="signin" data-label="Sign in with EU Wallet"></div> <!-- 2. Load the widget from your CodeB verifier origin --> <script src="https://phone.aloaha.com/signin-widget.min.js" data-verifier="https://phone.aloaha.com" data-mode="signin" data-theme="auto" async defer></script> <!-- 3. Handle the callback and POST the assertion to your backend --> <script> window.addEventListener('codeb:wallet-signed-in', function(e) { var assertion = e.detail.assertion; var claims = e.detail.claims; console.log('Verified claims:', claims); // POST assertion to your server; verify it against the CodeB verifier // JWKS at https://phone.aloaha.com/.well-known/openid-configuration. }); </script>

Data attributes on the <script> tag

AttributeDefaultEffect
data-verifierhttps://phone.aloaha.comOrigin serving oidc.ashx. Set to your own tenant domain.
data-modesigninCurrently signin only. age-verify lands with the dedicated backend endpoint in the next iteration.
data-themeautolight, dark, or auto (follows the browser’s prefers-color-scheme).
data-debugfalseSet to true to see widget lifecycle in the browser console.

Data attributes on the placeholder <div>

AttributeEffect
data-codeb-widget="signin"Required. Marks the div for widget insertion.
data-labelOverride the button label (default: Sign in with EU Wallet).

Events fired on window

codeb:wallet-signed-in e.detail.claims holds the verified SD-JWT VC claims (given_name, family_name, age_over_*, whatever the wallet released). e.detail.assertion holds a signed CodeB assertion your server verifies against the verifier JWKS.
codeb:wallet-declined User pressed “deny” in the wallet. Nothing to verify server-side.
codeb:wallet-expired The 5-minute presentation session timed out. Ask the user to try again.
codeb:wallet-error Wallet or verifier returned an error. e.detail.error holds the reason.

Programmatic API

If you prefer not to use the auto-rendered button, call the API directly:

CodeBEuWallet.open({ mode: 'signin' }); // opens the modal CodeBEuWallet.close(); // closes it CodeBEuWallet.config(); // reads current config CodeBEuWallet.version; // '2026-07-12-nadur'

Security & privacy

Origin isolation The widget only talks to the data-verifier origin. No third-party trackers, no cookies, no analytics.
Cross-origin fetches use credentials: 'omit' Your visitor’s session cookies never leave your site.
Modal cannot be spoofed by other origins Rendered from the widget script only; no iframes, no cross-frame messaging.
Assertion verification is server-side Never trust the browser’s e.detail.claims alone. POST e.detail.assertion to your backend and verify against the CodeB verifier JWKS.

Roadmap

Coming with Tier B follow-on rounds:

Legal footing. The widget makes no certification claim. See HAIP implementation notes for our honest position on OpenID Foundation conformance testing.

EU Wallet verifier overview · HAIP notes · Try full sign-in · Age verification