For the complete documentation index, see llms.txt. This page is also available as Markdown.

Quickstart

Add a wallet to a web app: sign the user in, create their wallet, send a transaction. Everything below runs in the browser, with a passkey as the user's key.

1. Get a publishable key

Create an app in the Aligned dashboard and copy its publishable key (aligned_pk_test_...). The key identifies your app. It is not a secret and is meant to ship in your frontend.

Add every origin your app runs on to the key's allowed origins, including http://localhost:5173 or whatever your dev server uses. Requests from any other origin are rejected with 403 origin_not_allowed.

2. Install the SDK

npm install @aligned-waas/sdk

3. Create a client

import { AlignedClient, localStorageAdapter, webPasskeyAdapter } from '@aligned-waas/sdk';

export const aligned = new AlignedClient({
  publishableKey: 'aligned_pk_test_...',
  storage: localStorageAdapter(), // keeps the session across reloads
  passkey: webPasskeyAdapter(),   // browser WebAuthn
});

The client connects to the Aligned testnet by default. Pass baseUrl to point it at a backend you run yourself.

Construct it once, at module scope. A new client on every render restarts session restoration and throws away its caches.

4. Sign the user in

Email one-time code, no password:

The first successful verification creates the account. Google sign-in is available too, in a popup:

5. Create the wallet

That one call registers a passkey on the device, creates the account on chain, and selects that passkey as the signing key.

If the user already has a wallet it is returned as is, with created: false and no new passkey. Adding a second device to an existing wallet is a different flow, see Keys and recovery.

6. Send a transaction

The SDK asks the backend for the digest bound to the wallet's current nonce, prompts for the passkey, and submits. Aligned relays the transaction and pays the gas, so your users never need the chain's native token. status is 1 when the transaction succeeded on chain.

7. Sign a message

Nothing is submitted on chain. The result is a signature any verifier can check by calling isValidSignature (ERC-1271) on the wallet.

Plain strings are hashed as keccak256(utf8(message)), which is not what personal_sign (EIP-191) does. For EIP-191 or EIP-712 semantics, compute the digest yourself and pass { hash }.

Handling errors

Failed calls throw ApiError, carrying the HTTP status, a stable code, and the parsed response body. Codes worth handling explicitly:

Code
What to do

unauthenticated

Session expired or missing. Send the user back through sign-in.

origin_not_allowed

The page origin is not on the publishable key's allowlist. Fix it in the dashboard.

rate_limited

Back off and retry.

step_up_required

The endpoint needs a fresh step-up proof, see Keys and recovery.

Passkey ceremonies throw whatever the browser throws, and a cancelled prompt is a normal outcome rather than a failure. Treat it as "the user said no".

A note on Node

The SDK is a browser and mobile library. The publishable-key path requires a real Origin header, which Node's fetch does not send, so calls from Node are rejected. Use it in Node only for tests or for building signing material that a browser will send.

Where next

Last updated

Was this helpful?