@appboxo/web-sdk
v1.4.3
Published
Boxo Desktop Host App SDK for handling miniapp events
Readme
Appboxo Web SDK
Embed miniapps into your desktop application using iframe communication.
Quick Start
import { AppboxoWebSDK } from "@appboxo/web-sdk";
const sdk = new AppboxoWebSDK({
clientId: "your-client-id",
appId: "your-app-id"
});
// Get auth code from your backend
const authCode = await fetch('/api/auth-code').then(r => r.json());
sdk.setAuthCode(authCode);
// Mount miniapp (SDK will automatically fetch URL from API)
await sdk.mount({
container: document.getElementById("miniapp")
});Installation
npm install @appboxo/web-sdk
# or
pnpm install @appboxo/web-sdkConfiguration
const sdk = new AppboxoWebSDK({
clientId: string; // Required
appId: string; // Required
userId?: string; // Optional, user reference identifier
baseUrl?: string; // Optional, default: "https://dashboard.boxo.io/api/v1"
sandboxMode?: boolean; // Optional, default: false
debug?: boolean; // Optional, default: false. When true, enables all console logs for debugging. When false, no console logs are output.
locale?: string; // Optional, locale/language code (e.g., 'en', 'en-US', 'ru', 'zh-CN')
theme?: 'dark' | 'light' | 'system'; // Optional, theme/color scheme preference (default: 'system')
onGetAuthCode?: () => Promise<string>; // Optional, for automatic auth code retrieval
onGetAuthTokens?: () => Promise<LoginResponse>; // Optional, for direct auth tokens
onPaymentRequest?: (params: PaymentRequest) => Promise<PaymentResponse>; // Optional, for handling payment requests
});Authentication
OAuth flow:
sdk.setAuthCode(authCode);Or provide a callback:
const sdk = new AppboxoWebSDK({
clientId: "your-client-id",
appId: "your-app-id",
onGetAuthCode: async () => {
const res = await fetch('/api/generate-auth-code');
return (await res.json()).auth_code;
}
});Direct auth flow:
sdk.onAuth(async () => {
const response = await fetch('/api/get-miniapp-tokens');
const tokens = await response.json();
sdk.setAuthTokens(tokens.access_token, tokens.refresh_token);
});Or use callback:
const sdk = new AppboxoWebSDK({
clientId: "your-client-id",
appId: "your-app-id",
onGetAuthTokens: async () => {
const res = await fetch('/api/get-miniapp-tokens');
const result = await res.json();
return {
token: result.access_token,
refresh_token: result.refresh_token
};
}
});Or set tokens directly:
const tokens = await getTokensFromBackend();
sdk.setAuthTokens(tokens.access_token, tokens.refresh_token);The SDK will try these in order:
- Pre-set tokens (
setAuthTokens) - Direct auth callback (
onGetAuthTokens) - OAuth auth code (
setAuthCodeoronGetAuthCodecallback)
Payment Processing
When a miniapp calls appboxo.pay(), the SDK will call your onPaymentRequest callback. Process the payment and return the result.
Payment status values: 'success', 'failed', or 'cancelled'.
const sdk = new AppboxoWebSDK({
clientId: "your-client-id",
appId: "your-app-id",
onPaymentRequest: async (paymentData) => {
// Process payment with your backend
const response = await fetch('/api/payments/process', {
method: 'POST',
body: JSON.stringify(paymentData)
});
const result = await response.json();
return {
...paymentData,
status: result.status, // 'success', 'failed', or 'cancelled'
hostappOrderId: result.orderId,
transactionId: result.transactionId, // optional
};
},
});
// Optional: listen for payment completion
sdk.onPaymentComplete((success, data) => {
if (success) {
console.log('Payment succeeded:', data);
}
});Important Notes:
- When
onPaymentRequestis set, the SDK automatically tells the miniapp it supportsAppBoxoWebAppPay, so it can callappboxo.pay(). - If
onPaymentRequestis not configured, payment requests will fail. Enabledebug: trueto see error messages. - About
debugmode:debug: false(default): No console logs are output. Suitable for production.debug: true: All SDK operations are logged to console. Useful for development and troubleshooting.- The
debugoption does not affect SDK functionality - it only controls console logging.
Locale/Language
Set the locale/language code to pass to the miniapp. The locale will be included in the InitData response.
// Set locale during initialization
const sdk = new AppboxoWebSDK({
clientId: "your-client-id",
appId: "your-app-id",
locale: "en-US" // or 'ru', 'zh-CN', etc.
});
// Or set locale dynamically
sdk.setLocale("ru");The locale is passed to the miniapp via InitData.data.locale on the next AppBoxoWebAppGetInitData request.
Important Notes:
- If you call
setLocale()after the miniapp has already loaded, the locale will be included in the next InitData request. The miniapp may need to reload or request InitData again to receive the updated locale. - To ensure the locale is available immediately, set it during SDK initialization or before calling
mount().
Theme/Dark Mode
Set the theme/color scheme preference to pass to the miniapp. The theme will be included in the InitData response.
// Set theme during initialization
const sdk = new AppboxoWebSDK({
clientId: "your-client-id",
appId: "your-app-id",
theme: "dark" // or 'light', 'system'
});
// Or set theme dynamically
sdk.setTheme("light");The theme is passed to the miniapp via InitData.data.theme on the next AppBoxoWebAppGetInitData request.
Theme values:
'dark': Force dark mode'light': Force light mode'system': Use system preference (default)
Important Notes:
- If you call
setTheme()after the miniapp has already loaded, the theme will be included in the next InitData request. The miniapp may need to reload or request InitData again to receive the updated theme. - To ensure the theme is available immediately, set it during SDK initialization or before calling
mount().
Logout
The logout() method clears the host app's storage and SDK's internal authentication data.
sdk.logout();Important Notes:
- This only clears the host app's
localStorageandsessionStorage - Miniapp's storage is separate (different origin) and cannot be cleared from the host app due to browser security restrictions
- The SDK will send a logout notification to the miniapp via
postMessageusing the standardappboxo-host-responseformat - Miniapp should listen for
AppBoxoWebAppLogouthandler to clear its own storage - SDK's internal
authCodeandauthTokensare also cleared
Miniapp Integration:
To receive logout notifications in your miniapp, add a message listener:
useEffect(() => {
const handleMessage = (event: MessageEvent) => {
if (
event.data?.type === "appboxo-host-response" &&
event.data?.handler === "AppBoxoWebAppLogout" &&
event.data?.data?.action === "logout"
) {
// Clear miniapp's storage
localStorage.clear();
sessionStorage.clear();
}
};
window.addEventListener("message", handleMessage);
return () => window.removeEventListener("message", handleMessage);
}, []);Methods
| Method | Description |
|--------|-------------|
| setAuthCode(code) | Set authentication code |
| setAuthTokens(token, refreshToken?) | Set authentication tokens directly |
| setLocale(locale) | Set locale/language code (e.g., 'en', 'en-US', 'ru', 'zh-CN') |
| setTheme(theme) | Set theme/color scheme preference ('dark' | 'light' | 'system') |
| onAuth(callback) | Register callback for authentication events |
| mount(config) | Create iframe and initialize SDK |
| getMiniappUrl() | Fetch miniapp URL from API settings endpoint |
| setIframe(iframe) | Set iframe element manually |
| initialize() | Start listening for events |
| onEvent(type, handler) | Register custom event handler |
| onLoginComplete(callback) | Login completion callback |
| onPaymentComplete(callback) | Payment completion callback |
| logout() | Clear host app's localStorage, sessionStorage, and SDK's internal auth data |
| destroy() | Clean up resources |
Events
SDK handles these miniapp events:
AppBoxoWebAppLogin- User authenticationAppBoxoWebAppPay- Payment processingAppBoxoWebAppGetInitData- Initial data requestAppBoxoWebAppCustomEvent- Custom events
Examples
React Example
import { AppboxoWebSDK } from "@appboxo/web-sdk";
import type { PaymentRequest, PaymentResponse } from "@appboxo/web-sdk";
function App() {
const iframeRef = useRef<HTMLIFrameElement>(null);
const [sdk, setSdk] = useState<AppboxoWebSDK | null>(null);
useEffect(() => {
const s = new AppboxoWebSDK({
clientId: "your-client-id",
appId: "your-app-id",
onPaymentRequest: async (paymentData: PaymentRequest): Promise<PaymentResponse> => {
const response = await fetch('/api/payments/process', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(paymentData)
});
const result = await response.json();
return {
...paymentData,
status: result.status,
hostappOrderId: result.hostappOrderId,
};
},
});
s.setAuthCode("your-auth-code");
s.onLoginComplete((success, data) => {
console.log('Login:', success ? 'success' : 'failed', data);
});
s.onPaymentComplete((success, data) => {
console.log('Payment:', success ? 'success' : 'failed', data);
});
setSdk(s);
return () => s.destroy();
}, []);
useEffect(() => {
const fetchUrl = async () => {
if (sdk && iframeRef.current) {
const url = await sdk.getMiniappUrl();
iframeRef.current.src = url;
}
};
fetchUrl();
}, [sdk]);
const handleLoad = () => {
if (sdk && iframeRef.current) {
sdk.setIframe(iframeRef.current);
sdk.initialize();
}
};
return <iframe ref={iframeRef} onLoad={handleLoad} src="" />;
}Using mount helper
// SDK will automatically fetch miniapp URL from API
await sdk.mount({
container: '#miniapp-container',
className: 'miniapp-iframe'
});Styling is handled via CSS:
.miniapp-container {
width: 100%;
height: 500px;
}
.miniapp-iframe {
width: 100%;
height: 100%;
border: none;
}License
Apache-2.0
