Skip to Content
MigrationUpgrade to v2
View .md

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.1

All five packages move in lockstep on the latest tag — 2.1.1 is the current release.

At a Glance

v1v2
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)
MethodNotSupportedErrorBridgeMethodUnsupportedError
ReactSDKErrorremoved (hooks surface BridgeError subclasses)
BridgeWindowUnavailableErrorBridgeUnavailableError
error: Error | undefinederror: BridgeError | null
readText(): Promise<string | null>readText(): Promise<ClipboardReadResult>

1. supportedcallable

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. useIsMethodSupporteduseCallable

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:

Next Steps

Last updated on