Skip to Content
React SDKBridge Reference
View .md

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/bridge

Core 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:

OptionTypeDefaultDescription
timeoutnumber30000Timeout in ms
reqIdstringautoRequest 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:

ParameterTypeDescription
authTokenstring | undefinedJWT auth token
contractVersionVersion | undefinedContract version (semver)
hostAppVersionstring | undefinedHost app version
platform'ios' | 'android' | undefinedPlatform
startParamstring | undefinedCustom deeplink parameter
safeAreaInsetsSafeAreaInsets | undefinedSafe area insets
displayModeDisplayModeDisplay 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

OptionTypeDefaultDescription
launchParamsPartial<LaunchParams>see belowMock launch params
handlersRecord<MethodName, fn | false>{}Custom handlers
delaynumber0Response 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

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

MethodPayloadDescriptionSince
app:ready{}Signal mini app is ready0.0.9
app:close{}Close the mini app1.0.0
host.back.button:toggle{ visible }Show/hide back button1.0.0
payment:requestSee belowRequest payment0.1.1
clipboard:write{ text: string }Write to clipboard0.1.1
clipboard:read{}Read from clipboard0.1.1
link:open{ url, openMode? }Open a URL0.1.3
haptic:impact{ style }Impact feedback0.2.4
haptic:notification{ type }Notification feedback0.2.4
haptic:selection{}Selection feedback0.2.4
wallet.solana:connect{}Connect Solana wallet1.0.0
wallet.solana:disconnect{}Disconnect wallet1.0.0
wallet.solana:sign.transaction{ transaction }Sign tx1.0.0
wallet.solana:sign.message{ message }Sign message1.0.0
wallet.solana:sign.send{ transaction, ... }Sign+send1.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 handler
  • internal: 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.

EventPayloadDescriptionSince
host.back.button:clicked{}Back button pressed1.0.0
payment:responseSee belowPayment result0.1.1
clipboard:responseSee belowClipboard read result0.1.1
wallet.solana:connect.responseSee belowWallet connect result1.0.0
wallet.solana:sign.transaction.responseSee belowSign tx1.0.0
wallet.solana:sign.message.responseSee belowSign msg result1.0.0
wallet.solana:sign.send.responseSee belowSign+send result1.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

CodeNameDescription
5000USER_REJECTEDUser rejected the request
-32602INVALID_PARAMSInvalid request parameters
-32603INTERNAL_ERRORInternal wallet error
8000REQUEST_EXPIREDRequest 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):

ErrorDescription
BridgeErrorBase error class
BridgeTimeoutErrorRequest timed out
BridgeUnavailableErrorNot in Alien app
BridgeWindowUnavailableErrorWindow undefined (SSR)
BridgeMethodUnsupportedErrorMethod not supported by host
LaunchParamsErrorLaunch params unavailable

React SDK errors (from @alien_org/react):

ErrorDescription
ReactSDKErrorBase React SDK error
MethodNotSupportedErrorMethod 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 nothing
  • request() logs a warning, will eventually timeout
  • on() logs a warning, returns no-op unsubscribe
  • isBridgeAvailable() returns false
  • getLaunchParams() returns undefined
  • send.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

Last updated on