Skip to main content

Configuration

SDK Options

interface SDKOptions {
// Required
applicationId: string; // Your registered app ID
apiKey: string; // Organization API key (gwsk_...)
jwksUri?: string; // JWKS endpoint URL (optional if environment is set)

// Environment (auto-resolves endpoints)
environment?: 'production' | 'demo' | 'dev';

// Endpoints (auto-resolved when environment is set)
apiEndpoint?: string; // SDK API endpoint

// Optional hooks
hooks?: {
onSessionStart?: (context: SessionStartContext) => Promise<void>;
onSessionEnd?: (context: SessionEndContext) => Promise<void>;
onSessionWarning?: (context: SessionWarningContext) => Promise<void>;
onSessionExtend?: (context: SessionExtendContext) => Promise<void>;
};

// Session controls configuration
sessionControls?: SessionControlsConfig;

// Other optional settings
marketplaceUrl?: string; // Redirect URL after session end
warningThresholdMinutes?: number; // Warning threshold (default: 5)
debug?: boolean; // Enable debug logging
pauseWhenHidden?: boolean; // Auto-pause when tab hidden
validateJWTBackend?: boolean; // Use backend validation
validationEndpoint?: string; // Backend validation URL
heartbeat?: {
enabled: boolean;
intervalSeconds: number;
endpoint: string;
};
}

Environment Configuration

Development

const config = {
applicationId: 'test-app',
apiKey: 'gwsk_YOUR_API_KEY_HERE',
jwksUri: 'http://localhost:3000/.well-known/jwks.json',
marketplaceUrl: 'http://localhost:8080',
debug: true,
};

Production

const config = {
applicationId: process.env.MARKETPLACE_APP_ID,
apiKey: process.env.MARKETPLACE_API_KEY,
jwksUri: 'https://api.generalwisdom.com/.well-known/jwks.json',
marketplaceUrl: 'https://platform.generalwisdom.com',
debug: false,
};

Framework Integration Patterns

Vanilla JavaScript

import MarketplaceSDK from '@mission_sciences/provider-sdk';

const sdk = new MarketplaceSDK({
applicationId: 'my-vanilla-app',
apiKey: 'gwsk_YOUR_API_KEY_HERE',
jwksUri: 'https://api.generalwisdom.com/.well-known/jwks.json',
hooks: {
onSessionStart: async (context) => {
localStorage.setItem('marketplace_user', JSON.stringify({
userId: context.userId,
email: context.email,
sessionId: context.sessionId,
expiresAt: context.expiresAt,
}));

document.getElementById('login-section').style.display = 'none';
document.getElementById('app-section').style.display = 'block';
document.getElementById('user-email').textContent = context.email;
},

onSessionEnd: async (context) => {
localStorage.removeItem('marketplace_user');
document.getElementById('login-section').style.display = 'block';
document.getElementById('app-section').style.display = 'none';
},
},
});

sdk.initialize().then(() => {
console.log('Marketplace SDK initialized');
});

window.marketplaceSDK = sdk;

Vue

import { ref, onMounted, onUnmounted } from 'vue';
import MarketplaceSDK from '@mission_sciences/provider-sdk';
import type { SessionStartContext, SessionEndContext } from '@mission_sciences/provider-sdk';

export function useMarketplaceSession() {
const sdk = ref<MarketplaceSDK | null>(null);
const session = ref({
isActive: false,
userId: '',
email: '',
expiresAt: 0,
});

onMounted(async () => {
const marketplaceSDK = new MarketplaceSDK({
applicationId: 'my-vue-app',
apiKey: 'gwsk_YOUR_API_KEY_HERE',
jwksUri: 'https://api.generalwisdom.com/.well-known/jwks.json',
hooks: {
onSessionStart: async (context: SessionStartContext) => {
session.value = {
isActive: true,
userId: context.userId,
email: context.email || '',
expiresAt: context.expiresAt,
};
await authenticateUser(context);
},

onSessionEnd: async (context: SessionEndContext) => {
session.value = {
isActive: false,
userId: '',
email: '',
expiresAt: 0,
};
await clearAuth();
},
},
});

await marketplaceSDK.initialize();
sdk.value = marketplaceSDK;
});

onUnmounted(() => {
sdk.value?.destroy();
});

return { sdk, session };
}

Chrome Extensions

Background Script:

import MarketplaceSDK from '@mission_sciences/provider-sdk';

