Upgrade to v2 (the Callability Rollup)
Version 2 reworks one idea: how a mini app asks “can I call this
method right now?” Before, capability was a bare supported boolean.
Now it’s a typed Callability
value that tells you why a method isn’t available — no bridge vs. host
too old — so you can render the right UI.
This guide covers every breaking change. Most are mechanical renames; a few change a return shape.
Bump the Packages
npm install \
@alien-id/miniapps-react@2.1.1 \
@alien-id/miniapps-bridge@2.1.1 \
@alien-id/miniapps-contract@2.1.1 \
@alien-id/miniapps-auth-client@2.1.1 \
@alien-id/miniapps-solana-provider@2.1.1All five packages move in lockstep on the latest tag — 2.1.1 is the
current release.
At a Glance
| v1 | v2 |
|---|---|
supported (on every hook) | callable |
useIsMethodSupported(method) | useCallable(method) |
isAvailable(method, opts) | callability(method, opts) |
import { sendIfAvailable } | send.ifAvailable(...) |
import { requestIfAvailable } | request.ifAvailable(...) |
useMethod(m, e, { checkVersion }) | useMethod(m, e) |
MethodNotSupportedError | BridgeMethodUnsupportedError |
ReactSDKError | removed (hooks surface BridgeError subclasses) |
BridgeWindowUnavailableError | BridgeUnavailableError |
error: Error | undefined | error: BridgeError | null |
readText(): Promise<string | null> | readText(): Promise<ClipboardReadResult> |
1. supported → callable
Every call hook (useMethod, usePayment, useClipboard, useHaptic,
useBackButton, useClose, useNotificationPermission) now returns
callable instead of supported.
- const { pay, supported } = usePayment();
- if (!supported) return <Unavailable />;
+ const { pay, callable } = usePayment();
+ if (!callable) return <Unavailable />;The old supported still works as a deprecated alias — reading it logs a
one-time dev warning. Rename at your own pace; nothing breaks immediately.
2. useIsMethodSupported → useCallable
useIsMethodSupported is gone. useCallable returns a discriminated
union instead of { supported, minVersion, contractVersion }, so you can
branch on the reason:
- const { supported, minVersion } = useIsMethodSupported('payment:request');
- if (!supported) return <div>Update the Alien app (needs {minVersion})</div>;
+ const c = useCallable('payment:request');
+ if (c.callable) return <PayButton />;
+ if (c.reason === 'no-bridge') return <OpenInAlienApp />;
+ return <UpdateAlienApp needs={c.needs} has={c.has} />;3. isAvailable() → callability()
callability() is the direct replacement. It already runs the
bridge-presence check internally — no bridge yields
{ callable: false, reason: 'no-bridge' } — so you don’t pair it with a
separate isBridgeAvailable():
- import { isAvailable } from '@alien-id/miniapps-bridge';
- if (isAvailable('payment:request', { version: contractVersion })) { ... }
+ import { callability } from '@alien-id/miniapps-bridge';
+ const c = callability('payment:request', { version: contractVersion });
+ if (c.callable) { /* safe to call */ }isBridgeAvailable() still exists, but only as the method-agnostic
“are we inside the Alien app at all?” check (it’s also exposed as
useAlien().isBridgeAvailable). For a pure protocol-only check that
ignores the bridge entirely, use isMethodSupported(method, version)
from @alien-id/miniapps-contract.
4. Safe Variants Are Attached Methods
The sendIfAvailable / requestIfAvailable named exports never shipped
in v2. Use the attached .ifAvailable methods:
- import { sendIfAvailable, requestIfAvailable } from '@alien-id/miniapps-bridge';
- sendIfAvailable('haptic:impact', { style: 'medium' });
+ import { send } from '@alien-id/miniapps-bridge';
+ send.ifAvailable('haptic:impact', { style: 'medium' });Both return a SafeResult instead of
throwing.
5. useMethod Takes Two Arguments
The third options argument and checkVersion flag are gone. Version
gating is always on. To override the version a single call gates against,
pass it to execute:
- const m = useMethod('payment:request', 'payment:response', { checkVersion: true });
- await m.execute(params);
+ const m = useMethod('payment:request', 'payment:response');
+ await m.execute(params);
+ // optional per-call override:
+ await m.execute(params, { version: '1.5.0' });6. One Error Model
React no longer defines its own error classes. ReactSDKError and
MethodNotSupportedError are gone — hooks surface the bridge’s typed
errors directly. The unsupported-method error is now
BridgeMethodUnsupportedError.
- import { ReactSDKError, MethodNotSupportedError } from '@alien-id/miniapps-react';
- if (error instanceof MethodNotSupportedError) { ... }
+ import { BridgeMethodUnsupportedError } from '@alien-id/miniapps-react';
+ if (error instanceof BridgeMethodUnsupportedError) { ... }BridgeWindowUnavailableError is also gone — the SSR / no-window case
now folds into BridgeUnavailableError:
- } else if (error instanceof BridgeWindowUnavailableError) {
+ } else if (error instanceof BridgeUnavailableError) {
// not running in the Alien app (also covers SSR)
}Finally, hook error state is now BridgeError | null (was
Error | undefined). If you checked error === undefined, check for
null instead.
7. useClipboard().readText Returns a Result Object
readText() no longer returns string | null. It resolves a
ClipboardReadResult:
- const content = await readText();
- if (content !== null) console.log(content);
+ const r = await readText();
+ if (r.ok) console.log(r.text);
+ else if (r.errorCode) console.warn('refused:', r.errorCode);
+ else console.warn('bridge error:', r.error.message);New in v2
While you’re upgrading, three additions are worth adopting:
useNotificationPermission— request OS push-notification permission (contract 1.5.0)useCallable— the canonical capability hookuseClose— close the mini app from React
Next Steps
- React SDK Overview — the updated hook surface
- Bridge Reference — Strict vs. Safe tracks, errors
- Notifications — request permission and send push notifications