@finamx/extension-sdk
v1.0.1
Published
<!-- generated-by: gsd-doc-writer --> # @finamx/extension-sdk
Readme
@finamx/extension-sdk
TypeScript SDK for FinamX Open Platform extension developers. Connects your iframe or WebView to the FinamX host bridge, handling the handshake, message routing, and typed platform invocations.
Part of the finamx-mobile monorepo.
Installation
npm install @finamx/extension-sdk @finamx/bridge-protocolFor local monorepo development, reference the package directly:
{
"dependencies": {
"@finamx/extension-sdk": "file:../../packages/extension-sdk",
"@finamx/bridge-protocol": "file:../../packages/bridge-protocol"
}
}Quick start
import { createExtensionBridge } from '@finamx/extension-sdk';
// Called once on extension load. Resolves after the host sends bridge:ready.
const bridge = await createExtensionBridge();
console.log(bridge.hostContext.theme); // 'light' | 'dark'
console.log(bridge.grantedScopes); // string[] of approved permission scopes
// Resize the iframe to fit content
bridge.ui.resize({ height: 400 });
// Show a toast notification in the host shell
bridge.ui.toast('Loaded', 'success');
// Invoke a platform method
const quote = await bridge.platform.invoke<{ last: number }>('market.quote', { symbol: 'SBER' });
console.log(quote.last);
// Subscribe to platform events (returns an unsubscribe function)
const off = bridge.platform.on('theme.changed', (payload) => {
console.log('new theme:', payload.data);
});Exports
Main entry (@finamx/extension-sdk)
| Export | Kind | Description |
|---|---|---|
| createExtensionBridge | function | Initiates the bridge handshake and returns ExtensionBridge |
| ExtensionBridge | interface | The connected bridge instance shape |
| CreateExtensionBridgeOptions | interface | Options accepted by createExtensionBridge |
| EmbedTransport | interface | Custom transport contract (send / subscribe) |
| BridgeLogEntry | interface | Shape of debug log entries emitted via onLog |
Mock entry (@finamx/extension-sdk/mock)
| Export | Kind | Description |
|---|---|---|
| createMockBridge | function | Returns a synchronous ExtensionBridge backed by in-process stubs |
| MockBridgeOptions | interface | Options for configuring the mock |
createExtensionBridge(options?)
async function createExtensionBridge(
options?: CreateExtensionBridgeOptions,
): Promise<ExtensionBridge>
interface CreateExtensionBridgeOptions {
extensionId?: string; // overrides value from window.__FINAMX_BRIDGE_SESSION__
bridgeVersion?: string; // defaults to BRIDGE_VERSION from @finamx/bridge-protocol
invokeTimeoutMs?: number; // default 30 000 ms
transport?: EmbedTransport; // custom transport; auto-detected if omitted
debug?: boolean; // enable envelope logging
onLog?: (entry: BridgeLogEntry) => void; // required when debug=true
}Transport is auto-detected: WebView (window.FinamXBridge) takes priority over postMessage.
Bridge mock for local development
Use createMockBridge to develop and test your extension without a running host:
import { createMockBridge } from '@finamx/extension-sdk/mock';
const bridge = createMockBridge({
hostContext: { theme: 'dark', locale: 'ru' },
grantedScopes: ['market.quote', 'user.profile.read'],
invokeHandler: async (method, params) => {
if (method === 'market.quote') {
return { symbol: params.symbol, last: 310.0, change: 0.5 };
}
throw new Error(`Unhandled: ${method}`);
},
});
// Same ExtensionBridge interface — no code changes needed for production
const quote = await bridge.platform.invoke('market.quote', { symbol: 'GAZP' });Built-in stub responses (used when no invokeHandler is provided):
| Method | Returns |
|---|---|
| market.quote | { symbol, last: 285.4, change: 1.2 } |
| user.profile.read | { displayName: 'Mock User', locale: 'ru' } |
Debug logging
const bridge = await createExtensionBridge({
debug: true,
onLog: (entry) => console.log(`[bridge] ${entry.direction} ${entry.type}`, entry),
});BridgeLogEntry never contains PII — invoke params, result data, and grantedScopes values are intentionally omitted.
Build
npm run build # tsc -p tsconfig.json → dist/No test script is configured in this package. Integration tests live in the extension-template app, which consumes this package.