const sdk = new MarketplaceSDK({
applicationId: 'my-chrome-extension',
apiKey: 'gwsk_YOUR_API_KEY_HERE',
jwksUri: 'https://api.generalwisdom.com/.well-known/jwks.json',
hooks: {
onSessionStart: async (context) => {
await chrome.storage.local.set({
marketplace_session: {
userId: context.userId,
email: context.email,
expiresAt: context.expiresAt,
jwt: context.jwt,
},
});

chrome.runtime.sendMessage({
type: 'MARKETPLACE_SESSION_START',
session: context,
});
},

onSessionEnd: async (context) => {
await chrome.storage.local.remove('marketplace_session');
chrome.runtime.sendMessage({
type: 'MARKETPLACE_SESSION_END',
reason: context.reason,
});
},
},
});

sdk.initialize();

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.type === 'GET_SESSION') {
chrome.storage.local.get('marketplace_session', (result) => {
sendResponse(result.marketplace_session || null);
});
return true;
}
});

Content Script:

chrome.runtime.sendMessage(
{ type: 'GET_SESSION' },
(session) => {
if (session) {
console.log('Active marketplace session:', session);
injectSessionHeader(session);
}
}
);

chrome.runtime.onMessage.addListener((request) => {
if (request.type === 'MARKETPLACE_SESSION_START') {
console.log('Session started:', request.session);
}

if (request.type === 'MARKETPLACE_SESSION_END') {
console.log('Session ended:', request.reason);
}
});

Authentication Integration

Backend Token Exchange Pattern

The recommended approach for production apps is to exchange the marketplace JWT for your own application token:

onSessionStart: async (context: SessionStartContext) => {
try {
const response = await fetch('https://your-api.com/auth/marketplace', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${context.jwt}`,
},
body: JSON.stringify({
userId: context.userId,
email: context.email,
sessionId: context.sessionId,
}),
});

if (!response.ok) {
throw new Error(`Auth failed: ${response.status}`);
}

const { token, refreshToken, expiresIn } = await response.json();

localStorage.setItem('auth_token', token);
localStorage.setItem('refresh_token', refreshToken);
localStorage.setItem('token_expires', String(Date.now() + (expiresIn * 1000)));

console.log('[Auth] User authenticated via marketplace');
} catch (error) {
console.error('[Auth] Failed:', error);
throw error; // Prevents session from starting
}
},

Firebase Integration

import { signInWithCustomToken } from 'firebase/auth';
import { auth } from './firebase';

onSessionStart: async (context: SessionStartContext) => {
const response = await fetch('https://your-api.com/auth/firebase-token', {
method: 'POST',
headers: {
'Authorization': `Bearer ${context.jwt}`,
},
});

const { customToken } = await response.json();
await signInWithCustomToken(auth, customToken);
},

Auth0 Integration

onSessionStart: async (context: SessionStartContext) => {
const response = await fetch('https://your-domain.auth0.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: context.jwt,
client_id: 'your-auth0-client-id',
client_secret: 'your-auth0-client-secret',
scope: 'openid profile email',
}),
});

const { access_token, id_token } = await response.json();

localStorage.setItem('auth0_access_token', access_token);
localStorage.setItem('auth0_id_token', id_token);
},

Keycloak Integration

onSessionStart: async (context: SessionStartContext) => {
const response = await fetch('https://your-api.com/auth/keycloak-exchange', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${context.jwt}`,
},
body: JSON.stringify({
userId: context.userId,
email: context.email,
}),
});

const { accessToken, refreshToken, idToken } = await response.json();

localStorage.setItem('keycloak_access_token', accessToken);
localStorage.setItem('keycloak_refresh_token', refreshToken);
localStorage.setItem('keycloak_id_token', idToken);
},

Okta Integration

onSessionStart: async (context: SessionStartContext) => {
const response = await fetch('https://your-api.com/auth/okta-exchange', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${context.jwt}`,
},
body: JSON.stringify({
userId: context.userId,
email: context.email,
}),
});

const { accessToken, refreshToken, idToken } = await response.json();

localStorage.setItem('okta_access_token', accessToken);
localStorage.setItem('okta_refresh_token', refreshToken);
localStorage.setItem('okta_id_token', idToken);
},

Performance Optimization

Bundle Size

  • SDK is approximately 36 KB gzipped as of 0.3.0 (main ES 5.9 KB + lazy MarketplaceSDK chunk 35 KB)
  • Tree-shake unused features — React hooks, Privy modals, and ExtensionModal ship in separate entry points
  • Use code splitting — the MarketplaceSDK chunk lazy-loads on first initialize()

Network

  • Cache JWKS response (SDK does this automatically)
  • Use CDN for static assets
  • Enable HTTP/2

Rendering

  • Lazy load session header component
  • Debounce timer updates (SDK uses 1s intervals)
  • Use requestAnimationFrame for animations