Skip to content

Vanilla JS / TS

The Sigil class is the only public surface of the vanilla entrypoint. It mounts the iframe, drives the postMessage protocol, and exposes a small async API.

Full example

import { Sigil } from '@sigil/sdk';
const wallet = new Sigil({
organizationId: 'org_xxx',
publishableKey: 'pk_live_xxx',
iframeUrl: 'https://wallet.sigilkeys.com',
authMode: 'sigil',
// optional: where the iframe gets mounted. Defaults to document.body.
iframeContainer: document.getElementById('wallet-slot') ?? undefined,
});
await wallet.init();
console.log(wallet.getAddress()); // 0x…
const sig = await wallet.signMessage('hello');
await wallet.logout();
wallet.destroy(); // tear down iframe + transport

Methods

new Sigil(config)

Synchronous. Just wires the config; no network, no DOM mutation yet.

await sigil.init()

Mounts the iframe in iframeContainer (or document.body), waits for its load event, opens a postMessage transport against its origin, and runs the auth handshake:

  • authMode: 'sigil' → the iframe shows the email-OTP UI; init() resolves once the user has signed in (or immediately if the user already has a session in localStorage).
  • authMode: 'oidc' → the SDK calls getToken() once, sends the JWT to the iframe; the iframe validates it against your provider via Sigil backend and either reuses the existing wallet or creates one.

After init() resolves you can call the remaining methods. Calling it a second time is a no-op.

sigil.getAddress(): string | null

Returns the wallet address, or null if there’s no wallet yet (authenticated user without a wallet — happens between sign-in and wallet creation).

await sigil.signMessage(message: string): Promise<string>

Opens a confirmation modal in the iframe, the user approves, the iframe reconstructs the key in memory, signs (ECDSA secp256k1), wipes, and returns the signature in hex.

If the user rejects, signMessage rejects with SigilRejectedError. If the iframe doesn’t respond within 30s, it rejects with SigilTimeoutError.

await sigil.logout(): Promise<void>

Clears the session token. The Device share stays so the same end user can sign in again without going through recovery.

sigil.destroy(): void

Removes the iframe from the DOM, closes the transport, and frees memory. After destroy() the instance is unusable; create a new one for another session.

Lifecycle in a single function

async function signOnce(message: string) {
const wallet = new Sigil({ /* … */ });
try {
await wallet.init();
return await wallet.signMessage(message);
} finally {
wallet.destroy();
}
}

For long-lived integrations, prefer the React provider which keeps one instance alive for the lifetime of the app.