Bridge Reference
The @alien_org/bridge package provides low-level communication with the
Alien host app. Use this directly when you need fine-grained control or
aren’t using React.
For React apps, prefer the higher-level hooks from @alien_org/react
(React SDK Overview).
Installation
npm install @alien_org/bridgeCore Functions
send
Fire-and-forget method call. No response expected.
send('app:ready', {});
send('app:close', {});
send('clipboard:write', { text: 'Hello!' });
send('host.back.button:toggle', { visible: false });
send('link:open', { url: 'https://example.com' });
send('haptic:impact', { style: 'medium' });request
Send a method and wait for a response event. Returns a promise that resolves with the response payload.
const response = await request(
'payment:request',
{ recipient, amount, token, network, invoice },
'payment:response',
{ timeout: 30000 },
);Options:
| Option | Type | Default | Description |
|---|---|---|---|
timeout | number | 30000 | Timeout in ms |
reqId | string | auto | Request ID for correlation |
on / off
Subscribe to events from the host app.
const handler = (payload) => {
console.log('Back button clicked');
};
on('host.back.button:clicked', handler);
// Later: unsubscribe
off('host.back.button:clicked', handler);on() returns an unsubscribe function for convenience:
const unsubscribe = on('host.back.button:clicked', handler);
// Later:
unsubscribe();emit
Send an event (not a method). Rarely needed by mini apps.
emit('some:event', { data: 'value' });isBridgeAvailable
Check if running inside the Alien app.
if (isBridgeAvailable()) {
// Running in Alien app
} else {
// Browser dev mode
}isAvailable
Check if a specific method can be executed. Verifies bridge availability and optionally checks version support.
import { isAvailable } from '@alien_org/bridge';
if (isAvailable('payment:request', { version: contractVersion })) {
// Safe to call
}getLaunchParams
Get launch parameters injected by the host app.
Returns undefined if unavailable.
const params = getLaunchParams();Launch Parameters:
| Parameter | Type | Description |
|---|---|---|
authToken | string | undefined | JWT auth token |
contractVersion | Version | undefined | Contract version (semver) |
hostAppVersion | string | undefined | Host app version |
platform | 'ios' | 'android' | undefined | Platform |
startParam | string | undefined | Custom deeplink parameter |
safeAreaInsets | SafeAreaInsets | undefined | Safe area insets |
displayMode | DisplayMode | Display mode (see below) |
DisplayMode values: 'standard' (default), 'fullscreen',
'immersive'. Safe area inset values are in CSS pixels.
retrieveLaunchParams
Strict version of getLaunchParams that throws LaunchParamsError if
params are unavailable.
try {
const params = retrieveLaunchParams();
} catch (error) {
if (error instanceof LaunchParamsError) {
console.log('Not running in Alien app');
}
}parseLaunchParams
Parse launch params from a JSON string.
const params = parseLaunchParams(jsonString);mockLaunchParamsForDev
Simulate launch params during development. Injects values into window globals just like the host app would.
if (process.env.NODE_ENV === 'development') {
mockLaunchParamsForDev({
authToken: 'dev-token',
platform: 'ios',
contractVersion: '1.0.0',
displayMode: 'standard',
});
}clearMockLaunchParams
Remove mock launch params from window globals and sessionStorage.
clearMockLaunchParams();enableLinkInterceptor
Intercept external link clicks and route them through the bridge’s
link:open method. Same-origin links are unaffected.
Returns an unsubscribe function.
const disable = enableLinkInterceptor({ openMode: 'external' });
// Later:
disable();Safe Variants
The bridge provides safe versions of send and request that never
throw. Instead, they return a SafeResult discriminated union.
type SafeResult<T> = { ok: true; data: T } | { ok: false; error: Error };send.ifAvailable
Safe version of send(). Returns a SafeResult<void>.
const result = send.ifAvailable(
'haptic:impact',
{ style: 'medium' },
{ version: contractVersion },
);
if (!result.ok) {
console.warn('Could not send:', result.error.message);
}request.ifAvailable
Safe version of request(). Returns a Promise<SafeResult<EventPayload>>.
const result = await request.ifAvailable(
'payment:request',
{ recipient, amount, token, network, invoice },
'payment:response',
{ version: contractVersion },
);
if (result.ok) {
console.log('Payment:', result.data.status);
} else {
console.warn('Failed:', result.error.message);
}Both safe variants accept an optional version option. When provided,
they check method support before executing and return a
BridgeMethodUnsupportedError if the method is not supported.
Mock Bridge
For testing, use createMockBridge to simulate the host app environment.
It injects a mock bridge and launch params into window globals.
import { createMockBridge } from '@alien_org/bridge/mock';
const mock = createMockBridge({
launchParams: {
authToken: 'test-token',
contractVersion: '1.0.0',
platform: 'ios',
},
handlers: {
'payment:request': (payload) => ({
status: 'paid',
txHash: 'mock-tx-123',
reqId: payload.reqId,
}),
},
delay: 100, // simulate async delay in ms
});
// Emit events to the miniapp
mock.emitEvent('host.back.button:clicked', {});
// Inspect method calls
const calls = mock.getCalls();
// Cleanup
mock.cleanup();Options
| Option | Type | Default | Description |
|---|---|---|---|
launchParams | Partial<LaunchParams> | see below | Mock launch params |
handlers | Record<MethodName, fn | false> | {} | Custom handlers |
delay | number | 0 | Response delay in ms |
Default launch params: authToken: 'mock-auth-token',
contractVersion: '1.0.0', platform: 'ios',
displayMode: 'standard'.
Set a handler to false to suppress the response entirely.
Instance Methods
| Method | Description |
|---|---|
cleanup() | Remove mock bridge and clear launch params |
emitEvent(name, payload) | Emit an event to the miniapp |
getCalls() | Get array of recorded method calls |
resetCalls() | Clear recorded calls |
Methods Reference
Methods are actions the mini app requests from the host app.
| Method | Payload | Description | Since |
|---|---|---|---|
app:ready | {} | Signal mini app is ready | 0.0.9 |
app:close | {} | Close the mini app | 1.0.0 |
host.back.button:toggle | { visible } | Show/hide back button | 1.0.0 |
payment:request | See below | Request payment | 0.1.1 |
clipboard:write | { text: string } | Write to clipboard | 0.1.1 |
clipboard:read | {} | Read from clipboard | 0.1.1 |
link:open | { url, openMode? } | Open a URL | 0.1.3 |
haptic:impact | { style } | Impact feedback | 0.2.4 |
haptic:notification | { type } | Notification feedback | 0.2.4 |
haptic:selection | {} | Selection feedback | 0.2.4 |
wallet.solana:connect | {} | Connect Solana wallet | 1.0.0 |
wallet.solana:disconnect | {} | Disconnect wallet | 1.0.0 |
wallet.solana:sign.transaction | { transaction } | Sign tx | 1.0.0 |
wallet.solana:sign.message | { message } | Sign message | 1.0.0 |
wallet.solana:sign.send | { transaction, ... } | Sign+send | 1.0.0 |
payment:request
{
recipient: string; // Wallet address
amount: string; // Amount in token's smallest unit
token: string; // 'USDC', 'ALIEN', or token identifier
network: string; // 'solana' or 'alien'
invoice: string; // Your order/invoice ID
item?: { // Optional display info
title: string;
iconUrl: string;
quantity: number;
};
test?: PaymentTestScenario; // Test mode scenario
}Test scenarios: 'paid', 'paid:failed', 'cancelled',
'error:insufficient_balance', 'error:network_error',
'error:unknown'
link:open
{
url: string;
openMode?: 'external' | 'internal';
}external(default): Opens in system browser or appropriate app handlerinternal: Opens within the Alien app (other mini apps, webviews)
send('link:open', { url: 'https://example.com' });
send('link:open', { url: 'solana:...' });
send('link:open', { url: 'mailto:hi@example.com' });
send('link:open', {
url: 'https://alien.app/miniapp/other-app',
openMode: 'internal',
});haptic:impact
{
style: 'light' | 'medium' | 'heavy' | 'soft' | 'rigid';
}haptic:notification
{
type: 'success' | 'warning' | 'error';
}haptic:selection
{}wallet.solana:sign.transaction
{
transaction: string; // Base64-encoded serialized transaction
}wallet.solana:sign.message
{
message: string; // Base58-encoded message bytes
}wallet.solana:sign.send
{
transaction: string; // Base64-encoded
chain?: SolanaChain; // 'solana:mainnet' etc.
options?: {
skipPreflight?: boolean;
preflightCommitment?: SolanaCommitment;
commitment?: SolanaCommitment;
minContextSlot?: number;
maxRetries?: number;
};
}SolanaChain values: 'solana:mainnet',
'solana:devnet', 'solana:testnet'.
SolanaCommitment values: 'processed',
'confirmed', 'finalized'.
Events Reference
Events are notifications from the host app to the mini app.
| Event | Payload | Description | Since |
|---|---|---|---|
host.back.button:clicked | {} | Back button pressed | 1.0.0 |
payment:response | See below | Payment result | 0.1.1 |
clipboard:response | See below | Clipboard read result | 0.1.1 |
wallet.solana:connect.response | See below | Wallet connect result | 1.0.0 |
wallet.solana:sign.transaction.response | See below | Sign tx | 1.0.0 |
wallet.solana:sign.message.response | See below | Sign msg result | 1.0.0 |
wallet.solana:sign.send.response | See below | Sign+send result | 1.0.0 |
payment:response
{
reqId: string;
status: 'paid' | 'cancelled' | 'failed';
txHash?: string;
errorCode?: PaymentErrorCode;
}Error codes: insufficient_balance, network_error, unknown
clipboard:response
{
reqId: string;
text: string | null;
errorCode?: 'permission_denied' | 'unavailable';
}wallet.solana:connect.response
{
reqId: string;
publicKey?: string; // Base58-encoded
errorCode?: WalletSolanaErrorCode;
errorMessage?: string; // Human-readable error
}wallet.solana:sign.transaction.response
{
reqId: string;
signedTransaction?: string; // Base64-encoded
errorCode?: WalletSolanaErrorCode;
errorMessage?: string;
}wallet.solana:sign.message.response
{
reqId: string;
signature?: string; // Base58-encoded
publicKey?: string; // Base58-encoded
errorCode?: WalletSolanaErrorCode;
errorMessage?: string;
}wallet.solana:sign.send.response
{
reqId: string;
signature?: string; // Base58-encoded
errorCode?: WalletSolanaErrorCode;
errorMessage?: string;
}Wallet Error Codes
| Code | Name | Description |
|---|---|---|
5000 | USER_REJECTED | User rejected the request |
-32602 | INVALID_PARAMS | Invalid request parameters |
-32603 | INTERNAL_ERROR | Internal wallet error |
8000 | REQUEST_EXPIRED | Request timed out |
Error Handling
import {
BridgeError,
BridgeTimeoutError,
BridgeUnavailableError,
BridgeWindowUnavailableError,
BridgeMethodUnsupportedError,
} from '@alien_org/bridge';
try {
const result = await request(
'payment:request',
params,
'payment:response',
);
} catch (error) {
if (error instanceof BridgeTimeoutError) {
// error.method, error.timeout
} else if (error instanceof BridgeMethodUnsupportedError) {
// error.method, error.contractVersion, error.minVersion
} else if (error instanceof BridgeUnavailableError) {
// Not running in Alien app
} else if (error instanceof BridgeWindowUnavailableError) {
// Window not available (SSR)
}
}Bridge errors (from @alien_org/bridge):
| Error | Description |
|---|---|
BridgeError | Base error class |
BridgeTimeoutError | Request timed out |
BridgeUnavailableError | Not in Alien app |
BridgeWindowUnavailableError | Window undefined (SSR) |
BridgeMethodUnsupportedError | Method not supported by host |
LaunchParamsError | Launch params unavailable |
React SDK errors (from @alien_org/react):
| Error | Description |
|---|---|
ReactSDKError | Base React SDK error |
MethodNotSupportedError | Method unsupported by version |
MethodNotSupportedError is set by useMethod when
checkVersion is true and the method is not supported.
It has method, contractVersion, and minVersion properties.
Dev Mode Behavior
When running in a browser (bridge unavailable):
send()logs a warning, does nothingrequest()logs a warning, will eventually timeouton()logs a warning, returns no-op unsubscribeisBridgeAvailable()returnsfalsegetLaunchParams()returnsundefinedsend.ifAvailable()returns{ ok: false, error }request.ifAvailable()returns{ ok: false, error }
Use mockLaunchParamsForDev() to simulate launch params,
or createMockBridge() for full bridge simulation.
Next Steps
- React SDK Overview — Higher-level React hooks
- Safe Area Insets — Handle notches and home indicators
- Authentication — User authentication
- Payments — Accept payments
- Haptic Feedback — Haptic feedback
- Quickstart — Create your first mini app