@usethrottle/extension-bridge
v1.1.0
Published
iframe bridge runtime for Throttle extensions — host helper + webhook verifier.
Readme
@usethrottle/extension-bridge
Runtime bridge for Throttle extensions rendered inside dashboard iframes. The package includes the iframe-side client, the dashboard host helper, shared postMessage protocol types, and a Node webhook verifier.
npm install @usethrottle/extension-bridgeIframe Client
import { createBridge } from '@usethrottle/extension-bridge';
const bridge = createBridge({
targetOrigin: 'https://dashboard.usethrottle.dev',
});
const context = await bridge.ready;
console.log(context.environment.environmentId);
console.log(context.environment.environmentSlug);
const orders = await bridge.api.get('/api/v1/orders');
bridge.toast('Loaded orders', 'success');bridge.ready resolves to a SessionContext:
type SessionContext = {
user: { id: string; email: string };
workspace: { id: string; slug: string };
application: { id: string; slug: string };
environment: {
environmentId: string;
environmentSlug: string;
environmentKind: 'production' | 'non_production';
providerEnvironment: 'production' | 'sandbox';
};
installationId: string;
extensionId: string;
version: string;
role: string;
scopes: string[];
};Production is the only production-provider environment. Every custom workspace
environment is non-production and uses sandbox provider credentials, so extension
API calls and webhooks stay isolated by environment.environmentId.
Dashboard Host
import { createBridgeHost } from '@usethrottle/extension-bridge';
const host = createBridgeHost({
iframe,
targetOrigin: new URL(iframe.src).origin,
apiBaseUrl: 'https://api.usethrottle.dev',
async mintToken() {
return fetch('/api/extension-launch-token').then((res) => res.json());
},
onResize(height) {
iframe.style.height = `${height}px`;
},
});
host.destroy();mintToken must return { token, expiresAt, context }, where context is the
same SessionContext shape above.
Webhook Verification
import { verifyWebhook } from '@usethrottle/extension-bridge/webhook';
const ok = verifyWebhook(rawBody, signatureHeader, process.env.THROTTLE_WEBHOOK_SECRET!);The verifier accepts the X-Throttle-Signature format used by Throttle outbound
webhooks and returns boolean.
For Web Crypto runtimes such as Cloudflare Workers, Deno, Bun, or browser-like extension backends, import the async verifier:
import { verifyWebhook } from '@usethrottle/extension-bridge/verify';
const ok = await verifyWebhook(rawBody, signatureHeader, secret);